From 75543c08c778eb7315d2368072d0ff710fb228eb Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 16 May 2016 19:59:58 -0400 Subject: [PATCH] simplify HR subtyping back to what we did before A lot of the refactors, however, seem helpful, so leave those in, particularly since we may want to make this change in the future. --- src/librustc/diagnostics.rs | 3 +- src/librustc/infer/error_reporting.rs | 16 ----- src/librustc/infer/higher_ranked/mod.rs | 70 +------------------ src/librustc/infer/mod.rs | 6 -- src/libsyntax/ext/quote.rs | 2 +- src/libsyntax_ext/concat_idents.rs | 2 +- src/test/compile-fail/hr-subtype.rs | 11 +-- .../regions-close-over-type-parameter-1.rs | 5 +- 8 files changed, 15 insertions(+), 100 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index ed83870ea386..1ba722b6baee 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -1647,6 +1647,5 @@ register_diagnostics! { E0490, // a value of type `..` is borrowed for too long E0491, // in type `..`, reference has a longer lifetime than the data it... E0495, // cannot infer an appropriate lifetime due to conflicting requirements - E0525, // expected a closure that implements `..` but this closure only implements `..` - E0526, // skolemization subtype + E0525 // expected a closure that implements `..` but this closure only implements `..` } diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index 402488e59a2c..2f67042ca1c2 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -919,17 +919,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ""); err } - infer::SkolemizeSuccessor(span) => { - let mut err = - struct_span_err!(self.tcx.sess, span, E0526, - "to satisfy higher-ranked bounds, \ - a static lifetime is required"); - self.tcx.note_and_explain_region(&mut err, - "but the lifetime is only valid for ", - sub, - ""); - err - } } } @@ -1817,11 +1806,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { "...so that references are valid when the destructor \ runs"); } - infer::SkolemizeSuccessor(span) => { - err.span_note( - span, - "...so that higher-ranked bounds are satisfied"); - } } } } diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index b432e39fdc6b..3459f48f5c43 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -15,7 +15,6 @@ use super::{CombinedSnapshot, InferCtxt, LateBoundRegion, HigherRankedType, - SubregionOrigin, SkolemizationMap}; use super::combine::CombineFields; use super::region_inference::{TaintDirections}; @@ -527,7 +526,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // be itself or other new variables. let incoming_taints = self.tainted_regions(snapshot, skol, - TaintDirections::incoming()); + TaintDirections::both()); for &tainted_region in &incoming_taints { // Each skolemized should only be relatable to itself // or new variables: @@ -568,71 +567,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.issue_32330_warnings(span, &warnings); - for (_, &skol) in skol_map { - // The outputs from a skolemized variable must all be - // equatable with `'static`. - let outgoing_taints = self.tainted_regions(snapshot, - skol, - TaintDirections::outgoing()); - for &tainted_region in &outgoing_taints { - match tainted_region { - ty::ReVar(vid) if new_vars.contains(&vid) => { - // There is a path from a skolemized variable - // to some region variable that doesn't escape - // this snapshot: - // - // [skol] -> [tainted_region] - // - // We can ignore this. The reasoning relies on - // the fact that the preivous loop - // completed. There are two possible cases - // here. - // - // - `tainted_region` eventually reaches a - // skolemized variable, which *must* be `skol` - // (because otherwise we would have already - // returned `Err`). In that case, - // `tainted_region` could be inferred to `skol`. - // - // - `tainted_region` never reaches a - // skolemized variable. In that case, we can - // safely choose `'static` as an upper bound - // incoming edges. This is a conservative - // choice -- the LUB might be one of the - // incoming skolemized variables, which we - // might know by ambient bounds. We can - // consider a more clever choice of upper - // bound later (modulo some theoretical - // breakage). - // - // We used to force such `tainted_region` to be - // `'static`, but that leads to problems when - // combined with `plug_leaks`. If you have a case - // where `[skol] -> [tainted_region] -> [skol]`, - // then `plug_leaks` concludes it should replace - // `'static` with a late-bound region, which is - // clearly wrong. (Well, what actually happens is - // you get assertion failures because it WOULD - // have to replace 'static with a late-bound - // region.) - } - ty::ReSkolemized(..) => { - // the only skolemized region we find in the - // successors of X can be X; if there was another - // region Y, then X would have been in the preds - // of Y, and we would have aborted above - assert_eq!(skol, tainted_region); - } - _ => { - self.region_vars.make_subregion( - SubregionOrigin::SkolemizeSuccessor(span), - ty::ReStatic, - tainted_region); - } - } - } - } - Ok(()) } @@ -682,7 +616,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { skol_map .iter() .flat_map(|(&skol_br, &skol)| { - self.tainted_regions(snapshot, skol, TaintDirections::incoming()) + self.tainted_regions(snapshot, skol, TaintDirections::both()) .into_iter() .map(move |tainted_region| (tainted_region, skol_br)) }) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 1f1fed7c5e88..a05660ffaaf8 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -340,11 +340,6 @@ pub enum SubregionOrigin<'tcx> { // Region constraint arriving from destructor safety SafeDestructor(Span), - - // When doing a higher-ranked comparison, this region was a - // successor from a skolemized region, which means that it must be - // `'static` to be sound. - SkolemizeSuccessor(Span), } /// Places that type/region parameters can appear. @@ -1798,7 +1793,6 @@ impl<'tcx> SubregionOrigin<'tcx> { AddrOf(a) => a, AutoBorrow(a) => a, SafeDestructor(a) => a, - SkolemizeSuccessor(a) => a, } } } diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index ee9a197ce56c..871b0d4b1c02 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -422,7 +422,7 @@ pub fn expand_quote_expr<'cx>(cx: &'cx mut ExtCtxt, base::MacEager::expr(expanded) } -pub fn expand_quote_item<'cx>(cx: &mut ExtCtxt, +pub fn expand_quote_item<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box { diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs index 3d5f32eadb3c..09c23682cd73 100644 --- a/src/libsyntax_ext/concat_idents.rs +++ b/src/libsyntax_ext/concat_idents.rs @@ -17,7 +17,7 @@ use syntax::parse::token; use syntax::parse::token::str_to_ident; use syntax::ptr::P; -pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) +pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box { if !cx.ecfg.enable_concat_idents() { feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic, diff --git a/src/test/compile-fail/hr-subtype.rs b/src/test/compile-fail/hr-subtype.rs index e3077eb00406..95e469ebcfd7 100644 --- a/src/test/compile-fail/hr-subtype.rs +++ b/src/test/compile-fail/hr-subtype.rs @@ -52,6 +52,10 @@ macro_rules! check { //[bound_inv_a_b_vs_bound_inv_a]~^^^ ERROR mismatched types //[bound_a_b_ret_a_vs_bound_a_ret_a]~^^^^ ERROR mismatched types //[free_inv_x_vs_free_inv_y]~^^^^^ ERROR mismatched types + //[bound_a_b_vs_bound_a]~^^^^^^ ERROR mismatched types + //[bound_co_a_b_vs_bound_co_a]~^^^^^^^ ERROR mismatched types + //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^ ERROR mismatched types + //[bound_co_a_co_b_ret_contra_a]~^^^^^^^^^ ERROR mismatched types } } } @@ -87,6 +91,9 @@ check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>), // - if we are covariant, then 'a and 'b can be set to the call-site // intersection; // - if we are contravariant, then 'a can be inferred to 'static. +// +// FIXME(#32330) this is true, but we are not currently impl'ing this +// full semantics check! { bound_a_b_vs_bound_a: (for<'a,'b> fn(&'a u32, &'b u32), for<'a> fn(&'a u32, &'a u32)) } check! { bound_co_a_b_vs_bound_co_a: (for<'a,'b> fn(Co<'a>, Co<'b>), @@ -109,8 +116,4 @@ fn main() { //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful //[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful //[free_x_vs_free_x]~^^^^^ ERROR compilation successful -//[bound_a_b_vs_bound_a]~^^^^^^ ERROR compilation successful -//[bound_co_a_b_vs_bound_co_a]~^^^^^^^ ERROR compilation successful -//[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^ ERROR compilation successful -//[bound_co_a_co_b_ret_contra_a]~^^^^^^^^^ ERROR compilation successful } diff --git a/src/test/compile-fail/regions-close-over-type-parameter-1.rs b/src/test/compile-fail/regions-close-over-type-parameter-1.rs index 989fc5ea9546..b70ec59420db 100644 --- a/src/test/compile-fail/regions-close-over-type-parameter-1.rs +++ b/src/test/compile-fail/regions-close-over-type-parameter-1.rs @@ -19,7 +19,7 @@ trait SomeTrait { fn get(&self) -> isize; } fn make_object1(v: A) -> Box { box v as Box //~^ ERROR the parameter type `A` may not live long enough - //~^^ ERROR the parameter type `A` may not live long enough + //~| ERROR the parameter type `A` may not live long enough } fn make_object2<'a,A:SomeTrait+'a>(v: A) -> Box { @@ -28,7 +28,8 @@ fn make_object2<'a,A:SomeTrait+'a>(v: A) -> Box { fn make_object3<'a,'b,A:SomeTrait+'a>(v: A) -> Box { box v as Box - //~^ ERROR E0478 + //~^ ERROR the parameter type `A` may not live long enough + //~| ERROR the parameter type `A` may not live long enough } fn main() { }