From 99198d573a8c2fddac449578dfc96f42077a7bf1 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 1 Feb 2019 10:33:44 -0500 Subject: [PATCH 01/12] print more information for closures when `-Zverbose` is given Ideally, we'd probably print the closure substs themselves actually. --- src/librustc/util/ppaux.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 1cb9f47bb31f1..768fd02e8238a 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1430,6 +1430,15 @@ define_print! { } } + if cx.is_verbose { + write!( + f, + " closure_kind_ty={:?} closure_sig_ty={:?}", + substs.closure_kind_ty(did, tcx), + substs.closure_sig_ty(did, tcx), + )?; + } + write!(f, "]") }), Array(ty, sz) => { From 91b03eb1ab52451b527062916355da94404de0e0 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 1 Feb 2019 10:34:42 -0500 Subject: [PATCH 02/12] include more universe information in `debug!` printouts --- src/librustc/infer/higher_ranked/mod.rs | 9 +++++++-- src/librustc/infer/region_constraints/mod.rs | 5 +++-- src/librustc/infer/type_variable.rs | 8 +++++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index 7f01078737d73..c864349019b88 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -96,10 +96,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let (result, map) = self.tcx.replace_bound_vars(binder, fld_r, fld_t); debug!( - "replace_bound_vars_with_placeholders(binder={:?}, result={:?}, map={:?})", + "replace_bound_vars_with_placeholders(\ + next_universe={:?}, \ + binder={:?}, \ + result={:?}, \ + map={:?})", + next_universe, binder, result, - map + map, ); (result, map) diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 65d25333c7179..4ab1c1699b37a 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -514,8 +514,8 @@ impl<'tcx> RegionConstraintCollector<'tcx> { self.undo_log.push(AddVar(vid)); } debug!( - "created new region variable {:?} with origin {:?}", - vid, origin + "created new region variable {:?} in {:?} with origin {:?}", + vid, universe, origin ); return vid; } @@ -671,6 +671,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { self.make_subregion(origin, sup, sub); if let (ty::ReVar(sub), ty::ReVar(sup)) = (*sub, *sup) { + debug!("make_eqregion: uniying {:?} with {:?}", sub, sup); self.unification_table.union(sub, sup); self.any_unifications = true; } diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs index 09a0a6ce9c97c..4c76818346b43 100644 --- a/src/librustc/infer/type_variable.rs +++ b/src/librustc/infer/type_variable.rs @@ -188,7 +188,13 @@ impl<'tcx> TypeVariableTable<'tcx> { }); assert_eq!(eq_key.vid.index, index as u32); - debug!("new_var(index={:?}, diverging={:?}, origin={:?}", eq_key.vid, diverging, origin); + debug!( + "new_var(index={:?}, universe={:?}, diverging={:?}, origin={:?}", + eq_key.vid, + universe, + diverging, + origin, + ); eq_key.vid } From 0c1f841f529470088c8761ac549858e5ffd1f840 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 1 Feb 2019 10:41:08 -0500 Subject: [PATCH 03/12] make generalization code create new variables in correct universe In our type inference system, when we "generalize" a type T to become a suitable value for a type variable V, we sometimes wind up creating new inference variables. So, for example, if we are making V be some subtype of `&'X u32`, then we might instantiate V with `&'Y u32`. This generalized type is then related `&'Y u32 <: &'X u32`, resulting in a region constriant `'Y: 'X`. Previously, however, we were making these fresh variables like `'Y` in the "current universe", but they should be created in the universe of V. Moreover, we sometimes cheat in an invariant context and avoid creating fresh variables if we know the result must be equal -- we can only do that when the universes work out. --- src/librustc/infer/combine.rs | 71 +++++++++++++------ src/librustc/infer/mod.rs | 12 ++++ src/librustc/infer/region_constraints/mod.rs | 2 +- ...project-fn-ret-invariant.krisskross.stderr | 14 ++-- .../cache/project-fn-ret-invariant.rs | 4 +- .../project-fn-ret-invariant.transmute.stderr | 2 +- src/test/ui/issues/issue-57843.rs | 24 +++++++ src/test/ui/issues/issue-57843.stderr | 12 ++++ 8 files changed, 110 insertions(+), 31 deletions(-) create mode 100644 src/test/ui/issues/issue-57843.rs create mode 100644 src/test/ui/issues/issue-57843.stderr diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index 361fbfea09798..9cd5a844f1590 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -255,10 +255,24 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> { RelationDir::SupertypeOf => ty::Contravariant, }; + debug!("generalize: ambient_variance = {:?}", ambient_variance); + + let for_universe = match self.infcx.type_variables.borrow_mut().probe(for_vid) { + v @ TypeVariableValue::Known { .. } => panic!( + "instantiating {:?} which has a known value {:?}", + for_vid, + v, + ), + TypeVariableValue::Unknown { universe } => universe, + }; + + debug!("generalize: for_universe = {:?}", for_universe); + let mut generalize = Generalizer { infcx: self.infcx, span: self.trace.cause.span, for_vid_sub_root: self.infcx.type_variables.borrow_mut().sub_root_var(for_vid), + for_universe, ambient_variance, needs_wf: false, root_ty: ty, @@ -288,6 +302,11 @@ struct Generalizer<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> { /// that means we would have created a cyclic type. for_vid_sub_root: ty::TyVid, + /// The universe of the type variable that is in the process of + /// being instantiated. Any fresh variables that we create in this + /// process should be in that same universe. + for_universe: ty::UniverseIndex, + /// Track the variance as we descend into the type. ambient_variance: ty::Variance, @@ -386,6 +405,8 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, ' fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { assert_eq!(t, t2); // we are abusing TypeRelation here; both LHS and RHS ought to be == + debug!("generalize: t={:?}", t); + // Check to see whether the type we are genealizing references // any other type variable related to `vid` via // subtyping. This is basically our "occurs check", preventing @@ -403,12 +424,17 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, ' match variables.probe(vid) { TypeVariableValue::Known { value: u } => { drop(variables); + debug!("generalize: known value {:?}", u); self.relate(&u, &u) } TypeVariableValue::Unknown { universe } => { match self.ambient_variance { // Invariant: no need to make a fresh type variable. - ty::Invariant => return Ok(t), + ty::Invariant => { + if self.for_universe.can_name(universe) { + return Ok(t); + } + } // Bivariant: make a fresh var, but we // may need a WF predicate. See @@ -422,7 +448,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, ' } let origin = *variables.var_origin(vid); - let new_var_id = variables.new_var(universe, false, origin); + let new_var_id = variables.new_var(self.for_universe, false, origin); let u = self.tcx().mk_var(new_var_id); debug!("generalize: replacing original vid={:?} with new={:?}", vid, u); @@ -448,6 +474,8 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, ' -> RelateResult<'tcx, ty::Region<'tcx>> { assert_eq!(r, r2); // we are abusing TypeRelation here; both LHS and RHS ought to be == + debug!("generalize: regions r={:?}", r); + match *r { // Never make variables for regions bound within the type itself, // nor for erased regions. @@ -456,37 +484,40 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, ' return Ok(r); } - // Always make a fresh region variable for placeholder - // regions; the higher-ranked decision procedures rely on - // this. - ty::RePlaceholder(..) => { } + ty::ReClosureBound(..) => { + span_bug!( + self.span, + "encountered unexpected ReClosureBound: {:?}", + r, + ); + } - // For anything else, we make a region variable, unless we - // are *equating*, in which case it's just wasteful. + ty::RePlaceholder(..) | + ty::ReVar(..) | ty::ReEmpty | ty::ReStatic | ty::ReScope(..) | - ty::ReVar(..) | ty::ReEarlyBound(..) | ty::ReFree(..) => { - match self.ambient_variance { - ty::Invariant => return Ok(r), - ty::Bivariant | ty::Covariant | ty::Contravariant => (), - } + // see common code below } + } - ty::ReClosureBound(..) => { - span_bug!( - self.span, - "encountered unexpected ReClosureBound: {:?}", - r, - ); + // If we are in an invariant context, we can re-use the region + // as is, unless it happens to be in some universe that we + // can't name. (In the case of a region *variable*, we could + // use it if we promoted it into our universe, but we don't + // bother.) + if let ty::Invariant = self.ambient_variance { + let r_universe = self.infcx.universe_of_region(r); + if self.for_universe.can_name(r_universe) { + return Ok(r); } } // FIXME: This is non-ideal because we don't give a // very descriptive origin for this region variable. - Ok(self.infcx.next_region_var(MiscVariable(self.span))) + Ok(self.infcx.next_region_var_in_universe(MiscVariable(self.span), self.for_universe)) } } diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index a61771b2a4eea..04d08c199802e 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -1018,6 +1018,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.tcx.mk_region(ty::ReVar(region_var)) } + /// Return the universe that the region `r` was created in. For + /// most regions (e.g., `'static`, named regions from the user, + /// etc) this is the root universe U0. For inference variables or + /// placeholders, however, it will return the universe which which + /// they are associated. + fn universe_of_region( + &self, + r: ty::Region<'tcx>, + ) -> ty::UniverseIndex { + self.borrow_region_constraints().universe(r) + } + /// Number of region variables created so far. pub fn num_region_vars(&self) -> usize { self.borrow_region_constraints().num_region_vars() diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 4ab1c1699b37a..45d614167ea91 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -824,7 +824,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { new_r } - fn universe(&self, region: Region<'tcx>) -> ty::UniverseIndex { + pub fn universe(&self, region: Region<'tcx>) -> ty::UniverseIndex { match *region { ty::ReScope(..) | ty::ReStatic diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr index 46901b44c4b6d..fa831ea81dcfb 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr @@ -9,15 +9,15 @@ LL | let a = bar(foo, y); //[krisskross]~ ERROR E0623 | ^ ...but data from `x` is returned here error[E0623]: lifetime mismatch - --> $DIR/project-fn-ret-invariant.rs:55:8 + --> $DIR/project-fn-ret-invariant.rs:54:21 | LL | fn transmute<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) { - | -------- -------------------- - | | - | this parameter and the return type are declared with different lifetimes... -... -LL | (a, b) //[krisskross]~ ERROR E0623 - | ^ ...but data from `x` is returned here + | -------- -------------------- + | | + | this parameter and the return type are declared with different lifetimes... +LL | let a = bar(foo, y); //[krisskross]~ ERROR E0623 +LL | let b = bar(foo, x); //[krisskross]~ ERROR E0623 + | ^ ...but data from `y` is returned here error: aborting due to 2 previous errors diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs b/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs index dfcf31b3b1f26..54b6e3642c2ea 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs @@ -51,8 +51,8 @@ fn baz<'a,'b>(x: Type<'a>) -> Type<'static> { #[cfg(krisskross)] // two instantiations, mixing and matching: BAD fn transmute<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) { let a = bar(foo, y); //[krisskross]~ ERROR E0623 - let b = bar(foo, x); - (a, b) //[krisskross]~ ERROR E0623 + let b = bar(foo, x); //[krisskross]~ ERROR E0623 + (a, b) } #[rustc_error] diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr index 947844c45c408..dd1212eaac91d 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr @@ -1,4 +1,4 @@ -error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements +error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements --> $DIR/project-fn-ret-invariant.rs:48:8 | LL | bar(foo, x) //[transmute]~ ERROR E0495 diff --git a/src/test/ui/issues/issue-57843.rs b/src/test/ui/issues/issue-57843.rs new file mode 100644 index 0000000000000..466082552667b --- /dev/null +++ b/src/test/ui/issues/issue-57843.rs @@ -0,0 +1,24 @@ +// Regression test for an ICE that occurred with the universes code: +// +// The signature of the closure `|_|` was being inferred to +// `exists<'r> fn(&'r u8)`. This should result in a type error since +// the signature `for<'r> fn(&'r u8)` is required. However, due to a +// bug in the type variable generalization code, the placeholder for +// `'r` was leaking out into the writeback phase, causing an ICE. + +trait ClonableFn { + fn clone(&self) -> Box; +} + +impl ClonableFn for F +where F: Fn(T) + Clone { + fn clone(&self) -> Box { + Box::new(self.clone()) + } +} + +struct Foo(Box ClonableFn<&'a bool>>); + +fn main() { + Foo(Box::new(|_| ())); //~ ERROR mismatched types +} diff --git a/src/test/ui/issues/issue-57843.stderr b/src/test/ui/issues/issue-57843.stderr new file mode 100644 index 0000000000000..4ef884cb3f589 --- /dev/null +++ b/src/test/ui/issues/issue-57843.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/issue-57843.rs:23:9 + | +LL | Foo(Box::new(|_| ())); //~ ERROR mismatched types + | ^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected type `std::ops::FnOnce<(&'a bool,)>` + found type `std::ops::FnOnce<(&bool,)>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From dd782331463af0279c4e894cc021377a008fb33e Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 15 Feb 2019 15:52:29 +0100 Subject: [PATCH 04/12] fix tests post-rebase --- .../higher-ranked-projection.bad.stderr | 10 +++++----- .../higher-ranked-projection.good.stderr | 2 +- .../ui/associated-types/higher-ranked-projection.rs | 2 +- src/test/ui/hrtb/hrtb-perfect-forwarding.rs | 2 +- src/test/ui/hrtb/hrtb-perfect-forwarding.stderr | 12 ++++++------ 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr index 3bbf48cb37f58..811c9a8f5e12b 100644 --- a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr +++ b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr @@ -1,12 +1,12 @@ -error: implementation of `Mirror` is not general enough +error[E0308]: mismatched types --> $DIR/higher-ranked-projection.rs:25:5 | LL | foo(()); - | ^^^ + | ^^^ one type is more general than the other | - = note: Due to a where-clause on `foo`, - = note: `Mirror` would have to be implemented for the type `&'0 ()`, for any lifetime `'0` - = note: but `Mirror` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` + = note: expected type `&'a ()` + found type `&()` error: aborting due to previous error +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/associated-types/higher-ranked-projection.good.stderr b/src/test/ui/associated-types/higher-ranked-projection.good.stderr index c5c8451a5a9db..92fd256285852 100644 --- a/src/test/ui/associated-types/higher-ranked-projection.good.stderr +++ b/src/test/ui/associated-types/higher-ranked-projection.good.stderr @@ -3,7 +3,7 @@ error: compilation successful | LL | / fn main() { //[good]~ ERROR compilation successful LL | | foo(()); -LL | | //[bad]~^ ERROR not general enough +LL | | //[bad]~^ ERROR mismatched types LL | | } | |_^ diff --git a/src/test/ui/associated-types/higher-ranked-projection.rs b/src/test/ui/associated-types/higher-ranked-projection.rs index 1280c8cb4cb09..fd7252f9e2253 100644 --- a/src/test/ui/associated-types/higher-ranked-projection.rs +++ b/src/test/ui/associated-types/higher-ranked-projection.rs @@ -23,5 +23,5 @@ fn foo(_t: T) #[rustc_error] fn main() { //[good]~ ERROR compilation successful foo(()); - //[bad]~^ ERROR not general enough + //[bad]~^ ERROR mismatched types } diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.rs b/src/test/ui/hrtb/hrtb-perfect-forwarding.rs index 0094091c6bd76..63db695f7e67c 100644 --- a/src/test/ui/hrtb/hrtb-perfect-forwarding.rs +++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.rs @@ -43,7 +43,7 @@ fn foo_hrtb_bar_not<'b,T>(mut t: T) // be implemented. Thus to satisfy `&mut T : for<'a> Foo<&'a // isize>`, we require `T : for<'a> Bar<&'a isize>`, but the where // clause only specifies `T : Bar<&'b isize>`. - foo_hrtb_bar_not(&mut t); //~ ERROR not general enough + foo_hrtb_bar_not(&mut t); //~ ERROR mismatched types } fn foo_hrtb_bar_hrtb(mut t: T) diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr index c7be3790aa1c8..ea08af0164061 100644 --- a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr +++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr @@ -1,12 +1,12 @@ -error: implementation of `Foo` is not general enough +error[E0308]: mismatched types --> $DIR/hrtb-perfect-forwarding.rs:46:5 | -LL | foo_hrtb_bar_not(&mut t); //~ ERROR not general enough - | ^^^^^^^^^^^^^^^^ +LL | foo_hrtb_bar_not(&mut t); //~ ERROR mismatched types + | ^^^^^^^^^^^^^^^^ one type is more general than the other | - = note: Due to a where-clause on `foo_hrtb_bar_not`, - = note: `&mut T` must implement `Foo<&'0 isize>`, for any lifetime `'0` - = note: but `&mut T` actually implements `Foo<&'1 isize>`, for some specific lifetime `'1` + = note: expected type `Bar<&'a isize>` + found type `Bar<&'b isize>` error: aborting due to previous error +For more information about this error, try `rustc --explain E0308`. From 8a16405924aac0227e44a38d82ca61c4d5e8d1b1 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 19 Feb 2019 18:38:42 -0500 Subject: [PATCH 05/12] reintroduce `commit_if_ok` call into `higher_ranked_sub` --- src/librustc/infer/higher_ranked/mod.rs | 51 ++++++++++++------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index c864349019b88..28bcae4248090 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -29,27 +29,29 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { let span = self.trace.cause.span; - // First, we instantiate each bound region in the supertype with a - // fresh placeholder region. - let (b_prime, _) = self.infcx.replace_bound_vars_with_placeholders(b); + return self.infcx.commit_if_ok(|_snapshot| { + // First, we instantiate each bound region in the supertype with a + // fresh placeholder region. + let (b_prime, _) = self.infcx.replace_bound_vars_with_placeholders(b); - // Next, we instantiate each bound region in the subtype - // with a fresh region variable. These region variables -- - // but no other pre-existing region variables -- can name - // the placeholders. - let (a_prime, _) = - self.infcx - .replace_bound_vars_with_fresh_vars(span, HigherRankedType, a); + // Next, we instantiate each bound region in the subtype + // with a fresh region variable. These region variables -- + // but no other pre-existing region variables -- can name + // the placeholders. + let (a_prime, _) = + self.infcx + .replace_bound_vars_with_fresh_vars(span, HigherRankedType, a); - debug!("a_prime={:?}", a_prime); - debug!("b_prime={:?}", b_prime); + debug!("a_prime={:?}", a_prime); + debug!("b_prime={:?}", b_prime); - // Compare types now that bound regions have been replaced. - let result = self.sub(a_is_expected).relate(&a_prime, &b_prime)?; + // Compare types now that bound regions have been replaced. + let result = self.sub(a_is_expected).relate(&a_prime, &b_prime)?; - debug!("higher_ranked_sub: OK result={:?}", result); + debug!("higher_ranked_sub: OK result={:?}", result); - Ok(ty::Binder::bind(result)) + Ok(ty::Binder::bind(result)) + }); } } @@ -72,10 +74,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/hrtb.html pub fn replace_bound_vars_with_placeholders( &self, - binder: &ty::Binder + binder: &ty::Binder, ) -> (T, PlaceholderMap<'tcx>) where - T: TypeFoldable<'tcx> + T: TypeFoldable<'tcx>, { let next_universe = self.create_next_universe(); @@ -97,14 +99,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { debug!( "replace_bound_vars_with_placeholders(\ - next_universe={:?}, \ - binder={:?}, \ - result={:?}, \ - map={:?})", - next_universe, - binder, - result, - map, + next_universe={:?}, \ + binder={:?}, \ + result={:?}, \ + map={:?})", + next_universe, binder, result, map, ); (result, map) From 4e954369b743fbbbc1db54e1c98d325f4b60dccc Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 19 Feb 2019 18:48:29 -0500 Subject: [PATCH 06/12] reintroduce `commit_if_ok` calls to `subtype_predicate` --- src/librustc/infer/mod.rs | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 04d08c199802e..ecd27444caed9 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -937,20 +937,22 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { return None; } - let ( - ty::SubtypePredicate { - a_is_expected, - a, - b, - }, - _, - ) = self.replace_bound_vars_with_placeholders(predicate); - - Some( - self.at(cause, param_env) - .sub_exp(a_is_expected, a, b) - .map(|ok| ok.unit()), - ) + Some(self.commit_if_ok(|_snapshot| { + let ( + ty::SubtypePredicate { + a_is_expected, + a, + b, + }, + _, + ) = self.replace_bound_vars_with_placeholders(predicate); + + Ok( + self.at(cause, param_env) + .sub_exp(a_is_expected, a, b)? + .unit(), + ) + })) } pub fn region_outlives_predicate( From a3bf42f47d4e6faf605886df62bf2080418b4336 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 20 Feb 2019 04:57:32 -0500 Subject: [PATCH 07/12] s/skol_/placeholder_/ --- src/librustc/traits/select.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index c2c05ce7af50b..34deb9ccdcabc 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1682,15 +1682,15 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ) -> bool { let poly_trait_predicate = self.infcx() .resolve_type_vars_if_possible(&obligation.predicate); - let (skol_trait_predicate, _) = self.infcx() + let (placeholder_trait_predicate, _) = self.infcx() .replace_bound_vars_with_placeholders(&poly_trait_predicate); debug!( "match_projection_obligation_against_definition_bounds: \ - skol_trait_predicate={:?}", - skol_trait_predicate, + placeholder_trait_predicate={:?}", + placeholder_trait_predicate, ); - let (def_id, substs) = match skol_trait_predicate.trait_ref.self_ty().sty { + let (def_id, substs) = match placeholder_trait_predicate.trait_ref.self_ty().sty { ty::Projection(ref data) => (data.trait_ref(self.tcx()).def_id, data.substs), ty::Opaque(def_id, substs) => (def_id, substs), _ => { @@ -1698,7 +1698,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation.cause.span, "match_projection_obligation_against_definition_bounds() called \ but self-ty is not a projection: {:?}", - skol_trait_predicate.trait_ref.self_ty() + placeholder_trait_predicate.trait_ref.self_ty() ); } }; @@ -1723,7 +1723,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { self.match_projection( obligation, bound.clone(), - skol_trait_predicate.trait_ref.clone(), + placeholder_trait_predicate.trait_ref.clone(), ) }) }); @@ -1740,7 +1740,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let result = self.match_projection( obligation, bound, - skol_trait_predicate.trait_ref.clone(), + placeholder_trait_predicate.trait_ref.clone(), ); assert!(result); @@ -1753,12 +1753,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { &mut self, obligation: &TraitObligation<'tcx>, trait_bound: ty::PolyTraitRef<'tcx>, - skol_trait_ref: ty::TraitRef<'tcx>, + placeholder_trait_ref: ty::TraitRef<'tcx>, ) -> bool { - debug_assert!(!skol_trait_ref.has_escaping_bound_vars()); + debug_assert!(!placeholder_trait_ref.has_escaping_bound_vars()); self.infcx .at(&obligation.cause, obligation.param_env) - .sup(ty::Binder::dummy(skol_trait_ref), trait_bound) + .sup(ty::Binder::dummy(placeholder_trait_ref), trait_bound) .is_ok() } From 79f68b796f84330c1ae0e5ac0ec22cb55d553683 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 20 Feb 2019 05:22:23 -0500 Subject: [PATCH 08/12] introduce a dummy leak check and invoke it in all the right places This set of diffs was produced by combing through b68fad670bb3612cac26e50751e4fd9150e59977 and seeing where the `leak_check` used to be invoked and how. --- src/librustc/infer/higher_ranked/mod.rs | 26 ++++++++++++-- src/librustc/infer/mod.rs | 31 ++++++++++------- src/librustc/traits/auto_trait.rs | 8 ++++- src/librustc/traits/error_reporting.rs | 11 ++++-- src/librustc/traits/fulfill.rs | 6 ++-- src/librustc/traits/project.rs | 14 ++++---- src/librustc/traits/select.rs | 46 ++++++++++++++++++------- 7 files changed, 103 insertions(+), 39 deletions(-) diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index 28bcae4248090..50487f488852d 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -4,6 +4,7 @@ use super::combine::CombineFields; use super::{HigherRankedType, InferCtxt, PlaceholderMap}; +use crate::infer::CombinedSnapshot; use crate::ty::relate::{Relate, RelateResult, TypeRelation}; use crate::ty::{self, Binder, TypeFoldable}; @@ -29,10 +30,10 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { let span = self.trace.cause.span; - return self.infcx.commit_if_ok(|_snapshot| { + return self.infcx.commit_if_ok(|snapshot| { // First, we instantiate each bound region in the supertype with a // fresh placeholder region. - let (b_prime, _) = self.infcx.replace_bound_vars_with_placeholders(b); + let (b_prime, placeholder_map) = self.infcx.replace_bound_vars_with_placeholders(b); // Next, we instantiate each bound region in the subtype // with a fresh region variable. These region variables -- @@ -48,6 +49,9 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { // Compare types now that bound regions have been replaced. let result = self.sub(a_is_expected).relate(&a_prime, &b_prime)?; + self.infcx + .leak_check(!a_is_expected, &placeholder_map, snapshot)?; + debug!("higher_ranked_sub: OK result={:?}", result); Ok(ty::Binder::bind(result)) @@ -108,4 +112,22 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { (result, map) } + + /// Searches region constraints created since `snapshot` that + /// affect one of the placeholders in `placeholder_map`, returning + /// an error if any of the placeholders are related to another + /// placeholder or would have to escape into some parent universe + /// that cannot name them. + /// + /// This is a temporary backwards compatibility measure to try and + /// retain the older (arguably incorrect) behavior of the + /// compiler. + pub fn leak_check( + &self, + _overly_polymorphic: bool, + _placeholder_map: &PlaceholderMap<'tcx>, + _snapshot: &CombinedSnapshot<'_, 'tcx>, + ) -> RelateResult<'tcx, ()> { + Ok(()) + } } diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index ecd27444caed9..508c1ff7eea3d 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -937,21 +937,22 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { return None; } - Some(self.commit_if_ok(|_snapshot| { + Some(self.commit_if_ok(|snapshot| { let ( ty::SubtypePredicate { a_is_expected, a, b, }, - _, + placeholder_map, ) = self.replace_bound_vars_with_placeholders(predicate); - Ok( - self.at(cause, param_env) - .sub_exp(a_is_expected, a, b)? - .unit(), - ) + let ok = self.at(cause, param_env) + .sub_exp(a_is_expected, a, b)?; + + self.leak_check(false, &placeholder_map, snapshot)?; + + Ok(ok.unit()) })) } @@ -959,12 +960,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { &self, cause: &traits::ObligationCause<'tcx>, predicate: &ty::PolyRegionOutlivesPredicate<'tcx>, - ) { - let (ty::OutlivesPredicate(r_a, r_b), _) = - self.replace_bound_vars_with_placeholders(predicate); - let origin = - SubregionOrigin::from_obligation_cause(cause, || RelateRegionParamBound(cause.span)); - self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b` + ) -> UnitResult<'tcx> { + self.commit_if_ok(|snapshot| { + let (ty::OutlivesPredicate(r_a, r_b), placeholder_map) = + self.replace_bound_vars_with_placeholders(predicate); + let origin = + SubregionOrigin::from_obligation_cause(cause, || RelateRegionParamBound(cause.span)); + self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b` + self.leak_check(false, &placeholder_map, snapshot)?; + Ok(()) + }) } pub fn next_ty_var_id(&self, diverging: bool, origin: TypeVariableOrigin) -> TyVid { diff --git a/src/librustc/traits/auto_trait.rs b/src/librustc/traits/auto_trait.rs index 8957bbaa4ad7d..60a3777abf844 100644 --- a/src/librustc/traits/auto_trait.rs +++ b/src/librustc/traits/auto_trait.rs @@ -771,7 +771,13 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { } } &ty::Predicate::RegionOutlives(ref binder) => { - let () = select.infcx().region_outlives_predicate(&dummy_cause, binder); + if select + .infcx() + .region_outlives_predicate(&dummy_cause, binder) + .is_err() + { + return false; + } } &ty::Predicate::TypeOutlives(ref binder) => { match ( diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index eb284645d36c8..3eb49092fed1d 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -730,9 +730,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } ty::Predicate::RegionOutlives(ref predicate) => { - // These errors should show up as region - // inference failures. - panic!("region outlives {:?} failed", predicate); + let predicate = self.resolve_type_vars_if_possible(predicate); + let err = self.region_outlives_predicate(&obligation.cause, + &predicate).err().unwrap(); + struct_span_err!( + self.tcx.sess, span, E0279, + "the requirement `{}` is not satisfied (`{}`)", + predicate, err, + ) } ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => { diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 587f57bb09dee..7648bde1d3c87 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -331,8 +331,10 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx, } ty::Predicate::RegionOutlives(ref binder) => { - let () = self.selcx.infcx().region_outlives_predicate(&obligation.cause, binder); - ProcessResult::Changed(vec![]) + match self.selcx.infcx().region_outlives_predicate(&obligation.cause, binder) { + Ok(()) => ProcessResult::Changed(vec![]), + Err(_) => ProcessResult::Error(CodeSelectionError(Unimplemented)), + } } ty::Predicate::TypeOutlives(ref binder) => { diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 5a44d886e3c0a..05141c9daf1d4 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -191,12 +191,15 @@ pub fn poly_project_and_unify_type<'cx, 'gcx, 'tcx>( obligation); let infcx = selcx.infcx(); - infcx.commit_if_ok(|_| { - let (placeholder_predicate, _) = + infcx.commit_if_ok(|snapshot| { + let (placeholder_predicate, placeholder_map) = infcx.replace_bound_vars_with_placeholders(&obligation.predicate); let placeholder_obligation = obligation.with(placeholder_predicate); - project_and_unify_type(selcx, &placeholder_obligation) + let result = project_and_unify_type(selcx, &placeholder_obligation)?; + infcx.leak_check(false, &placeholder_map, snapshot) + .map_err(|err| MismatchedProjectionTypes { err })?; + Ok(result) }) } @@ -1427,9 +1430,8 @@ fn confirm_callable_candidate<'cx, 'gcx, 'tcx>( fn confirm_param_env_candidate<'cx, 'gcx, 'tcx>( selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, - poly_cache_entry: ty::PolyProjectionPredicate<'tcx>) - -> Progress<'tcx> -{ + poly_cache_entry: ty::PolyProjectionPredicate<'tcx>, +) -> Progress<'tcx> { let infcx = selcx.infcx(); let cause = &obligation.cause; let param_env = obligation.param_env; diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 34deb9ccdcabc..4a02b0331478f 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -29,7 +29,7 @@ use super::{ use crate::dep_graph::{DepKind, DepNodeIndex}; use crate::hir::def_id::DefId; -use crate::infer::{InferCtxt, InferOk, TypeFreshener}; +use crate::infer::{CombinedSnapshot, InferCtxt, InferOk, PlaceholderMap, TypeFreshener}; use crate::middle::lang_items; use crate::mir::interpret::GlobalId; use crate::ty::fast_reject; @@ -1667,8 +1667,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { _ => return, } - let result = self.infcx.probe(|_| { - self.match_projection_obligation_against_definition_bounds(obligation) + let result = self.infcx.probe(|snapshot| { + self.match_projection_obligation_against_definition_bounds( + obligation, + snapshot, + ) }); if result { @@ -1679,10 +1682,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn match_projection_obligation_against_definition_bounds( &mut self, obligation: &TraitObligation<'tcx>, + snapshot: &CombinedSnapshot<'_, 'tcx>, ) -> bool { let poly_trait_predicate = self.infcx() .resolve_type_vars_if_possible(&obligation.predicate); - let (placeholder_trait_predicate, _) = self.infcx() + let (placeholder_trait_predicate, placeholder_map) = self.infcx() .replace_bound_vars_with_placeholders(&poly_trait_predicate); debug!( "match_projection_obligation_against_definition_bounds: \ @@ -1724,6 +1728,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation, bound.clone(), placeholder_trait_predicate.trait_ref.clone(), + &placeholder_map, + snapshot, ) }) }); @@ -1741,6 +1747,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation, bound, placeholder_trait_predicate.trait_ref.clone(), + &placeholder_map, + snapshot, ); assert!(result); @@ -1754,12 +1762,16 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation: &TraitObligation<'tcx>, trait_bound: ty::PolyTraitRef<'tcx>, placeholder_trait_ref: ty::TraitRef<'tcx>, + placeholder_map: &PlaceholderMap<'tcx>, + snapshot: &CombinedSnapshot<'_, 'tcx>, ) -> bool { debug_assert!(!placeholder_trait_ref.has_escaping_bound_vars()); self.infcx .at(&obligation.cause, obligation.param_env) .sup(ty::Binder::dummy(placeholder_trait_ref), trait_bound) .is_ok() + && + self.infcx.leak_check(false, placeholder_map, snapshot).is_ok() } /// Given an obligation like ``, search the obligations that the caller @@ -1960,8 +1972,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation.predicate.def_id(), obligation.predicate.skip_binder().trait_ref.self_ty(), |impl_def_id| { - self.infcx.probe(|_| { - if let Ok(_substs) = self.match_impl(impl_def_id, obligation) + self.infcx.probe(|snapshot| { + if let Ok(_substs) = self.match_impl(impl_def_id, obligation, snapshot) { candidates.vec.push(ImplCandidate(impl_def_id)); } @@ -2758,9 +2770,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } fn confirm_projection_candidate(&mut self, obligation: &TraitObligation<'tcx>) { - self.infcx.in_snapshot(|_| { + self.infcx.in_snapshot(|snapshot| { let result = - self.match_projection_obligation_against_definition_bounds(obligation); + self.match_projection_obligation_against_definition_bounds( + obligation, + snapshot, + ); assert!(result); }) } @@ -2912,8 +2927,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // First, create the substitutions by matching the impl again, // this time not in a probe. - self.infcx.in_snapshot(|_| { - let substs = self.rematch_impl(impl_def_id, obligation); + self.infcx.in_snapshot(|snapshot| { + let substs = self.rematch_impl(impl_def_id, obligation, snapshot); debug!("confirm_impl_candidate: substs={:?}", substs); let cause = obligation.derived_cause(ImplDerivedObligation); self.vtable_impl( @@ -3504,8 +3519,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { &mut self, impl_def_id: DefId, obligation: &TraitObligation<'tcx>, + snapshot: &CombinedSnapshot<'_, 'tcx>, ) -> Normalized<'tcx, &'tcx Substs<'tcx>> { - match self.match_impl(impl_def_id, obligation) { + match self.match_impl(impl_def_id, obligation, snapshot) { Ok(substs) => substs, Err(()) => { bug!( @@ -3521,6 +3537,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { &mut self, impl_def_id: DefId, obligation: &TraitObligation<'tcx>, + snapshot: &CombinedSnapshot<'_, 'tcx>, ) -> Result>, ()> { let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap(); @@ -3531,7 +3548,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { return Err(()); } - let (skol_obligation, _) = self.infcx() + let (skol_obligation, placeholder_map) = self.infcx() .replace_bound_vars_with_placeholders(&obligation.predicate); let skol_obligation_trait_ref = skol_obligation.trait_ref; @@ -3563,6 +3580,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { .map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{}`", e))?; nested_obligations.extend(obligations); + if let Err(e) = self.infcx.leak_check(false, &placeholder_map, snapshot) { + debug!("match_impl: failed leak check due to `{}`", e); + return Err(()); + } + debug!("match_impl: success impl_substs={:?}", impl_substs); Ok(Normalized { value: impl_substs, From fd0e76442b484b3fc752018a9440cf73e324bb89 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 20 Feb 2019 05:39:04 -0500 Subject: [PATCH 09/12] restore the actual leak-check --- src/librustc/infer/higher_ranked/mod.rs | 19 +- .../infer/region_constraints/leak_check.rs | 162 ++++++++++++++++++ src/librustc/infer/region_constraints/mod.rs | 2 + src/librustc/ty/error.rs | 16 +- src/librustc/ty/structural_impls.rs | 8 + src/test/ui/hrtb/issue-46989.rs | 42 +++++ src/test/ui/hrtb/issue-57639.rs | 29 ++++ src/test/ui/hrtb/issue-58451.rs | 13 ++ 8 files changed, 277 insertions(+), 14 deletions(-) create mode 100644 src/librustc/infer/region_constraints/leak_check.rs create mode 100644 src/test/ui/hrtb/issue-46989.rs create mode 100644 src/test/ui/hrtb/issue-57639.rs create mode 100644 src/test/ui/hrtb/issue-58451.rs diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index 50487f488852d..7c83fe7fd6946 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -113,21 +113,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { (result, map) } - /// Searches region constraints created since `snapshot` that - /// affect one of the placeholders in `placeholder_map`, returning - /// an error if any of the placeholders are related to another - /// placeholder or would have to escape into some parent universe - /// that cannot name them. - /// - /// This is a temporary backwards compatibility measure to try and - /// retain the older (arguably incorrect) behavior of the - /// compiler. + /// See `infer::region_constraints::RegionConstraintCollector::leak_check`. pub fn leak_check( &self, - _overly_polymorphic: bool, - _placeholder_map: &PlaceholderMap<'tcx>, - _snapshot: &CombinedSnapshot<'_, 'tcx>, + overly_polymorphic: bool, + placeholder_map: &PlaceholderMap<'tcx>, + snapshot: &CombinedSnapshot<'_, 'tcx>, ) -> RelateResult<'tcx, ()> { - Ok(()) + self.borrow_region_constraints() + .leak_check(self.tcx, overly_polymorphic, placeholder_map, snapshot) } } diff --git a/src/librustc/infer/region_constraints/leak_check.rs b/src/librustc/infer/region_constraints/leak_check.rs new file mode 100644 index 0000000000000..4056b9e2d83bc --- /dev/null +++ b/src/librustc/infer/region_constraints/leak_check.rs @@ -0,0 +1,162 @@ +use super::*; +use crate::infer::{CombinedSnapshot, PlaceholderMap}; +use crate::ty::error::TypeError; +use crate::ty::relate::RelateResult; + +impl<'tcx> RegionConstraintCollector<'tcx> { + /// Searches region constraints created since `snapshot` that + /// affect one of the placeholders in `placeholder_map`, returning + /// an error if any of the placeholders are related to another + /// placeholder or would have to escape into some parent universe + /// that cannot name them. + /// + /// This is a temporary backwards compatibility measure to try and + /// retain the older (arguably incorrect) behavior of the + /// compiler. + /// + /// NB. The use of snapshot here is mostly an efficiency thing -- + /// we could search *all* region constraints, but that'd be a + /// bigger set and the data structures are not setup for that. If + /// we wind up keeping some form of this check long term, it would + /// probably be better to remove the snapshot parameter and to + /// refactor the constraint set. + pub fn leak_check( + &mut self, + tcx: TyCtxt<'_, '_, 'tcx>, + overly_polymorphic: bool, + placeholder_map: &PlaceholderMap<'tcx>, + _snapshot: &CombinedSnapshot<'_, 'tcx>, + ) -> RelateResult<'tcx, ()> { + debug!("leak_check(placeholders={:?})", placeholder_map); + + assert!(self.in_snapshot()); + + // Go through each placeholder that we created. + for (_, &placeholder_region) in placeholder_map { + // Find the universe this placeholder inhabits. + let placeholder = match placeholder_region { + ty::RePlaceholder(p) => p, + _ => bug!( + "leak_check: expected placeholder found {:?}", + placeholder_region, + ), + }; + + // Find all regions that are related to this placeholder + // in some way. This means any region that either outlives + // or is outlived by a placeholder. + let mut taint_set = TaintSet::new( + TaintDirections::both(), + placeholder_region, + ); + taint_set.fixed_point(tcx, &self.undo_log, &self.data.verifys); + let tainted_regions = taint_set.into_set(); + + // Report an error if two placeholders in the same universe + // are related to one another, or if a placeholder is related + // to something from a parent universe. + for &tainted_region in &tainted_regions { + if let ty::RePlaceholder(_) = tainted_region { + // Two placeholders cannot be related: + if tainted_region == placeholder_region { + continue; + } + } else if self.universe(tainted_region).can_name(placeholder.universe) { + continue; + } + + return Err(if overly_polymorphic { + debug!("Overly polymorphic!"); + TypeError::RegionsOverlyPolymorphic(placeholder.name, tainted_region) + } else { + debug!("Not as polymorphic!"); + TypeError::RegionsInsufficientlyPolymorphic(placeholder.name, tainted_region) + }); + } + } + + Ok(()) + } +} + +#[derive(Debug)] +struct TaintSet<'tcx> { + directions: TaintDirections, + regions: FxHashSet>, +} + +impl<'tcx> TaintSet<'tcx> { + fn new(directions: TaintDirections, initial_region: ty::Region<'tcx>) -> Self { + let mut regions = FxHashSet::default(); + regions.insert(initial_region); + TaintSet { + directions: directions, + regions: regions, + } + } + + fn fixed_point( + &mut self, + tcx: TyCtxt<'_, '_, 'tcx>, + undo_log: &[UndoLog<'tcx>], + verifys: &[Verify<'tcx>], + ) { + let mut prev_len = 0; + while prev_len < self.len() { + debug!( + "tainted: prev_len = {:?} new_len = {:?}", + prev_len, + self.len() + ); + + prev_len = self.len(); + + for undo_entry in undo_log { + match undo_entry { + &AddConstraint(Constraint::VarSubVar(a, b)) => { + self.add_edge(tcx.mk_region(ReVar(a)), tcx.mk_region(ReVar(b))); + } + &AddConstraint(Constraint::RegSubVar(a, b)) => { + self.add_edge(a, tcx.mk_region(ReVar(b))); + } + &AddConstraint(Constraint::VarSubReg(a, b)) => { + self.add_edge(tcx.mk_region(ReVar(a)), b); + } + &AddConstraint(Constraint::RegSubReg(a, b)) => { + self.add_edge(a, b); + } + &AddGiven(a, b) => { + self.add_edge(a, tcx.mk_region(ReVar(b))); + } + &AddVerify(i) => span_bug!( + verifys[i].origin.span(), + "we never add verifications while doing higher-ranked things", + ), + &Purged | &AddCombination(..) | &AddVar(..) => {} + } + } + } + } + + fn into_set(self) -> FxHashSet> { + self.regions + } + + fn len(&self) -> usize { + self.regions.len() + } + + fn add_edge(&mut self, source: ty::Region<'tcx>, target: ty::Region<'tcx>) { + if self.directions.incoming { + if self.regions.contains(&target) { + self.regions.insert(source); + } + } + + if self.directions.outgoing { + if self.regions.contains(&source) { + self.regions.insert(target); + } + } + } +} diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 45d614167ea91..8389f0ab1aa79 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -17,6 +17,8 @@ use crate::ty::{Region, RegionVid}; use std::collections::BTreeMap; use std::{cmp, fmt, mem, u32}; +mod leak_check; + #[derive(Default)] pub struct RegionConstraintCollector<'tcx> { /// For each `RegionVid`, the corresponding `RegionVariableOrigin`. diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index e3e0ce147741f..f58e5e4fb69f6 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -1,5 +1,5 @@ use crate::hir::def_id::DefId; -use crate::ty::{self, Region, Ty, TyCtxt}; +use crate::ty::{self, BoundRegion, Region, Ty, TyCtxt}; use std::borrow::Cow; use std::fmt; use rustc_target::spec::abi; @@ -27,6 +27,8 @@ pub enum TypeError<'tcx> { ArgCount, RegionsDoesNotOutlive(Region<'tcx>, Region<'tcx>), + RegionsInsufficientlyPolymorphic(BoundRegion, Region<'tcx>), + RegionsOverlyPolymorphic(BoundRegion, Region<'tcx>), RegionsPlaceholderMismatch, Sorts(ExpectedFound>), @@ -101,6 +103,18 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { RegionsDoesNotOutlive(..) => { write!(f, "lifetime mismatch") } + RegionsInsufficientlyPolymorphic(br, _) => { + write!(f, + "expected bound lifetime parameter{}{}, found concrete lifetime", + if br.is_named() { " " } else { "" }, + br) + } + RegionsOverlyPolymorphic(br, _) => { + write!(f, + "expected concrete lifetime, found bound lifetime parameter{}{}", + if br.is_named() { " " } else { "" }, + br) + } RegionsPlaceholderMismatch => { write!(f, "one type is more general than the other") } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index d09cfa84a1690..f9173836cc627 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -434,6 +434,12 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> { RegionsDoesNotOutlive(a, b) => { return tcx.lift(&(a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b)) } + RegionsInsufficientlyPolymorphic(a, b) => { + return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b)) + } + RegionsOverlyPolymorphic(a, b) => { + return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b)) + } RegionsPlaceholderMismatch => RegionsPlaceholderMismatch, IntMismatch(x) => IntMismatch(x), FloatMismatch(x) => FloatMismatch(x), @@ -1021,6 +1027,8 @@ EnumTypeFoldableImpl! { (ty::error::TypeError::FixedArraySize)(x), (ty::error::TypeError::ArgCount), (ty::error::TypeError::RegionsDoesNotOutlive)(a, b), + (ty::error::TypeError::RegionsInsufficientlyPolymorphic)(a, b), + (ty::error::TypeError::RegionsOverlyPolymorphic)(a, b), (ty::error::TypeError::RegionsPlaceholderMismatch), (ty::error::TypeError::IntMismatch)(x), (ty::error::TypeError::FloatMismatch)(x), diff --git a/src/test/ui/hrtb/issue-46989.rs b/src/test/ui/hrtb/issue-46989.rs new file mode 100644 index 0000000000000..2c85905545807 --- /dev/null +++ b/src/test/ui/hrtb/issue-46989.rs @@ -0,0 +1,42 @@ +// Regression test for #46989: +// +// In the move to universes, this test started passing. +// It is not necessarily WRONG to do so, but it was a bit +// surprising. The reason that it passed is that when we were +// asked to prove that +// +// for<'a> fn(&'a i32): Foo +// +// we were able to use the impl below to prove +// +// fn(&'empty i32): Foo +// +// and then we were able to prove that +// +// fn(&'empty i32) = for<'a> fn(&'a i32) +// +// This last fact is somewhat surprising, but essentially "falls out" +// from handling variance correctly. In particular, consider the subtyping +// relations. First: +// +// fn(&'empty i32) <: for<'a> fn(&'a i32) +// +// This holds because -- intuitively -- a fn that takes a reference but doesn't use +// it can be given a reference with any lifetime. Similarly, the opposite direction: +// +// for<'a> fn(&'a i32) <: fn(&'empty i32) +// +// holds because 'a can be instantiated to 'empty. + +trait Foo { + +} + +impl Foo for fn(A) { } + +fn assert_foo() {} + +fn main() { + assert_foo::(); + //~^ ERROR the trait bound `for<'r> fn(&'r i32): Foo` is not satisfied +} diff --git a/src/test/ui/hrtb/issue-57639.rs b/src/test/ui/hrtb/issue-57639.rs new file mode 100644 index 0000000000000..4bcaef3616bd5 --- /dev/null +++ b/src/test/ui/hrtb/issue-57639.rs @@ -0,0 +1,29 @@ +// Regression test for #57639: +// +// In the move to universes, this test stopped working. The problem +// was that when the trait solver was asked to prove `for<'a> T::Item: +// Foo<'a>` as part of WF checking, it wound up "eagerly committing" +// to the where clause, which says that `T::Item: Foo<'a>`, but it +// should instead have been using the bound found in the trait +// declaration. Pre-universe, this used to work out ok because we got +// "eager errors" due to the leak check. +// +// See [this comment on GitHub][c] for more details. +// +// run-pass +// +// [c]: https://github.com/rust-lang/rust/issues/57639#issuecomment-455685861 + +trait Foo<'a> {} + +trait Bar { + type Item: for<'a> Foo<'a>; +} + +fn foo<'a, T>(_: T) +where + T: Bar, + T::Item: Foo<'a>, +{} + +fn main() { } diff --git a/src/test/ui/hrtb/issue-58451.rs b/src/test/ui/hrtb/issue-58451.rs new file mode 100644 index 0000000000000..7ca6914d2ea96 --- /dev/null +++ b/src/test/ui/hrtb/issue-58451.rs @@ -0,0 +1,13 @@ +// Regression test for #58451: +// +// Error reporting here encountered an ICE in the shift to universes. + +fn f(i: I) +where + I: IntoIterator, + I::Item: for<'a> Into<&'a ()>, +{} + +fn main() { + f(&[f()]); +} From 79de8bd8ddb225fabb9381927963d01c2cb388bf Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 20 Feb 2019 12:52:23 -0500 Subject: [PATCH 10/12] update test files to reflect new output One surprise: old-lub-glb-object.rs, may indicate a bug --- .../infer/region_constraints/leak_check.rs | 12 ++ .../ui/anonymous-higher-ranked-lifetime.rs | 11 + .../anonymous-higher-ranked-lifetime.stderr | 196 ++++++++++++++++-- .../associated-types-eq-hr.rs | 8 +- .../associated-types-eq-hr.stderr | 95 +++++++-- .../higher-ranked-projection.bad.stderr | 15 +- .../higher-ranked-projection.good.stderr | 2 +- .../higher-ranked-projection.rs | 2 +- .../expect-fn-supply-fn.rs | 6 +- .../expect-fn-supply-fn.stderr | 57 +++-- .../coherence/coherence-subtyping.old.stderr | 14 -- .../coherence/coherence-subtyping.re.stderr | 14 -- src/test/ui/coherence/coherence-subtyping.rs | 6 +- ...pe.bound_a_b_ret_a_vs_bound_a_ret_a.stderr | 2 +- .../hr-subtype.bound_a_b_vs_bound_a.stderr | 22 +- .../hr-subtype.bound_a_vs_bound_a.stderr | 6 +- .../hr-subtype.bound_a_vs_bound_b.stderr | 6 +- .../hr-subtype.bound_a_vs_free_x.stderr | 2 +- ...-subtype.bound_co_a_b_vs_bound_co_a.stderr | 22 +- ...ubtype.bound_co_a_co_b_ret_contra_a.stderr | 22 +- ...hr-subtype.bound_co_a_vs_bound_co_b.stderr | 6 +- ...pe.bound_contra_a_contra_b_ret_co_a.stderr | 22 +- ...ubtype.bound_inv_a_b_vs_bound_inv_a.stderr | 2 +- ...-subtype.bound_inv_a_vs_bound_inv_b.stderr | 6 +- .../hr-subtype.free_x_vs_free_x.stderr | 6 +- src/test/ui/hr-subtype/hr-subtype.rs | 8 +- src/test/ui/hrtb/hrtb-conflate-regions.stderr | 18 +- src/test/ui/hrtb/hrtb-exists-forall-fn.stderr | 2 +- .../hrtb-exists-forall-trait-contravariant.rs | 7 +- ...b-exists-forall-trait-contravariant.stderr | 21 ++ .../hrtb-exists-forall-trait-covariant.rs | 7 +- .../hrtb-exists-forall-trait-covariant.stderr | 21 ++ .../hrtb-exists-forall-trait-invariant.rs | 2 +- .../hrtb-exists-forall-trait-invariant.stderr | 21 +- ...igher-ranker-supertraits-transitive.stderr | 17 +- .../ui/hrtb/hrtb-higher-ranker-supertraits.rs | 4 +- .../hrtb-higher-ranker-supertraits.stderr | 41 +++- src/test/ui/hrtb/hrtb-just-for-static.stderr | 35 +++- src/test/ui/hrtb/issue-46989.stderr | 17 ++ src/test/ui/hrtb/issue-58451.rs | 2 +- src/test/ui/hrtb/issue-58451.stderr | 16 ++ src/test/ui/issues/issue-40000.stderr | 6 +- src/test/ui/issues/issue-57362-1.rs | 2 +- src/test/ui/issues/issue-57362-1.stderr | 11 +- src/test/ui/issues/issue-57362-2.rs | 2 +- src/test/ui/issues/issue-57362-2.stderr | 16 +- src/test/ui/lub-glb/old-lub-glb-hr.rs | 5 +- src/test/ui/lub-glb/old-lub-glb-hr.stderr | 18 ++ src/test/ui/lub-glb/old-lub-glb-object.rs | 6 +- src/test/ui/lub-glb/old-lub-glb-object.stderr | 16 -- .../closure-arg-type-mismatch.rs | 4 +- .../closure-arg-type-mismatch.stderr | 33 +-- .../ui/mismatched_types/closure-mismatch.rs | 3 +- .../mismatched_types/closure-mismatch.stderr | 34 ++- src/test/ui/mismatched_types/issue-36053-2.rs | 1 + .../ui/mismatched_types/issue-36053-2.stderr | 10 +- ...regions-fn-subtyping-return-static-fail.rs | 4 +- ...ons-fn-subtyping-return-static-fail.stderr | 17 +- ...lifetime-bounds-on-fns-where-clause.stderr | 4 +- ...lifetime-bounds-on-fns-where-clause.stderr | 4 +- .../regions-fn-subtyping-return-static.rs | 4 +- .../regions-fn-subtyping-return-static.stderr | 12 ++ .../regions-lifetime-bounds-on-fns.stderr | 4 +- .../unboxed-closures-unsafe-extern-fn.rs | 2 + .../unboxed-closures-unsafe-extern-fn.stderr | 34 ++- .../unboxed-closures-wrong-abi.rs | 2 + .../unboxed-closures-wrong-abi.stderr | 34 ++- ...boxed-closures-wrong-arg-type-extern-fn.rs | 2 + ...d-closures-wrong-arg-type-extern-fn.stderr | 34 ++- src/test/ui/where-clauses/where-for-self-2.rs | 2 +- .../ui/where-clauses/where-for-self-2.stderr | 19 +- 71 files changed, 846 insertions(+), 300 deletions(-) delete mode 100644 src/test/ui/coherence/coherence-subtyping.old.stderr delete mode 100644 src/test/ui/coherence/coherence-subtyping.re.stderr create mode 100644 src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr create mode 100644 src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.stderr create mode 100644 src/test/ui/hrtb/issue-46989.stderr create mode 100644 src/test/ui/hrtb/issue-58451.stderr create mode 100644 src/test/ui/lub-glb/old-lub-glb-hr.stderr delete mode 100644 src/test/ui/lub-glb/old-lub-glb-object.stderr create mode 100644 src/test/ui/regions/regions-fn-subtyping-return-static.stderr diff --git a/src/librustc/infer/region_constraints/leak_check.rs b/src/librustc/infer/region_constraints/leak_check.rs index 4056b9e2d83bc..8085258610d84 100644 --- a/src/librustc/infer/region_constraints/leak_check.rs +++ b/src/librustc/infer/region_constraints/leak_check.rs @@ -31,6 +31,18 @@ impl<'tcx> RegionConstraintCollector<'tcx> { assert!(self.in_snapshot()); + // If the user gave `-Zno-leak-check`, then skip the leak + // check completely. This is wildly unsound and also not + // unlikely to cause an ICE or two. It is intended for use + // only during a transition period, in which the MIR typeck + // uses the "universe-style" check, and the rest of typeck + // uses the more conservative leak check. Since the leak + // check is more conservative, we can't test the + // universe-style check without disabling it. + if tcx.sess.opts.debugging_opts.no_leak_check { + return Ok(()); + } + // Go through each placeholder that we created. for (_, &placeholder_region) in placeholder_map { // Find the universe this placeholder inhabits. diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.rs b/src/test/ui/anonymous-higher-ranked-lifetime.rs index 55b1667da50b1..2e2a124db9a5d 100644 --- a/src/test/ui/anonymous-higher-ranked-lifetime.rs +++ b/src/test/ui/anonymous-higher-ranked-lifetime.rs @@ -1,15 +1,26 @@ fn main() { f1(|_: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch f2(|_: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch f3(|_: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch f4(|_: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch f5(|_: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch g1(|_: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch g2(|_: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch g3(|_: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch g4(|_: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch h1(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch h2(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch + //~^ ERROR type mismatch } // Basic diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.stderr b/src/test/ui/anonymous-higher-ranked-lifetime.stderr index d2c722e32b210..378f352cb9228 100644 --- a/src/test/ui/anonymous-higher-ranked-lifetime.stderr +++ b/src/test/ui/anonymous-higher-ranked-lifetime.stderr @@ -7,13 +7,27 @@ LL | f1(|_: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'r, 's> fn(&'r (), &'s ()) -> _` | note: required by `f1` - --> $DIR/anonymous-higher-ranked-lifetime.rs:16:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:27:1 | LL | fn f1(_: F) where F: Fn(&(), &()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:3:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:2:5 + | +LL | f1(|_: (), _: ()| {}); //~ ERROR type mismatch + | ^^ -------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `fn(&(), &()) -> _` + | +note: required by `f1` + --> $DIR/anonymous-higher-ranked-lifetime.rs:27:1 + | +LL | fn f1(_: F) where F: Fn(&(), &()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:4:5 | LL | f2(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ -------------- found signature of `fn((), ()) -> _` @@ -21,7 +35,7 @@ LL | f2(|_: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'a, 'r> fn(&'a (), &'r ()) -> _` | note: required by `f2` - --> $DIR/anonymous-higher-ranked-lifetime.rs:17:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:28:1 | LL | fn f2(_: F) where F: for<'a> Fn(&'a (), &()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -29,19 +43,47 @@ LL | fn f2(_: F) where F: for<'a> Fn(&'a (), &()) {} error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:4:5 | +LL | f2(|_: (), _: ()| {}); //~ ERROR type mismatch + | ^^ -------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `fn(&'a (), &()) -> _` + | +note: required by `f2` + --> $DIR/anonymous-higher-ranked-lifetime.rs:28:1 + | +LL | fn f2(_: F) where F: for<'a> Fn(&'a (), &()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:6:5 + | LL | f3(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ -------------- found signature of `fn((), ()) -> _` | | | expected signature of `for<'r> fn(&(), &'r ()) -> _` | note: required by `f3` - --> $DIR/anonymous-higher-ranked-lifetime.rs:18:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:29:1 | LL | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:5:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:6:5 + | +LL | f3(|_: (), _: ()| {}); //~ ERROR type mismatch + | ^^ -------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `fn(&(), &()) -> _` + | +note: required by `f3` + --> $DIR/anonymous-higher-ranked-lifetime.rs:29:1 + | +LL | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5 | LL | f4(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ -------------- found signature of `fn((), ()) -> _` @@ -49,13 +91,27 @@ LL | f4(|_: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'s, 'r> fn(&'s (), &'r ()) -> _` | note: required by `f4` - --> $DIR/anonymous-higher-ranked-lifetime.rs:19:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:30:1 | LL | fn f4(_: F) where F: for<'r> Fn(&(), &'r ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:6:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5 + | +LL | f4(|_: (), _: ()| {}); //~ ERROR type mismatch + | ^^ -------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `fn(&(), &'r ()) -> _` + | +note: required by `f4` + --> $DIR/anonymous-higher-ranked-lifetime.rs:30:1 + | +LL | fn f4(_: F) where F: for<'r> Fn(&(), &'r ()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5 | LL | f5(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ -------------- found signature of `fn((), ()) -> _` @@ -63,13 +119,27 @@ LL | f5(|_: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'r> fn(&'r (), &'r ()) -> _` | note: required by `f5` - --> $DIR/anonymous-higher-ranked-lifetime.rs:20:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:31:1 | LL | fn f5(_: F) where F: for<'r> Fn(&'r (), &'r ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:7:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5 + | +LL | f5(|_: (), _: ()| {}); //~ ERROR type mismatch + | ^^ -------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `fn(&'r (), &'r ()) -> _` + | +note: required by `f5` + --> $DIR/anonymous-higher-ranked-lifetime.rs:31:1 + | +LL | fn f5(_: F) where F: for<'r> Fn(&'r (), &'r ()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5 | LL | g1(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ -------------- found signature of `fn((), ()) -> _` @@ -77,13 +147,27 @@ LL | g1(|_: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'r> fn(&'r (), std::boxed::Box<(dyn for<'s> std::ops::Fn(&'s ()) + 'static)>) -> _` | note: required by `g1` - --> $DIR/anonymous-higher-ranked-lifetime.rs:23:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:34:1 | LL | fn g1(_: F) where F: Fn(&(), Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5 + | +LL | g1(|_: (), _: ()| {}); //~ ERROR type mismatch + | ^^ -------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _` + | +note: required by `g1` + --> $DIR/anonymous-higher-ranked-lifetime.rs:34:1 + | +LL | fn g1(_: F) where F: Fn(&(), Box) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:14:5 | LL | g2(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ -------------- found signature of `fn((), ()) -> _` @@ -91,13 +175,27 @@ LL | g2(|_: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'r> fn(&'r (), for<'s> fn(&'s ())) -> _` | note: required by `g2` - --> $DIR/anonymous-higher-ranked-lifetime.rs:24:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:35:1 | LL | fn g2(_: F) where F: Fn(&(), fn(&())) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:9:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:14:5 + | +LL | g2(|_: (), _: ()| {}); //~ ERROR type mismatch + | ^^ -------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `fn(&(), for<'r> fn(&'r ())) -> _` + | +note: required by `g2` + --> $DIR/anonymous-higher-ranked-lifetime.rs:35:1 + | +LL | fn g2(_: F) where F: Fn(&(), fn(&())) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:16:5 | LL | g3(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ -------------- found signature of `fn((), ()) -> _` @@ -105,13 +203,27 @@ LL | g3(|_: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'s> fn(&'s (), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _` | note: required by `g3` - --> $DIR/anonymous-higher-ranked-lifetime.rs:25:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:36:1 | LL | fn g3(_: F) where F: for<'s> Fn(&'s (), Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:16:5 + | +LL | g3(|_: (), _: ()| {}); //~ ERROR type mismatch + | ^^ -------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `fn(&'s (), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _` + | +note: required by `g3` + --> $DIR/anonymous-higher-ranked-lifetime.rs:36:1 + | +LL | fn g3(_: F) where F: for<'s> Fn(&'s (), Box) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:18:5 | LL | g4(|_: (), _: ()| {}); //~ ERROR type mismatch | ^^ -------------- found signature of `fn((), ()) -> _` @@ -119,13 +231,27 @@ LL | g4(|_: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'s> fn(&'s (), for<'r> fn(&'r ())) -> _` | note: required by `g4` - --> $DIR/anonymous-higher-ranked-lifetime.rs:26:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:37:1 + | +LL | fn g4(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:18:5 + | +LL | g4(|_: (), _: ()| {}); //~ ERROR type mismatch + | ^^ -------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `fn(&(), for<'r> fn(&'r ())) -> _` + | +note: required by `g4` + --> $DIR/anonymous-higher-ranked-lifetime.rs:37:1 | LL | fn g4(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:11:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:20:5 | LL | h1(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch | ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _` @@ -133,13 +259,27 @@ LL | h1(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'r, 's> fn(&'r (), std::boxed::Box<(dyn for<'t0> std::ops::Fn(&'t0 ()) + 'static)>, &'s (), for<'t0, 't1> fn(&'t0 (), &'t1 ())) -> _` | note: required by `h1` - --> $DIR/anonymous-higher-ranked-lifetime.rs:29:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:40:1 | LL | fn h1(_: F) where F: Fn(&(), Box, &(), fn(&(), &())) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments - --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5 + --> $DIR/anonymous-higher-ranked-lifetime.rs:20:5 + | +LL | h1(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch + | ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _` + | | + | expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>, &(), for<'r, 's> fn(&'r (), &'s ())) -> _` + | +note: required by `h1` + --> $DIR/anonymous-higher-ranked-lifetime.rs:40:1 + | +LL | fn h1(_: F) where F: Fn(&(), Box, &(), fn(&(), &())) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:22:5 | LL | h2(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch | ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _` @@ -147,11 +287,25 @@ LL | h2(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch | expected signature of `for<'r, 't0> fn(&'r (), std::boxed::Box<(dyn for<'s> std::ops::Fn(&'s ()) + 'static)>, &'t0 (), for<'s, 't1> fn(&'s (), &'t1 ())) -> _` | note: required by `h2` - --> $DIR/anonymous-higher-ranked-lifetime.rs:30:1 + --> $DIR/anonymous-higher-ranked-lifetime.rs:41:1 + | +LL | fn h2(_: F) where F: for<'t0> Fn(&(), Box, &'t0 (), fn(&(), &())) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:22:5 + | +LL | h2(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch + | ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _` + | | + | expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>, &'t0 (), for<'r, 's> fn(&'r (), &'s ())) -> _` + | +note: required by `h2` + --> $DIR/anonymous-higher-ranked-lifetime.rs:41:1 | LL | fn h2(_: F) where F: for<'t0> Fn(&(), Box, &'t0 (), fn(&(), &())) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 11 previous errors +error: aborting due to 22 previous errors For more information about this error, try `rustc --explain E0631`. diff --git a/src/test/ui/associated-types/associated-types-eq-hr.rs b/src/test/ui/associated-types/associated-types-eq-hr.rs index 20fa1e7a48db1..e6afa3f71c2f0 100644 --- a/src/test/ui/associated-types/associated-types-eq-hr.rs +++ b/src/test/ui/associated-types/associated-types-eq-hr.rs @@ -89,12 +89,14 @@ pub fn call_bar() { pub fn call_tuple_one() { tuple_one::(); - //~^ ERROR not general enough + //~^ ERROR not satisfied + //~| ERROR type mismatch } pub fn call_tuple_two() { tuple_two::(); - //~^ ERROR not general enough + //~^ ERROR not satisfied + //~| ERROR type mismatch } pub fn call_tuple_three() { @@ -103,7 +105,7 @@ pub fn call_tuple_three() { pub fn call_tuple_four() { tuple_four::(); - //~^ ERROR not general enough + //~^ ERROR not satisfied } fn main() { } diff --git a/src/test/ui/associated-types/associated-types-eq-hr.stderr b/src/test/ui/associated-types/associated-types-eq-hr.stderr index 5299ebbb1ba8a..3721b69898876 100644 --- a/src/test/ui/associated-types/associated-types-eq-hr.stderr +++ b/src/test/ui/associated-types/associated-types-eq-hr.stderr @@ -34,36 +34,93 @@ LL | | // ok for UintStruct, but not IntStruct LL | | } | |_^ -error: implementation of `TheTrait` is not general enough +error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied --> $DIR/associated-types-eq-hr.rs:91:5 | LL | tuple_one::(); - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple` | - = note: Due to a where-clause on `tuple_one`, - = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1` - = note: but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` + = help: the following implementations were found: + > +note: required by `tuple_one` + --> $DIR/associated-types-eq-hr.rs:56:1 + | +LL | / fn tuple_one() +LL | | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize> +LL | | { +LL | | // not ok for tuple, two lifetimes and we pick first +LL | | } + | |_^ -error: implementation of `TheTrait` is not general enough - --> $DIR/associated-types-eq-hr.rs:96:5 +error[E0271]: type mismatch resolving `for<'x, 'y> >::A == &'x isize` + --> $DIR/associated-types-eq-hr.rs:91:5 + | +LL | tuple_one::(); + | ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime + | +note: required by `tuple_one` + --> $DIR/associated-types-eq-hr.rs:56:1 + | +LL | / fn tuple_one() +LL | | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize> +LL | | { +LL | | // not ok for tuple, two lifetimes and we pick first +LL | | } + | |_^ + +error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied + --> $DIR/associated-types-eq-hr.rs:97:5 | LL | tuple_two::(); - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple` + | + = help: the following implementations were found: + > +note: required by `tuple_two` + --> $DIR/associated-types-eq-hr.rs:62:1 | - = note: Due to a where-clause on `tuple_two`, - = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1` - = note: but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` +LL | / fn tuple_two() +LL | | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize> +LL | | { +LL | | // not ok for tuple, two lifetimes and we pick second +LL | | } + | |_^ + +error[E0271]: type mismatch resolving `for<'x, 'y> >::A == &'y isize` + --> $DIR/associated-types-eq-hr.rs:97:5 + | +LL | tuple_two::(); + | ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime + | +note: required by `tuple_two` + --> $DIR/associated-types-eq-hr.rs:62:1 + | +LL | / fn tuple_two() +LL | | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize> +LL | | { +LL | | // not ok for tuple, two lifetimes and we pick second +LL | | } + | |_^ -error: implementation of `TheTrait` is not general enough - --> $DIR/associated-types-eq-hr.rs:105:5 +error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied + --> $DIR/associated-types-eq-hr.rs:107:5 | LL | tuple_four::(); - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple` + | + = help: the following implementations were found: + > +note: required by `tuple_four` + --> $DIR/associated-types-eq-hr.rs:74:1 | - = note: Due to a where-clause on `tuple_four`, - = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1` - = note: but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` +LL | / fn tuple_four() +LL | | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize)> +LL | | { +LL | | // not ok for tuple, two lifetimes, and lifetime matching is invariant +LL | | } + | |_^ -error: aborting due to 5 previous errors +error: aborting due to 7 previous errors -For more information about this error, try `rustc --explain E0271`. +Some errors occurred: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr index 811c9a8f5e12b..cc69e849fe144 100644 --- a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr +++ b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr @@ -1,12 +1,17 @@ -error[E0308]: mismatched types +error[E0271]: type mismatch resolving `for<'a> <&'a _ as Mirror>::Image == _` --> $DIR/higher-ranked-projection.rs:25:5 | LL | foo(()); - | ^^^ one type is more general than the other + | ^^^ expected bound lifetime parameter 'a, found concrete lifetime | - = note: expected type `&'a ()` - found type `&()` +note: required by `foo` + --> $DIR/higher-ranked-projection.rs:14:1 + | +LL | / fn foo(_t: T) +LL | | where for<'a> &'a T: Mirror +LL | | {} + | |__^ error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/associated-types/higher-ranked-projection.good.stderr b/src/test/ui/associated-types/higher-ranked-projection.good.stderr index 92fd256285852..165e5213e0d34 100644 --- a/src/test/ui/associated-types/higher-ranked-projection.good.stderr +++ b/src/test/ui/associated-types/higher-ranked-projection.good.stderr @@ -3,7 +3,7 @@ error: compilation successful | LL | / fn main() { //[good]~ ERROR compilation successful LL | | foo(()); -LL | | //[bad]~^ ERROR mismatched types +LL | | //[bad]~^ ERROR type mismatch LL | | } | |_^ diff --git a/src/test/ui/associated-types/higher-ranked-projection.rs b/src/test/ui/associated-types/higher-ranked-projection.rs index fd7252f9e2253..a2ea6d8f206b6 100644 --- a/src/test/ui/associated-types/higher-ranked-projection.rs +++ b/src/test/ui/associated-types/higher-ranked-projection.rs @@ -23,5 +23,5 @@ fn foo(_t: T) #[rustc_error] fn main() { //[good]~ ERROR compilation successful foo(()); - //[bad]~^ ERROR mismatched types + //[bad]~^ ERROR type mismatch } diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn.rs b/src/test/ui/closure-expected-type/expect-fn-supply-fn.rs index 6977fd47a2e85..a4e43da91baf8 100644 --- a/src/test/ui/closure-expected-type/expect-fn-supply-fn.rs +++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn.rs @@ -28,14 +28,14 @@ fn expect_free_supply_bound() { // Here, we are given a function whose region is bound at closure level, // but we expect one bound in the argument. Error results. with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {}); - //~^ ERROR mismatched types + //~^ ERROR type mismatch } fn expect_bound_supply_free_from_fn<'x>(x: &'x u32) { // Here, we are given a `fn(&u32)` but we expect a `fn(&'x // u32)`. In principle, this could be ok, but we demand equality. with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {}); - //~^ ERROR mismatched types + //~^ ERROR type mismatch } fn expect_bound_supply_free_from_closure() { @@ -44,7 +44,7 @@ fn expect_bound_supply_free_from_closure() { // the argument level. type Foo<'a> = fn(&'a u32); with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| { - //~^ ERROR mismatched types + //~^ ERROR type mismatch }); } diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr index b1cfd6cef1022..ab35aeff697b7 100644 --- a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr +++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr @@ -36,33 +36,58 @@ note: ...does not necessarily outlive the anonymous lifetime #2 defined on the b LL | with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {}); | ^^^^^^^^^^^^^^^^^^^^^^ -error[E0308]: mismatched types - --> $DIR/expect-fn-supply-fn.rs:30:52 +error[E0631]: type mismatch in closure arguments + --> $DIR/expect-fn-supply-fn.rs:30:5 | LL | with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {}); - | ^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------- found signature of `fn(for<'r> fn(&'r u32), _) -> _` + | | + | expected signature of `fn(fn(&'a u32), &i32) -> _` | - = note: expected type `fn(&u32)` - found type `for<'r> fn(&'r u32)` +note: required by `with_closure_expecting_fn_with_free_region` + --> $DIR/expect-fn-supply-fn.rs:1:1 + | +LL | / fn with_closure_expecting_fn_with_free_region(_: F) +LL | | where F: for<'a> FnOnce(fn(&'a u32), &i32) +LL | | { +LL | | } + | |_^ -error[E0308]: mismatched types - --> $DIR/expect-fn-supply-fn.rs:37:53 +error[E0631]: type mismatch in closure arguments + --> $DIR/expect-fn-supply-fn.rs:37:5 | LL | with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {}); - | ^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------- found signature of `fn(fn(&'x u32), _) -> _` + | | + | expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _` | - = note: expected type `for<'r> fn(&'r u32)` - found type `fn(&'x u32)` +note: required by `with_closure_expecting_fn_with_bound_region` + --> $DIR/expect-fn-supply-fn.rs:6:1 + | +LL | / fn with_closure_expecting_fn_with_bound_region(_: F) +LL | | where F: FnOnce(fn(&u32), &i32) +LL | | { +LL | | } + | |_^ -error[E0308]: mismatched types - --> $DIR/expect-fn-supply-fn.rs:46:53 +error[E0631]: type mismatch in closure arguments + --> $DIR/expect-fn-supply-fn.rs:46:5 | LL | with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| { - | ^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- found signature of `for<'r> fn(fn(&'r u32), _) -> _` + | | + | expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _` + | +note: required by `with_closure_expecting_fn_with_bound_region` + --> $DIR/expect-fn-supply-fn.rs:6:1 | - = note: expected type `for<'r> fn(&'r u32)` - found type `fn(&u32)` +LL | / fn with_closure_expecting_fn_with_bound_region(_: F) +LL | | where F: FnOnce(fn(&u32), &i32) +LL | | { +LL | | } + | |_^ error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors occurred: E0308, E0631. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/coherence/coherence-subtyping.old.stderr b/src/test/ui/coherence/coherence-subtyping.old.stderr deleted file mode 100644 index db9f9f7665374..0000000000000 --- a/src/test/ui/coherence/coherence-subtyping.old.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0119]: conflicting implementations of trait `TheTrait` for type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`: - --> $DIR/coherence-subtyping.rs:15:1 - | -LL | impl TheTrait for for<'a,'b> fn(&'a u8, &'b u8) -> &'a u8 { - | --------------------------------------------------------- first implementation here -... -LL | impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` - | - = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-subtyping.re.stderr b/src/test/ui/coherence/coherence-subtyping.re.stderr deleted file mode 100644 index db9f9f7665374..0000000000000 --- a/src/test/ui/coherence/coherence-subtyping.re.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0119]: conflicting implementations of trait `TheTrait` for type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`: - --> $DIR/coherence-subtyping.rs:15:1 - | -LL | impl TheTrait for for<'a,'b> fn(&'a u8, &'b u8) -> &'a u8 { - | --------------------------------------------------------- first implementation here -... -LL | impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` - | - = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-subtyping.rs b/src/test/ui/coherence/coherence-subtyping.rs index f27e14eab63da..e74067578069e 100644 --- a/src/test/ui/coherence/coherence-subtyping.rs +++ b/src/test/ui/coherence/coherence-subtyping.rs @@ -1,7 +1,11 @@ // Test that two distinct impls which match subtypes of one another // yield coherence errors (or not) depending on the variance. +// +// Note: This scenario is currently accepted, but as part of the +// universe transition (#56105) may eventually become an error. // revisions: old re +// compile-pass #![cfg_attr(re, feature(re_rebalance_coherence))] @@ -13,8 +17,6 @@ impl TheTrait for for<'a,'b> fn(&'a u8, &'b u8) -> &'a u8 { } impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { - //[old]~^ ERROR - //[re]~^^ ERROR } fn main() { } diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr index bdfabdabbebb7..8e2b0b8c60045 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/hr-subtype.rs:39:26 | LL | gimme::<$t1>(None::<$t2>); - | ^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a ... LL | / check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u32) -> &'a u32, LL | | for<'a> fn(&'a u32, &'a u32) -> &'a u32) } diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_b_vs_bound_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_b_vs_bound_a.stderr index 25b74d855bb48..dbb5018139076 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_a_b_vs_bound_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_b_vs_bound_a.stderr @@ -1,14 +1,16 @@ -error: compilation successful - --> $DIR/hr-subtype.rs:96:1 +error[E0308]: mismatched types + --> $DIR/hr-subtype.rs:39:26 | -LL | / fn main() { -LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful -LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful -LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful -... | -LL | | //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR compilation successful -LL | | } - | |_^ +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a +... +LL | / check! { bound_a_b_vs_bound_a: (for<'a,'b> fn(&'a u32, &'b u32), +LL | | for<'a> fn(&'a u32, &'a u32)) } + | |__________________________________________________________________- in this macro invocation + | + = note: expected type `std::option::Option fn(&'a u32, &'b u32)>` + found type `std::option::Option fn(&'a u32, &'a u32)>` error: aborting due to previous error +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr index 25b74d855bb48..5fcb63e17bf31 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr @@ -1,12 +1,12 @@ error: compilation successful - --> $DIR/hr-subtype.rs:96:1 + --> $DIR/hr-subtype.rs:100:1 | LL | / fn main() { LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful -... | -LL | | //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR compilation successful +LL | | //[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful +LL | | //[free_x_vs_free_x]~^^^^^ ERROR compilation successful LL | | } | |_^ diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr index 25b74d855bb48..5fcb63e17bf31 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr @@ -1,12 +1,12 @@ error: compilation successful - --> $DIR/hr-subtype.rs:96:1 + --> $DIR/hr-subtype.rs:100:1 | LL | / fn main() { LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful -... | -LL | | //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR compilation successful +LL | | //[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful +LL | | //[free_x_vs_free_x]~^^^^^ ERROR compilation successful LL | | } | |_^ diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr index 74b8c89b6e86f..db9892b48a6f7 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/hr-subtype.rs:39:26 | LL | gimme::<$t1>(None::<$t2>); - | ^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a ... LL | / check! { bound_a_vs_free_x: (for<'a> fn(&'a u32), LL | | fn(&'x u32)) } diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_b_vs_bound_co_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_b_vs_bound_co_a.stderr index 25b74d855bb48..e9fb73411bd39 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_b_vs_bound_co_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_b_vs_bound_co_a.stderr @@ -1,14 +1,16 @@ -error: compilation successful - --> $DIR/hr-subtype.rs:96:1 +error[E0308]: mismatched types + --> $DIR/hr-subtype.rs:39:26 | -LL | / fn main() { -LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful -LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful -LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful -... | -LL | | //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR compilation successful -LL | | } - | |_^ +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a +... +LL | / check! { bound_co_a_b_vs_bound_co_a: (for<'a,'b> fn(Co<'a>, Co<'b>), +LL | | for<'a> fn(Co<'a>, Co<'a>)) } + | |______________________________________________________________________- in this macro invocation + | + = note: expected type `std::option::Option fn(Co<'a>, Co<'b>)>` + found type `std::option::Option fn(Co<'a>, Co<'a>)>` error: aborting due to previous error +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_co_b_ret_contra_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_co_b_ret_contra_a.stderr index 25b74d855bb48..d0e80faa68e8b 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_co_b_ret_contra_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_co_b_ret_contra_a.stderr @@ -1,14 +1,16 @@ -error: compilation successful - --> $DIR/hr-subtype.rs:96:1 +error[E0308]: mismatched types + --> $DIR/hr-subtype.rs:39:26 | -LL | / fn main() { -LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful -LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful -LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful -... | -LL | | //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR compilation successful -LL | | } - | |_^ +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a +... +LL | / check! { bound_co_a_co_b_ret_contra_a: (for<'a,'b> fn(Co<'a>, Co<'b>) -> Contra<'a>, +LL | | for<'a> fn(Co<'a>, Co<'a>) -> Contra<'a>) } + | |______________________________________________________________________________________- in this macro invocation + | + = note: expected type `std::option::Option fn(Co<'a>, Co<'b>) -> Contra<'a>>` + found type `std::option::Option fn(Co<'a>, Co<'a>) -> Contra<'a>>` error: aborting due to previous error +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr index 25b74d855bb48..5fcb63e17bf31 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr @@ -1,12 +1,12 @@ error: compilation successful - --> $DIR/hr-subtype.rs:96:1 + --> $DIR/hr-subtype.rs:100:1 | LL | / fn main() { LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful -... | -LL | | //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR compilation successful +LL | | //[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful +LL | | //[free_x_vs_free_x]~^^^^^ ERROR compilation successful LL | | } | |_^ diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_contra_a_contra_b_ret_co_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_contra_a_contra_b_ret_co_a.stderr index 25b74d855bb48..3605ecf4f8667 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_contra_a_contra_b_ret_co_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_contra_a_contra_b_ret_co_a.stderr @@ -1,14 +1,16 @@ -error: compilation successful - --> $DIR/hr-subtype.rs:96:1 +error[E0308]: mismatched types + --> $DIR/hr-subtype.rs:39:26 | -LL | / fn main() { -LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful -LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful -LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful -... | -LL | | //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR compilation successful -LL | | } - | |_^ +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a +... +LL | / check! { bound_contra_a_contra_b_ret_co_a: (for<'a,'b> fn(Contra<'a>, Contra<'b>) -> Co<'a>, +LL | | for<'a> fn(Contra<'a>, Contra<'a>) -> Co<'a>) } + | |______________________________________________________________________________________________- in this macro invocation + | + = note: expected type `std::option::Option fn(Contra<'a>, Contra<'b>) -> Co<'a>>` + found type `std::option::Option fn(Contra<'a>, Contra<'a>) -> Co<'a>>` error: aborting due to previous error +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr index 8168941e2777c..fae6e9b5c89ca 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/hr-subtype.rs:39:26 | LL | gimme::<$t1>(None::<$t2>); - | ^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter 'a ... LL | / check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>), LL | | for<'a> fn(Inv<'a>, Inv<'a>)) } diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_vs_bound_inv_b.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_vs_bound_inv_b.stderr index 25b74d855bb48..5fcb63e17bf31 100644 --- a/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_vs_bound_inv_b.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_vs_bound_inv_b.stderr @@ -1,12 +1,12 @@ error: compilation successful - --> $DIR/hr-subtype.rs:96:1 + --> $DIR/hr-subtype.rs:100:1 | LL | / fn main() { LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful -... | -LL | | //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR compilation successful +LL | | //[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful +LL | | //[free_x_vs_free_x]~^^^^^ ERROR compilation successful LL | | } | |_^ diff --git a/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr b/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr index 25b74d855bb48..5fcb63e17bf31 100644 --- a/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr @@ -1,12 +1,12 @@ error: compilation successful - --> $DIR/hr-subtype.rs:96:1 + --> $DIR/hr-subtype.rs:100:1 | LL | / fn main() { LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful -... | -LL | | //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^^ ERROR compilation successful +LL | | //[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful +LL | | //[free_x_vs_free_x]~^^^^^ ERROR compilation successful LL | | } | |_^ diff --git a/src/test/ui/hr-subtype/hr-subtype.rs b/src/test/ui/hr-subtype/hr-subtype.rs index ad4f39f840528..2f7c1e6fd8c0d 100644 --- a/src/test/ui/hr-subtype/hr-subtype.rs +++ b/src/test/ui/hr-subtype/hr-subtype.rs @@ -42,6 +42,10 @@ macro_rules! check { //[bound_inv_a_b_vs_bound_inv_a]~^^^ ERROR //[bound_a_b_ret_a_vs_bound_a_ret_a]~^^^^ ERROR //[free_inv_x_vs_free_inv_y]~^^^^^ ERROR + //[bound_a_b_vs_bound_a]~^^^^^^ ERROR mismatched types + //[bound_co_a_co_b_ret_contra_a]~^^^^^^^ ERROR + //[bound_contra_a_contra_b_ret_co_a]~^^^^^^^^ ERROR + //[bound_co_a_b_vs_bound_co_a]~^^^^^^^^^ ERROR } } } @@ -99,8 +103,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_co_b_ret_contra_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 } diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.stderr b/src/test/ui/hrtb/hrtb-conflate-regions.stderr index 630dda2694fde..50e1af8f14231 100644 --- a/src/test/ui/hrtb/hrtb-conflate-regions.stderr +++ b/src/test/ui/hrtb/hrtb-conflate-regions.stderr @@ -1,12 +1,20 @@ -error: implementation of `Foo` is not general enough +error[E0277]: the trait bound `for<'a, 'b> SomeStruct: Foo<(&'a isize, &'b isize)>` is not satisfied --> $DIR/hrtb-conflate-regions.rs:28:10 | LL | fn b() { want_foo2::(); } //~ ERROR - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a, 'b> Foo<(&'a isize, &'b isize)>` is not implemented for `SomeStruct` | - = note: Due to a where-clause on `want_foo2`, - = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1` - = note: but `SomeStruct` actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` + = help: the following implementations were found: + > +note: required by `want_foo2` + --> $DIR/hrtb-conflate-regions.rs:8:1 + | +LL | / fn want_foo2() +LL | | where T : for<'a,'b> Foo<(&'a isize, &'b isize)> +LL | | { +LL | | } + | |_^ error: aborting due to previous error +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr b/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr index 6301ed45ac277..8e8892552b701 100644 --- a/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr +++ b/src/test/ui/hrtb/hrtb-exists-forall-fn.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/hrtb-exists-forall-fn.rs:17:34 | LL | let _: for<'b> fn(&'b u32) = foo(); //~ ERROR mismatched types - | ^^^^^ one type is more general than the other + | ^^^^^ expected concrete lifetime, found bound lifetime parameter 'b | = note: expected type `for<'b> fn(&'b u32)` found type `fn(&u32)` diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs index 8801760056ecb..4c1d4d28a09b0 100644 --- a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs +++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs @@ -1,9 +1,7 @@ -// Test a `exists<'a> { forall<'b> { 'a = 'b } }` pattern -- which should not compile! +// Test a case where variance and higher-ranked types interact in surprising ways. // // In particular, we test this pattern in trait solving, where it is not connected // to any part of the source code. -// -// compile-pass trait Trait {} @@ -30,6 +28,9 @@ fn main() { // - `?a: ?b` -- solveable if `?b` is also inferred to `'empty` // - So the subtyping check succeeds, somewhat surprisingly. // This is because we can use `'empty`. + // + // NB. *However*, the reinstated leak-check gives an error here. foo::<()>(); + //~^ ERROR not satisfied } diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr new file mode 100644 index 0000000000000..7f2ca037f0f49 --- /dev/null +++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `(): Trait fn(&'b u32)>` is not satisfied + --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:5 + | +LL | foo::<()>(); + | ^^^^^^^^^ the trait `Trait fn(&'b u32)>` is not implemented for `()` + | + = help: the following implementations were found: + <() as Trait> +note: required by `foo` + --> $DIR/hrtb-exists-forall-trait-contravariant.rs:8:1 + | +LL | / fn foo() +LL | | where +LL | | T: Trait fn(&'b u32)>, +LL | | { +LL | | } + | |_^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.rs b/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.rs index da1bb7cd5fd0b..95b57d6c5bb5e 100644 --- a/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.rs +++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.rs @@ -1,9 +1,7 @@ -// Test a `exists<'a> { forall<'b> { 'a = 'b } }` pattern -- which should not compile! +// Test a case where variance and higher-ranked types interact in surprising ways. // // In particular, we test this pattern in trait solving, where it is not connected // to any part of the source code. -// -// compile-pass trait Trait {} @@ -32,6 +30,9 @@ fn main() { // - `?b: ?a` -- solveable if `?b` is inferred to `'static` // - So the subtyping check succeeds, somewhat surprisingly. // This is because we can use `'static`. + // + // NB. *However*, the reinstated leak-check gives an error here. foo::<()>(); + //~^ ERROR not satisfied } diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.stderr new file mode 100644 index 0000000000000..cd5982e7588a7 --- /dev/null +++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `(): Trait fn(fn(&'b u32))>` is not satisfied + --> $DIR/hrtb-exists-forall-trait-covariant.rs:36:5 + | +LL | foo::<()>(); + | ^^^^^^^^^ the trait `Trait fn(fn(&'b u32))>` is not implemented for `()` + | + = help: the following implementations were found: + <() as Trait> +note: required by `foo` + --> $DIR/hrtb-exists-forall-trait-covariant.rs:8:1 + | +LL | / fn foo() +LL | | where +LL | | T: Trait fn(fn(&'b u32))>, +LL | | { +LL | | } + | |_^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.rs b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.rs index da3f8ad1b8957..827a68beee8bd 100644 --- a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.rs +++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.rs @@ -25,5 +25,5 @@ fn main() { // yielding `fn(&!b u32)`, in a fresh universe U1 // - So we get `?a = !b` but the universe U0 assigned to `?a` cannot name `!b`. - foo::<()>(); //~ ERROR not general enough + foo::<()>(); //~ ERROR not satisfied } diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr index a44837a1e26fd..f56b81759fede 100644 --- a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr +++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr @@ -1,12 +1,21 @@ -error: implementation of `Trait` is not general enough +error[E0277]: the trait bound `(): Trait fn(std::cell::Cell<&'b u32>)>` is not satisfied --> $DIR/hrtb-exists-forall-trait-invariant.rs:28:5 | -LL | foo::<()>(); //~ ERROR not general enough - | ^^^^^^^^^ +LL | foo::<()>(); //~ ERROR not satisfied + | ^^^^^^^^^ the trait `Trait fn(std::cell::Cell<&'b u32>)>` is not implemented for `()` | - = note: Due to a where-clause on `foo`, - = note: `()` must implement `Trait fn(std::cell::Cell<&'b u32>)>` - = note: but `()` actually implements `Trait)>`, for some specific lifetime `'0` + = help: the following implementations were found: + <() as Trait)>> +note: required by `foo` + --> $DIR/hrtb-exists-forall-trait-invariant.rs:10:1 + | +LL | / fn foo() +LL | | where +LL | | T: Trait fn(Cell<&'b u32>)>, +LL | | { +LL | | } + | |_^ error: aborting due to previous error +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr index 0d7b5cbf82348..77c1789852e52 100644 --- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr +++ b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr @@ -1,12 +1,19 @@ -error[E0308]: mismatched types +error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:5 | LL | want_bar_for_any_ccx(b); //~ ERROR - | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B` | - = note: expected type `for<'ccx> Bar<'ccx>` - found type `Bar<'static>` + = help: consider adding a `where for<'ccx> B: Bar<'ccx>` bound +note: required by `want_bar_for_any_ccx` + --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:31:1 + | +LL | / fn want_bar_for_any_ccx(b: &B) +LL | | where B : for<'ccx> Bar<'ccx> +LL | | { +LL | | } + | |_^ error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.rs b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.rs index 3d2d403462d8b..48ebe5017aa62 100644 --- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.rs +++ b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.rs @@ -15,7 +15,7 @@ fn want_foo_for_some_tcx<'x,F>(f: &'x F) where F : Foo<'x> { want_foo_for_some_tcx(f); - want_foo_for_any_tcx(f); //~ ERROR E0308 + want_foo_for_any_tcx(f); //~ ERROR not satisfied } fn want_foo_for_any_tcx(f: &F) @@ -32,7 +32,7 @@ fn want_bar_for_some_ccx<'x,B>(b: &B) want_foo_for_any_tcx(b); want_bar_for_some_ccx(b); - want_bar_for_any_ccx(b); //~ ERROR E0308 + want_bar_for_any_ccx(b); //~ ERROR not satisfied } fn want_bar_for_any_ccx(b: &B) diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr index 31dbeec2a551b..5914cb3eaa494 100644 --- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr +++ b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr @@ -1,21 +1,40 @@ -error[E0308]: mismatched types +error[E0277]: the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied --> $DIR/hrtb-higher-ranker-supertraits.rs:18:5 | -LL | want_foo_for_any_tcx(f); //~ ERROR E0308 - | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other +LL | want_foo_for_any_tcx(f); //~ ERROR not satisfied + | ^^^^^^^^^^^^^^^^^^^^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F` | - = note: expected type `for<'tcx> Foo<'tcx>` - found type `Foo<'x>` + = help: consider adding a `where for<'tcx> F: Foo<'tcx>` bound +note: required by `want_foo_for_any_tcx` + --> $DIR/hrtb-higher-ranker-supertraits.rs:21:1 + | +LL | / fn want_foo_for_any_tcx(f: &F) +LL | | where F : for<'tcx> Foo<'tcx> +LL | | { +LL | | want_foo_for_some_tcx(f); +LL | | want_foo_for_any_tcx(f); +LL | | } + | |_^ -error[E0308]: mismatched types +error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied --> $DIR/hrtb-higher-ranker-supertraits.rs:35:5 | -LL | want_bar_for_any_ccx(b); //~ ERROR E0308 - | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other +LL | want_bar_for_any_ccx(b); //~ ERROR not satisfied + | ^^^^^^^^^^^^^^^^^^^^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B` + | + = help: consider adding a `where for<'ccx> B: Bar<'ccx>` bound +note: required by `want_bar_for_any_ccx` + --> $DIR/hrtb-higher-ranker-supertraits.rs:38:1 | - = note: expected type `for<'ccx> Bar<'ccx>` - found type `Bar<'x>` +LL | / fn want_bar_for_any_ccx(b: &B) +LL | | where B : for<'ccx> Bar<'ccx> +LL | | { +LL | | want_foo_for_some_tcx(b); +... | +LL | | want_bar_for_any_ccx(b); +LL | | } + | |_^ error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/hrtb/hrtb-just-for-static.stderr b/src/test/ui/hrtb/hrtb-just-for-static.stderr index 99c87f13672b1..fe2bc1f222504 100644 --- a/src/test/ui/hrtb/hrtb-just-for-static.stderr +++ b/src/test/ui/hrtb/hrtb-just-for-static.stderr @@ -1,22 +1,37 @@ -error: implementation of `Foo` is not general enough +error[E0277]: the trait bound `for<'a> StaticInt: Foo<&'a isize>` is not satisfied --> $DIR/hrtb-just-for-static.rs:24:5 | LL | want_hrtb::() //~ ERROR - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `StaticInt` | - = note: Due to a where-clause on `want_hrtb`, - = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0` - = note: but `StaticInt` actually implements `Foo<&'1 isize>`, for some specific lifetime `'1` + = help: the following implementations were found: + > +note: required by `want_hrtb` + --> $DIR/hrtb-just-for-static.rs:8:1 + | +LL | / fn want_hrtb() +LL | | where T : for<'a> Foo<&'a isize> +LL | | { +LL | | } + | |_^ -error: implementation of `Foo` is not general enough +error[E0277]: the trait bound `for<'a> &'a u32: Foo<&'a isize>` is not satisfied --> $DIR/hrtb-just-for-static.rs:30:5 | LL | want_hrtb::<&'a u32>() //~ ERROR - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `&'a u32` + | + = help: the following implementations were found: + <&'a u32 as Foo<&'a isize>> +note: required by `want_hrtb` + --> $DIR/hrtb-just-for-static.rs:8:1 | - = note: Due to a where-clause on `want_hrtb`, - = note: `Foo<&'0 isize>` would have to be implemented for the type `&'a u32`, for any lifetime `'0` - = note: but `Foo<&'1 isize>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1` +LL | / fn want_hrtb() +LL | | where T : for<'a> Foo<&'a isize> +LL | | { +LL | | } + | |_^ error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/hrtb/issue-46989.stderr b/src/test/ui/hrtb/issue-46989.stderr new file mode 100644 index 0000000000000..b308291d5c0eb --- /dev/null +++ b/src/test/ui/hrtb/issue-46989.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `for<'r> fn(&'r i32): Foo` is not satisfied + --> $DIR/issue-46989.rs:40:5 + | +LL | assert_foo::(); + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `for<'r> fn(&'r i32)` + | + = help: the following implementations were found: + +note: required by `assert_foo` + --> $DIR/issue-46989.rs:37:1 + | +LL | fn assert_foo() {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/hrtb/issue-58451.rs b/src/test/ui/hrtb/issue-58451.rs index 7ca6914d2ea96..229e505767879 100644 --- a/src/test/ui/hrtb/issue-58451.rs +++ b/src/test/ui/hrtb/issue-58451.rs @@ -9,5 +9,5 @@ where {} fn main() { - f(&[f()]); + f(&[f()]); //~ ERROR this function takes 1 parameter } diff --git a/src/test/ui/hrtb/issue-58451.stderr b/src/test/ui/hrtb/issue-58451.stderr new file mode 100644 index 0000000000000..79c24855dc96c --- /dev/null +++ b/src/test/ui/hrtb/issue-58451.stderr @@ -0,0 +1,16 @@ +error[E0061]: this function takes 1 parameter but 0 parameters were supplied + --> $DIR/issue-58451.rs:12:9 + | +LL | / fn f(i: I) +LL | | where +LL | | I: IntoIterator, +LL | | I::Item: for<'a> Into<&'a ()>, +LL | | {} + | |__- defined here +... +LL | f(&[f()]); //~ ERROR this function takes 1 parameter + | ^^^ expected 1 parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/issues/issue-40000.stderr b/src/test/ui/issues/issue-40000.stderr index d7966cea52bb0..ce0c44c147563 100644 --- a/src/test/ui/issues/issue-40000.stderr +++ b/src/test/ui/issues/issue-40000.stderr @@ -2,10 +2,10 @@ error[E0308]: mismatched types --> $DIR/issue-40000.rs:6:9 | LL | foo(bar); //~ ERROR E0308 - | ^^^ one type is more general than the other + | ^^^ expected concrete lifetime, found bound lifetime parameter | - = note: expected type `dyn for<'r> std::ops::Fn(&'r i32)` - found type `dyn std::ops::Fn(&i32)` + = note: expected type `std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r i32) + 'static)>` + found type `std::boxed::Box` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-57362-1.rs b/src/test/ui/issues/issue-57362-1.rs index fe6b69f00977d..1fa417fe98ab7 100644 --- a/src/test/ui/issues/issue-57362-1.rs +++ b/src/test/ui/issues/issue-57362-1.rs @@ -17,7 +17,7 @@ impl Trait for fn(&T) { fn f() { let a: fn(_) = |_: &u8| {}; - a.f(); //~ ERROR not general enough + a.f(); //~ ERROR no method named `f` } fn main() {} diff --git a/src/test/ui/issues/issue-57362-1.stderr b/src/test/ui/issues/issue-57362-1.stderr index 06946bcf744a7..b21b35849b172 100644 --- a/src/test/ui/issues/issue-57362-1.stderr +++ b/src/test/ui/issues/issue-57362-1.stderr @@ -1,11 +1,14 @@ -error: implementation of `Trait` is not general enough +error[E0599]: no method named `f` found for type `fn(&u8)` in the current scope --> $DIR/issue-57362-1.rs:20:7 | -LL | a.f(); //~ ERROR not general enough +LL | a.f(); //~ ERROR no method named `f` | ^ | - = note: `Trait` would have to be implemented for the type `fn(&'0 u8)`, for some specific lifetime `'0` - = note: but `Trait` is actually implemented for the type `for<'r> fn(&'r u8)` + = note: a is a function, perhaps you wish to call it + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `f`, perhaps you need to implement it: + candidate #1: `Trait` error: aborting due to previous error +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-57362-2.rs b/src/test/ui/issues/issue-57362-2.rs index 436a4a904576d..870d7f28ba953 100644 --- a/src/test/ui/issues/issue-57362-2.rs +++ b/src/test/ui/issues/issue-57362-2.rs @@ -19,7 +19,7 @@ impl<'a> X for fn(&'a ()) { } fn g() { - let x = ::make_g(); //~ ERROR not general enough + let x = ::make_g(); //~ ERROR no function or associated item } fn main() {} diff --git a/src/test/ui/issues/issue-57362-2.stderr b/src/test/ui/issues/issue-57362-2.stderr index 14b7f52bb8799..b8211691f7be6 100644 --- a/src/test/ui/issues/issue-57362-2.stderr +++ b/src/test/ui/issues/issue-57362-2.stderr @@ -1,11 +1,15 @@ -error: implementation of `X` is not general enough - --> $DIR/issue-57362-2.rs:22:13 +error[E0599]: no function or associated item named `make_g` found for type `for<'r> fn(&'r ())` in the current scope + --> $DIR/issue-57362-2.rs:22:25 | -LL | let x = ::make_g(); //~ ERROR not general enough - | ^^^^^^^^^^^^^^^^^^ +LL | let x = ::make_g(); //~ ERROR no function or associated item + | ------------^^^^^^ + | | + | function or associated item not found in `for<'r> fn(&'r ())` | - = note: `X` would have to be implemented for the type `for<'r> fn(&'r ())` - = note: but `X` is actually implemented for the type `fn(&'0 ())`, for some specific lifetime `'0` + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `make_g`, perhaps you need to implement it: + candidate #1: `X` error: aborting due to previous error +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/lub-glb/old-lub-glb-hr.rs b/src/test/ui/lub-glb/old-lub-glb-hr.rs index 324dc86bd92b8..6bf1fd41d77be 100644 --- a/src/test/ui/lub-glb/old-lub-glb-hr.rs +++ b/src/test/ui/lub-glb/old-lub-glb-hr.rs @@ -4,7 +4,8 @@ // longer get an error, because we recognize these two types as // equivalent! // -// compile-pass +// Whoops -- now that we reinstituted the leak-check, we get an error +// again. fn foo( x: fn(&u8, &u8), @@ -12,7 +13,7 @@ fn foo( ) { let z = match 22 { 0 => x, - _ => y, + _ => y, //~ ERROR match arms have incompatible types }; } diff --git a/src/test/ui/lub-glb/old-lub-glb-hr.stderr b/src/test/ui/lub-glb/old-lub-glb-hr.stderr new file mode 100644 index 0000000000000..8f228ea4cad41 --- /dev/null +++ b/src/test/ui/lub-glb/old-lub-glb-hr.stderr @@ -0,0 +1,18 @@ +error[E0308]: match arms have incompatible types + --> $DIR/old-lub-glb-hr.rs:16:14 + | +LL | let z = match 22 { + | _____________- +LL | | 0 => x, + | | - this is found to be of type `for<'r, 's> fn(&'r u8, &'s u8)` +LL | | _ => y, //~ ERROR match arms have incompatible types + | | ^ expected bound lifetime parameter, found concrete lifetime +LL | | }; + | |_____- `match` arms have incompatible types + | + = note: expected type `for<'r, 's> fn(&'r u8, &'s u8)` + found type `for<'a> fn(&'a u8, &'a u8)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/lub-glb/old-lub-glb-object.rs b/src/test/ui/lub-glb/old-lub-glb-object.rs index 9be7a813603d4..3e95a7111e0cd 100644 --- a/src/test/ui/lub-glb/old-lub-glb-object.rs +++ b/src/test/ui/lub-glb/old-lub-glb-object.rs @@ -1,5 +1,9 @@ // Test that we give a note when the old LUB/GLB algorithm would have // succeeded but the new code (which is stricter) gives an error. +// +// compile-pass +// +// TODO -- why does this test pass? trait Foo { } @@ -7,7 +11,7 @@ fn foo( x: &for<'a, 'b> Foo<&'a u8, &'b u8>, y: &for<'a> Foo<&'a u8, &'a u8>, ) { - let z = match 22 { //~ ERROR E0308 + let z = match 22 { 0 => x, _ => y, }; diff --git a/src/test/ui/lub-glb/old-lub-glb-object.stderr b/src/test/ui/lub-glb/old-lub-glb-object.stderr deleted file mode 100644 index 17d3648156b51..0000000000000 --- a/src/test/ui/lub-glb/old-lub-glb-object.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/old-lub-glb-object.rs:10:13 - | -LL | let z = match 22 { //~ ERROR E0308 - | _____________^ -LL | | 0 => x, -LL | | _ => y, -LL | | }; - | |_____^ one type is more general than the other - | - = note: expected type `dyn for<'a, 'b> Foo<&'a u8, &'b u8>` - found type `dyn for<'a> Foo<&'a u8, &'a u8>` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs b/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs index 437150666be0c..521bd3695dfe5 100644 --- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs +++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs @@ -7,6 +7,6 @@ fn main() { fn baz(_: F) {} fn _test<'a>(f: fn(*mut &'a u32)) { - baz(f); //~ ERROR mismatched types - //~| ERROR mismatched types + baz(f); //~ ERROR type mismatch + //~| ERROR type mismatch } diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr index a6628006587c1..5dd6887005e83 100644 --- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr @@ -22,25 +22,34 @@ LL | a.iter().map(|_: (u16, u16)| 45); //~ ERROR type mismatch | | | expected signature of `fn(&(u32, u32)) -> _` -error[E0308]: mismatched types +error[E0631]: type mismatch in function arguments --> $DIR/closure-arg-type-mismatch.rs:10:5 | -LL | baz(f); //~ ERROR mismatched types - | ^^^ one type is more general than the other +LL | baz(f); //~ ERROR type mismatch + | ^^^ + | | + | expected signature of `for<'r> fn(*mut &'r u32) -> _` + | found signature of `fn(*mut &'a u32) -> _` | - = note: expected type `for<'r> std::ops::Fn<(*mut &'r u32,)>` - found type `std::ops::Fn<(*mut &'a u32,)>` +note: required by `baz` + --> $DIR/closure-arg-type-mismatch.rs:8:1 + | +LL | fn baz(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0308]: mismatched types +error[E0271]: type mismatch resolving `for<'r> >::Output == ()` --> $DIR/closure-arg-type-mismatch.rs:10:5 | -LL | baz(f); //~ ERROR mismatched types - | ^^^ one type is more general than the other +LL | baz(f); //~ ERROR type mismatch + | ^^^ expected bound lifetime parameter, found concrete lifetime + | +note: required by `baz` + --> $DIR/closure-arg-type-mismatch.rs:8:1 | - = note: expected type `std::ops::FnOnce<(*mut &u32,)>` - found type `std::ops::FnOnce<(*mut &'a u32,)>` +LL | fn baz(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 5 previous errors -Some errors occurred: E0308, E0631. -For more information about an error, try `rustc --explain E0308`. +Some errors occurred: E0271, E0631. +For more information about an error, try `rustc --explain E0271`. diff --git a/src/test/ui/mismatched_types/closure-mismatch.rs b/src/test/ui/mismatched_types/closure-mismatch.rs index 152a525493732..40a4641fe7196 100644 --- a/src/test/ui/mismatched_types/closure-mismatch.rs +++ b/src/test/ui/mismatched_types/closure-mismatch.rs @@ -5,5 +5,6 @@ impl Foo for T {} fn baz(_: T) {} fn main() { - baz(|_| ()); //~ ERROR E0308 + baz(|_| ()); //~ ERROR type mismatch + //~^ ERROR type mismatch } diff --git a/src/test/ui/mismatched_types/closure-mismatch.stderr b/src/test/ui/mismatched_types/closure-mismatch.stderr index 0d87bc228755f..e55047e96c297 100644 --- a/src/test/ui/mismatched_types/closure-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-mismatch.stderr @@ -1,12 +1,32 @@ -error[E0308]: mismatched types +error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/closure-mismatch.rs:8:9: 8:15] as std::ops::FnOnce<(&'r (),)>>::Output == ()` --> $DIR/closure-mismatch.rs:8:5 | -LL | baz(|_| ()); //~ ERROR E0308 - | ^^^ one type is more general than the other +LL | baz(|_| ()); //~ ERROR type mismatch + | ^^^ expected bound lifetime parameter, found concrete lifetime | - = note: expected type `for<'r> std::ops::Fn<(&'r (),)>` - found type `std::ops::Fn<(&(),)>` + = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:8:9: 8:15]` +note: required by `baz` + --> $DIR/closure-mismatch.rs:5:1 + | +LL | fn baz(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^ + +error[E0631]: type mismatch in closure arguments + --> $DIR/closure-mismatch.rs:8:5 + | +LL | baz(|_| ()); //~ ERROR type mismatch + | ^^^ ------ found signature of `fn(_) -> _` + | | + | expected signature of `for<'r> fn(&'r ()) -> _` + | + = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:8:9: 8:15]` +note: required by `baz` + --> $DIR/closure-mismatch.rs:5:1 + | +LL | fn baz(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors occurred: E0271, E0631. +For more information about an error, try `rustc --explain E0271`. diff --git a/src/test/ui/mismatched_types/issue-36053-2.rs b/src/test/ui/mismatched_types/issue-36053-2.rs index 9035e3380b0c5..9edfebcd49471 100644 --- a/src/test/ui/mismatched_types/issue-36053-2.rs +++ b/src/test/ui/mismatched_types/issue-36053-2.rs @@ -7,4 +7,5 @@ fn main() { once::<&str>("str").fuse().filter(|a: &str| true).count(); //~^ ERROR no method named `count` //~| ERROR type mismatch in closure arguments + //~| ERROR type mismatch in closure arguments } diff --git a/src/test/ui/mismatched_types/issue-36053-2.stderr b/src/test/ui/mismatched_types/issue-36053-2.stderr index e53e8c520e0c4..c5c67e6bd9bd9 100644 --- a/src/test/ui/mismatched_types/issue-36053-2.stderr +++ b/src/test/ui/mismatched_types/issue-36053-2.stderr @@ -16,7 +16,15 @@ LL | once::<&str>("str").fuse().filter(|a: &str| true).count(); | | | expected signature of `for<'r> fn(&'r &str) -> _` -error: aborting due to 2 previous errors +error[E0631]: type mismatch in closure arguments + --> $DIR/issue-36053-2.rs:7:32 + | +LL | once::<&str>("str").fuse().filter(|a: &str| true).count(); + | ^^^^^^ -------------- found signature of `for<'r> fn(&'r str) -> _` + | | + | expected signature of `fn(&&str) -> _` + +error: aborting due to 3 previous errors Some errors occurred: E0599, E0631. For more information about an error, try `rustc --explain E0599`. diff --git a/src/test/ui/regions-fn-subtyping-return-static-fail.rs b/src/test/ui/regions-fn-subtyping-return-static-fail.rs index 242119cc201da..2dd0c9796e258 100644 --- a/src/test/ui/regions-fn-subtyping-return-static-fail.rs +++ b/src/test/ui/regions-fn-subtyping-return-static-fail.rs @@ -37,7 +37,7 @@ fn baz(x: &S) -> &S { fn supply_F() { want_F(foo); - want_F(bar); + want_F(bar); //~ ERROR mismatched types want_F(baz); } @@ -45,7 +45,7 @@ fn supply_F() { fn supply_G() { want_G(foo); want_G(bar); - want_G(baz); //~ ERROR + want_G(baz); //~ ERROR mismatched types } pub fn main() { diff --git a/src/test/ui/regions-fn-subtyping-return-static-fail.stderr b/src/test/ui/regions-fn-subtyping-return-static-fail.stderr index a9234e43191ea..66e6a615b33bc 100644 --- a/src/test/ui/regions-fn-subtyping-return-static-fail.stderr +++ b/src/test/ui/regions-fn-subtyping-return-static-fail.stderr @@ -1,12 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/regions-fn-subtyping-return-static-fail.rs:40:12 + | +LL | want_F(bar); //~ ERROR mismatched types + | ^^^ expected concrete lifetime, found bound lifetime parameter 'cx + | + = note: expected type `for<'cx> fn(&'cx S) -> &'cx S` + found type `for<'a> fn(&'a S) -> &S {bar::<'_>}` + error[E0308]: mismatched types --> $DIR/regions-fn-subtyping-return-static-fail.rs:48:12 | -LL | want_G(baz); //~ ERROR - | ^^^ one type is more general than the other +LL | want_G(baz); //~ ERROR mismatched types + | ^^^ expected concrete lifetime, found bound lifetime parameter 'cx | = note: expected type `for<'cx> fn(&'cx S) -> &'static S` - found type `for<'r> fn(&'r S) -> &'r S` + found type `for<'r> fn(&'r S) -> &'r S {baz}` -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr index 47e1d0efdc77b..5c8b3d3ba6922 100644 --- a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr +++ b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr @@ -20,10 +20,10 @@ error[E0308]: mismatched types --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:43 | LL | let _: fn(&mut &isize, &mut &isize) = a; //~ ERROR mismatched types - | ^ one type is more general than the other + | ^ expected concrete lifetime, found bound lifetime parameter | = note: expected type `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)` - found type `for<'r, 's> fn(&'r mut &isize, &'s mut &isize)` + found type `for<'r, 's> fn(&'r mut &isize, &'s mut &isize) {a::<'_, '_>}` error: aborting due to 3 previous errors diff --git a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr index 1e7b99053f77f..f36885f7aeb99 100644 --- a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr +++ b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr @@ -31,10 +31,10 @@ error[E0308]: mismatched types --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:56 | LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; //~ ERROR E0308 - | ^ one type is more general than the other + | ^ expected concrete lifetime, found bound lifetime parameter | = note: expected type `for<'r, 's, 't0, 't1, 't2, 't3> fn(&'r mut &'s isize, &'t0 mut &'t1 isize, &'t2 mut &'t3 isize)` - found type `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize)` + found type `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize) {a::<'_, '_, '_>}` error: aborting due to 4 previous errors diff --git a/src/test/ui/regions/regions-fn-subtyping-return-static.rs b/src/test/ui/regions/regions-fn-subtyping-return-static.rs index 9010770f1dc82..fa2cc37d05b2b 100644 --- a/src/test/ui/regions/regions-fn-subtyping-return-static.rs +++ b/src/test/ui/regions/regions-fn-subtyping-return-static.rs @@ -5,8 +5,6 @@ // *ANY* lifetime and returns a reference with the 'static lifetime. // This can safely be considered to be an instance of `F` because all // lifetimes are sublifetimes of 'static. -// -// compile-pass #![allow(dead_code)] #![allow(unused_variables)] @@ -40,7 +38,7 @@ fn baz(x: &S) -> &S { fn supply_F() { want_F(foo); - want_F(bar); + want_F(bar); //~ ERROR mismatched types want_F(baz); } diff --git a/src/test/ui/regions/regions-fn-subtyping-return-static.stderr b/src/test/ui/regions/regions-fn-subtyping-return-static.stderr new file mode 100644 index 0000000000000..42a5a7c806e08 --- /dev/null +++ b/src/test/ui/regions/regions-fn-subtyping-return-static.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/regions-fn-subtyping-return-static.rs:41:12 + | +LL | want_F(bar); //~ ERROR mismatched types + | ^^^ expected concrete lifetime, found bound lifetime parameter 'cx + | + = note: expected type `for<'cx> fn(&'cx S) -> &'cx S` + found type `for<'a> fn(&'a S) -> &S {bar::<'_>}` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr b/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr index a43ee7ec3ace0..99d85e9e4b5a6 100644 --- a/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr +++ b/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr @@ -20,10 +20,10 @@ error[E0308]: mismatched types --> $DIR/regions-lifetime-bounds-on-fns.rs:20:43 | LL | let _: fn(&mut &isize, &mut &isize) = a; //~ ERROR E0308 - | ^ one type is more general than the other + | ^ expected concrete lifetime, found bound lifetime parameter | = note: expected type `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)` - found type `for<'r, 's> fn(&'r mut &isize, &'s mut &isize)` + found type `for<'r, 's> fn(&'r mut &isize, &'s mut &isize) {a::<'_, '_>}` error: aborting due to 3 previous errors diff --git a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.rs b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.rs index 12626fe69cb14..a6e26614a6a50 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.rs +++ b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.rs @@ -11,11 +11,13 @@ fn call_it_onceisize>(_: F, _: isize) -> isize { 0 } fn a() { let x = call_it(&square, 22); //~^ ERROR E0277 + //~| ERROR expected } fn b() { let y = call_it_mut(&mut square, 22); //~^ ERROR E0277 + //~| ERROR expected } fn c() { diff --git a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr index 29f276711c745..ca0298283661f 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr @@ -11,8 +11,21 @@ note: required by `call_it` LL | fn call_itisize>(_: &F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` + --> $DIR/unboxed-closures-unsafe-extern-fn.rs:12:13 + | +LL | let x = call_it(&square, 22); + | ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` + | + = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}` +note: required by `call_it` + --> $DIR/unboxed-closures-unsafe-extern-fn.rs:7:1 + | +LL | fn call_itisize>(_: &F, _: isize) -> isize { 0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` - --> $DIR/unboxed-closures-unsafe-extern-fn.rs:17:13 + --> $DIR/unboxed-closures-unsafe-extern-fn.rs:18:13 | LL | let y = call_it_mut(&mut square, 22); | ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` @@ -25,18 +38,31 @@ LL | fn call_it_mutisize>(_: &mut F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` - --> $DIR/unboxed-closures-unsafe-extern-fn.rs:22:13 + --> $DIR/unboxed-closures-unsafe-extern-fn.rs:18:13 + | +LL | let y = call_it_mut(&mut square, 22); + | ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` + | + = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}` +note: required by `call_it_mut` + --> $DIR/unboxed-closures-unsafe-extern-fn.rs:8:1 + | +LL | fn call_it_mutisize>(_: &mut F, _: isize) -> isize { 0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` + --> $DIR/unboxed-closures-unsafe-extern-fn.rs:24:13 | LL | let z = call_it_once(square, 22); | ^^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` | - = help: the trait `for<'r> std::ops::FnOnce<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}` + = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}` note: required by `call_it_once` --> $DIR/unboxed-closures-unsafe-extern-fn.rs:9:1 | LL | fn call_it_onceisize>(_: F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.rs b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.rs index 7c3152c87c461..dd3b1afc39f31 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.rs +++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.rs @@ -11,11 +11,13 @@ fn call_it_onceisize>(_: F, _: isize) -> isize { 0 } fn a() { let x = call_it(&square, 22); //~^ ERROR E0277 + //~| ERROR expected } fn b() { let y = call_it_mut(&mut square, 22); //~^ ERROR E0277 + //~| ERROR expected } fn c() { diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr index e382457860579..0abc58aeebfe5 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr @@ -11,8 +11,21 @@ note: required by `call_it` LL | fn call_itisize>(_: &F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` + --> $DIR/unboxed-closures-wrong-abi.rs:12:13 + | +LL | let x = call_it(&square, 22); + | ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` + | + = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}` +note: required by `call_it` + --> $DIR/unboxed-closures-wrong-abi.rs:7:1 + | +LL | fn call_itisize>(_: &F, _: isize) -> isize { 0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` - --> $DIR/unboxed-closures-wrong-abi.rs:17:13 + --> $DIR/unboxed-closures-wrong-abi.rs:18:13 | LL | let y = call_it_mut(&mut square, 22); | ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` @@ -25,18 +38,31 @@ LL | fn call_it_mutisize>(_: &mut F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` - --> $DIR/unboxed-closures-wrong-abi.rs:22:13 + --> $DIR/unboxed-closures-wrong-abi.rs:18:13 + | +LL | let y = call_it_mut(&mut square, 22); + | ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` + | + = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}` +note: required by `call_it_mut` + --> $DIR/unboxed-closures-wrong-abi.rs:8:1 + | +LL | fn call_it_mutisize>(_: &mut F, _: isize) -> isize { 0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` + --> $DIR/unboxed-closures-wrong-abi.rs:24:13 | LL | let z = call_it_once(square, 22); | ^^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` | - = help: the trait `for<'r> std::ops::FnOnce<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}` + = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}` note: required by `call_it_once` --> $DIR/unboxed-closures-wrong-abi.rs:9:1 | LL | fn call_it_onceisize>(_: F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.rs b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.rs index 61d46869cbbf2..c689d79266187 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.rs +++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.rs @@ -12,11 +12,13 @@ fn call_it_onceisize>(_: F, _: isize) -> isize { 0 } fn a() { let x = call_it(&square, 22); //~^ ERROR E0277 + //~| ERROR expected } fn b() { let y = call_it_mut(&mut square, 22); //~^ ERROR E0277 + //~| ERROR expected } fn c() { diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr index da511f091bf6a..19b87ad171a51 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr @@ -11,8 +11,21 @@ note: required by `call_it` LL | fn call_itisize>(_: &F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` + --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:13:13 + | +LL | let x = call_it(&square, 22); + | ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` + | + = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}` +note: required by `call_it` + --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:8:1 + | +LL | fn call_itisize>(_: &F, _: isize) -> isize { 0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` - --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:18:13 + --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:19:13 | LL | let y = call_it_mut(&mut square, 22); | ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` @@ -25,18 +38,31 @@ LL | fn call_it_mutisize>(_: &mut F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` - --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:23:13 + --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:19:13 + | +LL | let y = call_it_mut(&mut square, 22); + | ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` + | + = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}` +note: required by `call_it_mut` + --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:9:1 + | +LL | fn call_it_mutisize>(_: &mut F, _: isize) -> isize { 0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` + --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:25:13 | LL | let z = call_it_once(square, 22); | ^^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` | - = help: the trait `for<'r> std::ops::FnOnce<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}` + = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}` note: required by `call_it_once` --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:10:1 | LL | fn call_it_onceisize>(_: F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/where-clauses/where-for-self-2.rs b/src/test/ui/where-clauses/where-for-self-2.rs index 0ce38e69f6b0f..31174fd4cf163 100644 --- a/src/test/ui/where-clauses/where-for-self-2.rs +++ b/src/test/ui/where-clauses/where-for-self-2.rs @@ -18,5 +18,5 @@ fn foo(x: &T) {} fn main() { - foo(&X); //~ ERROR implementation of `Bar` is not general enough + foo(&X); //~ ERROR trait bound } diff --git a/src/test/ui/where-clauses/where-for-self-2.stderr b/src/test/ui/where-clauses/where-for-self-2.stderr index 342cabfd6bf0a..bbcb61a856d8d 100644 --- a/src/test/ui/where-clauses/where-for-self-2.stderr +++ b/src/test/ui/where-clauses/where-for-self-2.stderr @@ -1,12 +1,19 @@ -error: implementation of `Bar` is not general enough +error[E0277]: the trait bound `for<'a> &'a _: Bar` is not satisfied --> $DIR/where-for-self-2.rs:21:5 | -LL | foo(&X); //~ ERROR implementation of `Bar` is not general enough - | ^^^ +LL | foo(&X); //~ ERROR trait bound + | ^^^ the trait `for<'a> Bar` is not implemented for `&'a _` | - = note: Due to a where-clause on `foo`, - = note: `Bar` would have to be implemented for the type `&'0 u32`, for any lifetime `'0` - = note: but `Bar` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1` + = help: the following implementations were found: + <&'static u32 as Bar> +note: required by `foo` + --> $DIR/where-for-self-2.rs:16:1 + | +LL | / fn foo(x: &T) +LL | | where for<'a> &'a T: Bar +LL | | {} + | |__^ error: aborting due to previous error +For more information about this error, try `rustc --explain E0277`. From 63c4a1c73a1261d4bea77f6fdbec716c47e27a2c Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 20 Feb 2019 12:55:11 -0500 Subject: [PATCH 11/12] WIP infer/mod.rs : pacify mercilous tidy --- src/librustc/infer/mod.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 508c1ff7eea3d..ac2ebece442c8 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -964,8 +964,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.commit_if_ok(|snapshot| { let (ty::OutlivesPredicate(r_a, r_b), placeholder_map) = self.replace_bound_vars_with_placeholders(predicate); - let origin = - SubregionOrigin::from_obligation_cause(cause, || RelateRegionParamBound(cause.span)); + let origin = SubregionOrigin::from_obligation_cause( + cause, + || RelateRegionParamBound(cause.span), + ); self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b` self.leak_check(false, &placeholder_map, snapshot)?; Ok(()) From f156ac2695fb9cd3e5d995f467b11640cdac21e7 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 20 Feb 2019 12:55:30 -0500 Subject: [PATCH 12/12] WIP remove TODO for old-lub-glb-object so that tests pass Still don't know quite what is going on here. --- src/test/ui/lub-glb/old-lub-glb-object.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/ui/lub-glb/old-lub-glb-object.rs b/src/test/ui/lub-glb/old-lub-glb-object.rs index 3e95a7111e0cd..18734c816c910 100644 --- a/src/test/ui/lub-glb/old-lub-glb-object.rs +++ b/src/test/ui/lub-glb/old-lub-glb-object.rs @@ -2,8 +2,6 @@ // succeeded but the new code (which is stricter) gives an error. // // compile-pass -// -// TODO -- why does this test pass? trait Foo { }