diff options
| author | Matthew Jasper <mjjasper1@gmail.com> | 2021-02-09 22:59:32 +0000 |
|---|---|---|
| committer | Matthew Jasper <mjjasper1@gmail.com> | 2021-02-09 22:59:32 +0000 |
| commit | 94c11dfe78c9c2e81ababe51b04231db4c90d07f (patch) | |
| tree | 40c18db2ffd3f930109e7219e5965730736cf5cf | |
| parent | daab6db1a02b680a71976fcbeed577ff102b31e4 (diff) | |
| download | rust-94c11dfe78c9c2e81ababe51b04231db4c90d07f.tar.gz rust-94c11dfe78c9c2e81ababe51b04231db4c90d07f.zip | |
Report "nice" placeholder errors more often
If we have a cause containing `ValuePairs::PolyTraitRefs` but neither TraitRef has any escaping bound regions then we report the same error as for `ValuePairs::TraitRefs`.
19 files changed, 181 insertions, 263 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index 09be0b07670..285666b7acb 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -30,157 +30,153 @@ impl NiceRegionError<'me, 'tcx> { Some(RegionResolutionError::SubSupConflict( vid, _, - SubregionOrigin::Subtype(box TypeTrace { - cause, - values: ValuePairs::TraitRefs(ExpectedFound { expected, found }), - }), + SubregionOrigin::Subtype(box TypeTrace { cause, values }), sub_placeholder @ ty::RePlaceholder(_), _, sup_placeholder @ ty::RePlaceholder(_), - )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( + )) => self.try_report_trait_placeholder_mismatch( Some(self.tcx().mk_region(ty::ReVar(*vid))), cause, Some(sub_placeholder), Some(sup_placeholder), - expected.def_id, - expected.substs, - found.substs, - )), + values, + ), Some(RegionResolutionError::SubSupConflict( vid, _, - SubregionOrigin::Subtype(box TypeTrace { - cause, - values: ValuePairs::TraitRefs(ExpectedFound { expected, found }), - }), + SubregionOrigin::Subtype(box TypeTrace { cause, values }), sub_placeholder @ ty::RePlaceholder(_), _, _, - )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( + )) => self.try_report_trait_placeholder_mismatch( Some(self.tcx().mk_region(ty::ReVar(*vid))), cause, Some(sub_placeholder), None, - expected.def_id, - expected.substs, - found.substs, - )), + values, + ), Some(RegionResolutionError::SubSupConflict( vid, _, - SubregionOrigin::Subtype(box TypeTrace { - cause, - values: ValuePairs::TraitRefs(ExpectedFound { expected, found }), - }), + SubregionOrigin::Subtype(box TypeTrace { cause, values }), _, _, sup_placeholder @ ty::RePlaceholder(_), - )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( + )) => self.try_report_trait_placeholder_mismatch( Some(self.tcx().mk_region(ty::ReVar(*vid))), cause, None, Some(*sup_placeholder), - expected.def_id, - expected.substs, - found.substs, - )), + values, + ), Some(RegionResolutionError::SubSupConflict( vid, _, _, _, - SubregionOrigin::Subtype(box TypeTrace { - cause, - values: ValuePairs::TraitRefs(ExpectedFound { expected, found }), - }), + SubregionOrigin::Subtype(box TypeTrace { cause, values }), sup_placeholder @ ty::RePlaceholder(_), - )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( + )) => self.try_report_trait_placeholder_mismatch( Some(self.tcx().mk_region(ty::ReVar(*vid))), cause, None, Some(*sup_placeholder), - expected.def_id, - expected.substs, - found.substs, - )), + values, + ), Some(RegionResolutionError::UpperBoundUniverseConflict( vid, _, _, - SubregionOrigin::Subtype(box TypeTrace { - cause, - values: ValuePairs::TraitRefs(ExpectedFound { expected, found }), - }), + SubregionOrigin::Subtype(box TypeTrace { cause, values }), sup_placeholder @ ty::RePlaceholder(_), - )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( + )) => self.try_report_trait_placeholder_mismatch( Some(self.tcx().mk_region(ty::ReVar(*vid))), cause, None, Some(*sup_placeholder), - expected.def_id, - expected.substs, - found.substs, - )), + values, + ), Some(RegionResolutionError::ConcreteFailure( - SubregionOrigin::Subtype(box TypeTrace { - cause, - values: ValuePairs::TraitRefs(ExpectedFound { expected, found }), - }), + SubregionOrigin::Subtype(box TypeTrace { cause, values }), sub_region @ ty::RePlaceholder(_), sup_region @ ty::RePlaceholder(_), - )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( + )) => self.try_report_trait_placeholder_mismatch( None, cause, Some(*sub_region), Some(*sup_region), - expected.def_id, - expected.substs, - found.substs, - )), + values, + ), Some(RegionResolutionError::ConcreteFailure( - SubregionOrigin::Subtype(box TypeTrace { - cause, - values: ValuePairs::TraitRefs(ExpectedFound { expected, found }), - }), + SubregionOrigin::Subtype(box TypeTrace { cause, values }), sub_region @ ty::RePlaceholder(_), sup_region, - )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( + )) => self.try_report_trait_placeholder_mismatch( Some(sup_region), cause, Some(*sub_region), None, - expected.def_id, - expected.substs, - found.substs, - )), + values, + ), Some(RegionResolutionError::ConcreteFailure( - SubregionOrigin::Subtype(box TypeTrace { - cause, - values: ValuePairs::TraitRefs(ExpectedFound { expected, found }), - }), + SubregionOrigin::Subtype(box TypeTrace { cause, values }), sub_region, sup_region @ ty::RePlaceholder(_), - )) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( + )) => self.try_report_trait_placeholder_mismatch( Some(sub_region), cause, None, Some(*sup_region), - expected.def_id, - expected.substs, - found.substs, - )), + values, + ), _ => None, } } + fn try_report_trait_placeholder_mismatch( + &self, + vid: Option<ty::Region<'tcx>>, + cause: &ObligationCause<'tcx>, + sub_placeholder: Option<ty::Region<'tcx>>, + sup_placeholder: Option<ty::Region<'tcx>>, + value_pairs: &ValuePairs<'tcx>, + ) -> Option<DiagnosticBuilder<'tcx>> { + let (expected_substs, found_substs, trait_def_id) = match value_pairs { + ValuePairs::TraitRefs(ExpectedFound { expected, found }) + if expected.def_id == found.def_id => + { + (expected.substs, found.substs, expected.def_id) + } + ValuePairs::PolyTraitRefs(ExpectedFound { expected, found }) + if expected.def_id() == found.def_id() => + { + // It's possible that the placeholders come from a binder + // outside of this value pair. Use `no_bound_vars` as a + // simple heuristic for that. + (expected.no_bound_vars()?.substs, found.no_bound_vars()?.substs, expected.def_id()) + } + _ => return None, + }; + + Some(self.report_trait_placeholder_mismatch( + vid, + cause, + sub_placeholder, + sup_placeholder, + trait_def_id, + expected_substs, + found_substs, + )) + } + // error[E0308]: implementation of `Foo` does not apply to enough lifetimes // --> /home/nmatsakis/tmp/foo.rs:12:5 // | @@ -191,7 +187,7 @@ impl NiceRegionError<'me, 'tcx> { // = note: `T` must implement `...` for any two lifetimes `'1` and `'2`. // = note: However, the type `T` only implements `...` for some specific lifetime `'2`. #[instrument(level = "debug", skip(self))] - fn try_report_placeholders_trait( + fn report_trait_placeholder_mismatch( &self, vid: Option<ty::Region<'tcx>>, cause: &ObligationCause<'tcx>, diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr index edce0e6702e..c3dd7949575 100644 --- a/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr +++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr @@ -1,11 +1,11 @@ warning: function cannot return without recursing - --> $DIR/hrtb-perfect-forwarding.rs:22:1 + --> $DIR/hrtb-perfect-forwarding.rs:16:1 | -LL | / fn no_hrtb<'b,T>(mut t: T) -LL | | where T : Bar<&'b isize> +LL | / fn no_hrtb<'b, T>(mut t: T) +LL | | where +LL | | T: Bar<&'b isize>, LL | | { -LL | | // OK -- `T : Bar<&'b isize>`, and thus the impl above ensures that -LL | | // `&mut T : Bar<&'b isize>`. +... | LL | | no_hrtb(&mut t); | | --------------- recursive call site LL | | } @@ -15,12 +15,12 @@ LL | | } = help: a `loop` may express intention better if this is on purpose warning: function cannot return without recursing - --> $DIR/hrtb-perfect-forwarding.rs:30:1 + --> $DIR/hrtb-perfect-forwarding.rs:25:1 | LL | / fn bar_hrtb<T>(mut t: T) -LL | | where T : for<'b> Bar<&'b isize> +LL | | where +LL | | T: for<'b> Bar<&'b isize>, LL | | { -LL | | // OK -- `T : for<'b> Bar<&'b isize>`, and thus the impl above ... | LL | | bar_hrtb(&mut t); | | ---------------- recursive call site @@ -30,25 +30,26 @@ LL | | } = help: a `loop` may express intention better if this is on purpose warning: function cannot return without recursing - --> $DIR/hrtb-perfect-forwarding.rs:39:1 + --> $DIR/hrtb-perfect-forwarding.rs:35:1 | -LL | / fn foo_hrtb_bar_not<'b,T>(mut t: T) -LL | | where T : for<'a> Foo<&'a isize> + Bar<&'b isize> +LL | / fn foo_hrtb_bar_not<'b, T>(mut t: T) +LL | | where +LL | | T: for<'a> Foo<&'a isize> + Bar<&'b isize>, LL | | { -LL | | // Not OK -- The forwarding impl for `Foo` requires that `Bar` also ... | LL | | foo_hrtb_bar_not(&mut t); | | ------------------------ recursive call site LL | | +LL | | LL | | } | |_^ cannot return without recursing | = help: a `loop` may express intention better if this is on purpose error: lifetime may not live long enough - --> $DIR/hrtb-perfect-forwarding.rs:46:5 + --> $DIR/hrtb-perfect-forwarding.rs:43:5 | -LL | fn foo_hrtb_bar_not<'b,T>(mut t: T) +LL | fn foo_hrtb_bar_not<'b, T>(mut t: T) | -- lifetime `'b` defined here ... LL | foo_hrtb_bar_not(&mut t); @@ -57,18 +58,19 @@ LL | foo_hrtb_bar_not(&mut t); = help: consider replacing `'b` with `'static` error: higher-ranked subtype error - --> $DIR/hrtb-perfect-forwarding.rs:46:5 + --> $DIR/hrtb-perfect-forwarding.rs:43:5 | LL | foo_hrtb_bar_not(&mut t); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: function cannot return without recursing - --> $DIR/hrtb-perfect-forwarding.rs:50:1 + --> $DIR/hrtb-perfect-forwarding.rs:48:1 | LL | / fn foo_hrtb_bar_hrtb<T>(mut t: T) -LL | | where T : for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize> +LL | | where +LL | | T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>, LL | | { -LL | | // OK -- now we have `T : for<'b> Bar&'b isize>`. +LL | | // OK -- now we have `T : for<'b> Bar<&'b isize>`. LL | | foo_hrtb_bar_hrtb(&mut t); | | ------------------------- recursive call site LL | | } diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.rs b/src/test/ui/hrtb/hrtb-perfect-forwarding.rs index 0303a764c12..441a788359e 100644 --- a/src/test/ui/hrtb/hrtb-perfect-forwarding.rs +++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.rs @@ -2,25 +2,20 @@ // is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730. trait Foo<X> { - fn foo(&mut self, x: X) { } + fn foo(&mut self, x: X) {} } trait Bar<X> { - fn bar(&mut self, x: X) { } + fn bar(&mut self, x: X) {} } -impl<'a,X,F> Foo<X> for &'a mut F - where F : Foo<X> + Bar<X> -{ -} +impl<'a, X, F> Foo<X> for &'a mut F where F: Foo<X> + Bar<X> {} -impl<'a,X,F> Bar<X> for &'a mut F - where F : Bar<X> -{ -} +impl<'a, X, F> Bar<X> for &'a mut F where F: Bar<X> {} -fn no_hrtb<'b,T>(mut t: T) - where T : Bar<&'b isize> +fn no_hrtb<'b, T>(mut t: T) +where + T: Bar<&'b isize>, { // OK -- `T : Bar<&'b isize>`, and thus the impl above ensures that // `&mut T : Bar<&'b isize>`. @@ -28,7 +23,8 @@ fn no_hrtb<'b,T>(mut t: T) } fn bar_hrtb<T>(mut t: T) - where T : for<'b> Bar<&'b isize> +where + T: for<'b> Bar<&'b isize>, { // OK -- `T : for<'b> Bar<&'b isize>`, and thus the impl above // ensures that `&mut T : for<'b> Bar<&'b isize>`. This is an @@ -36,22 +32,25 @@ fn bar_hrtb<T>(mut t: T) bar_hrtb(&mut t); } -fn foo_hrtb_bar_not<'b,T>(mut t: T) - where T : for<'a> Foo<&'a isize> + Bar<&'b isize> +fn foo_hrtb_bar_not<'b, T>(mut t: T) +where + T: for<'a> Foo<&'a isize> + Bar<&'b isize>, { // Not OK -- The forwarding impl for `Foo` requires that `Bar` also // 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 mismatched types - //~| ERROR mismatched types + foo_hrtb_bar_not(&mut t); + //~^ ERROR implementation of `Bar` is not general enough + //~| ERROR implementation of `Bar` is not general enough } fn foo_hrtb_bar_hrtb<T>(mut t: T) - where T : for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize> +where + T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>, { - // OK -- now we have `T : for<'b> Bar&'b isize>`. + // OK -- now we have `T : for<'b> Bar<&'b isize>`. foo_hrtb_bar_hrtb(&mut t); } -fn main() { } +fn main() {} diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr index ed810d443be..e265f53cd2a 100644 --- a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr +++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr @@ -1,41 +1,20 @@ -error[E0308]: mismatched types - --> $DIR/hrtb-perfect-forwarding.rs:46:5 +error: implementation of `Bar` is not general enough + --> $DIR/hrtb-perfect-forwarding.rs:43:5 | LL | foo_hrtb_bar_not(&mut t); - | ^^^^^^^^^^^^^^^^ lifetime mismatch + | ^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough | - = note: expected type `Bar<&'a isize>` - found type `Bar<&'b isize>` -note: the required lifetime does not necessarily outlive the lifetime `'b` as defined on the function body at 39:21 - --> $DIR/hrtb-perfect-forwarding.rs:39:21 - | -LL | fn foo_hrtb_bar_not<'b,T>(mut t: T) - | ^^ -note: the lifetime requirement is introduced here - --> $DIR/hrtb-perfect-forwarding.rs:40:15 - | -LL | where T : for<'a> Foo<&'a isize> + Bar<&'b isize> - | ^^^^^^^^^^^^^^^^^^^^^^ + = note: `T` must implement `Bar<&'0 isize>`, for any lifetime `'0`... + = note: ...but it actually implements `Bar<&'1 isize>`, for some specific lifetime `'1` -error[E0308]: mismatched types - --> $DIR/hrtb-perfect-forwarding.rs:46:5 +error: implementation of `Bar` is not general enough + --> $DIR/hrtb-perfect-forwarding.rs:43:5 | LL | foo_hrtb_bar_not(&mut t); - | ^^^^^^^^^^^^^^^^ lifetime mismatch - | - = note: expected type `Bar<&'a isize>` - found type `Bar<&'b isize>` -note: the lifetime `'b` as defined on the function body at 39:21 doesn't meet the lifetime requirements - --> $DIR/hrtb-perfect-forwarding.rs:39:21 - | -LL | fn foo_hrtb_bar_not<'b,T>(mut t: T) - | ^^ -note: the lifetime requirement is introduced here - --> $DIR/hrtb-perfect-forwarding.rs:40:15 + | ^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough | -LL | where T : for<'a> Foo<&'a isize> + Bar<&'b isize> - | ^^^^^^^^^^^^^^^^^^^^^^ + = note: `T` must implement `Bar<&'0 isize>`, for any lifetime `'0`... + = note: ...but it actually implements `Bar<&'1 isize>`, for some specific lifetime `'1` error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issues/issue-57843.nll.stderr b/src/test/ui/issues/issue-57843.nll.stderr index 70310780b43..70d16cc9a1d 100644 --- a/src/test/ui/issues/issue-57843.nll.stderr +++ b/src/test/ui/issues/issue-57843.nll.stderr @@ -1,5 +1,5 @@ error: higher-ranked subtype error - --> $DIR/issue-57843.rs:23:9 + --> $DIR/issue-57843.rs:25:9 | LL | Foo(Box::new(|_| ())); | ^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-57843.rs b/src/test/ui/issues/issue-57843.rs index 46608255266..11629690ecc 100644 --- a/src/test/ui/issues/issue-57843.rs +++ b/src/test/ui/issues/issue-57843.rs @@ -11,7 +11,9 @@ trait ClonableFn<T> { } impl<T, F: 'static> ClonableFn<T> for F -where F: Fn(T) + Clone { +where + F: Fn(T) + Clone, +{ fn clone(&self) -> Box<dyn Fn(T)> { Box::new(self.clone()) } @@ -20,5 +22,5 @@ where F: Fn(T) + Clone { struct Foo(Box<dyn for<'a> ClonableFn<&'a bool>>); fn main() { - Foo(Box::new(|_| ())); //~ ERROR mismatched types + Foo(Box::new(|_| ())); //~ ERROR implementation of `FnOnce` is not general enough } diff --git a/src/test/ui/issues/issue-57843.stderr b/src/test/ui/issues/issue-57843.stderr index 7699e97da99..acd48b6c7e5 100644 --- a/src/test/ui/issues/issue-57843.stderr +++ b/src/test/ui/issues/issue-57843.stderr @@ -1,17 +1,11 @@ -error[E0308]: mismatched types - --> $DIR/issue-57843.rs:23:9 +error: implementation of `FnOnce` is not general enough + --> $DIR/issue-57843.rs:25:9 | LL | Foo(Box::new(|_| ())); - | ^^^^^^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough | - = note: expected type `FnOnce<(&'a bool,)>` - found type `FnOnce<(&bool,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-57843.rs:23:18 - | -LL | Foo(Box::new(|_| ())); - | ^^^^^^ + = note: `[closure@$DIR/issue-57843.rs:25:18: 25:24]` must implement `FnOnce<(&'1 bool,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 bool,)>`, for some specific lifetime `'2` error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/lifetimes/issue-79187.rs b/src/test/ui/lifetimes/issue-79187.rs index bf331d8a606..2ee69ee2234 100644 --- a/src/test/ui/lifetimes/issue-79187.rs +++ b/src/test/ui/lifetimes/issue-79187.rs @@ -2,5 +2,5 @@ fn thing(x: impl FnOnce(&u32)) {} fn main() { let f = |_| (); - thing(f); //~ERROR mismatched types + thing(f); //~ERROR implementation of `FnOnce` is not general enough } diff --git a/src/test/ui/lifetimes/issue-79187.stderr b/src/test/ui/lifetimes/issue-79187.stderr index 63f501e08fc..3627ab5ed1e 100644 --- a/src/test/ui/lifetimes/issue-79187.stderr +++ b/src/test/ui/lifetimes/issue-79187.stderr @@ -1,22 +1,11 @@ -error[E0308]: mismatched types +error: implementation of `FnOnce` is not general enough --> $DIR/issue-79187.rs:5:5 | LL | thing(f); - | ^^^^^ lifetime mismatch + | ^^^^^ implementation of `FnOnce` is not general enough | - = note: expected type `FnOnce<(&u32,)>` - found type `FnOnce<(&u32,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-79187.rs:4:13 - | -LL | let f = |_| (); - | ^^^^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-79187.rs:1:18 - | -LL | fn thing(x: impl FnOnce(&u32)) {} - | ^^^^^^^^^^^^ + = note: `[closure@$DIR/issue-79187.rs:4:13: 4:19]` must implement `FnOnce<(&'1 u32,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 u32,)>`, for some specific lifetime `'2` 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 e278049c8cc..2d485d14a8d 100644 --- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs +++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.rs @@ -8,8 +8,8 @@ fn main() { fn baz<F: Fn(*mut &u32)>(_: F) {} fn _test<'a>(f: fn(*mut &'a u32)) { baz(f); - //~^ ERROR mismatched types - //~| ERROR mismatched types + //~^ ERROR implementation of `FnOnce` is not general enough + //~| ERROR implementation of `FnOnce` is not general enough //~| ERROR mismatched types //~| ERROR mismatched types } 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 02ba60f7f4b..67c5a68ed83 100644 --- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr @@ -41,24 +41,14 @@ note: the lifetime requirement is introduced here LL | fn baz<F: Fn(*mut &u32)>(_: F) {} | ^^^^^^^^^^^^^ -error[E0308]: mismatched types +error: implementation of `FnOnce` is not general enough --> $DIR/closure-arg-type-mismatch.rs:10:5 | LL | baz(f); - | ^^^ lifetime mismatch - | - = note: expected type `FnOnce<(*mut &u32,)>` - found type `FnOnce<(*mut &'a u32,)>` -note: the required lifetime does not necessarily outlive the lifetime `'a` as defined on the function body at 9:10 - --> $DIR/closure-arg-type-mismatch.rs:9:10 - | -LL | fn _test<'a>(f: fn(*mut &'a u32)) { - | ^^ -note: the lifetime requirement is introduced here - --> $DIR/closure-arg-type-mismatch.rs:8:11 + | ^^^ implementation of `FnOnce` is not general enough | -LL | fn baz<F: Fn(*mut &u32)>(_: F) {} - | ^^^^^^^^^^^^^ + = note: `fn(*mut &'2 u32)` must implement `FnOnce<(*mut &'1 u32,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(*mut &'2 u32,)>`, for some specific lifetime `'2` error[E0308]: mismatched types --> $DIR/closure-arg-type-mismatch.rs:10:5 @@ -79,24 +69,14 @@ note: the lifetime requirement is introduced here LL | fn baz<F: Fn(*mut &u32)>(_: F) {} | ^^^^^^^^^^^^^ -error[E0308]: mismatched types +error: implementation of `FnOnce` is not general enough --> $DIR/closure-arg-type-mismatch.rs:10:5 | LL | baz(f); - | ^^^ lifetime mismatch - | - = note: expected type `FnOnce<(*mut &u32,)>` - found type `FnOnce<(*mut &'a u32,)>` -note: the lifetime `'a` as defined on the function body at 9:10 doesn't meet the lifetime requirements - --> $DIR/closure-arg-type-mismatch.rs:9:10 - | -LL | fn _test<'a>(f: fn(*mut &'a u32)) { - | ^^ -note: the lifetime requirement is introduced here - --> $DIR/closure-arg-type-mismatch.rs:8:11 + | ^^^ implementation of `FnOnce` is not general enough | -LL | fn baz<F: Fn(*mut &u32)>(_: F) {} - | ^^^^^^^^^^^^^ + = note: `fn(*mut &'2 u32)` must implement `FnOnce<(*mut &'1 u32,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(*mut &'2 u32,)>`, for some specific lifetime `'2` error: aborting due to 7 previous errors diff --git a/src/test/ui/rfc1623.rs b/src/test/ui/rfc1623.rs index aa6b1c0012c..9ff4813d112 100644 --- a/src/test/ui/rfc1623.rs +++ b/src/test/ui/rfc1623.rs @@ -22,7 +22,7 @@ static SOME_STRUCT: &SomeStruct = &SomeStruct { foo: &Foo { bools: &[false, true] }, bar: &Bar { bools: &[true, true] }, f: &id, - //~^ ERROR mismatched types + //~^ ERROR implementation of `FnOnce` is not general enough }; // very simple test for a 'static static with default lifetime diff --git a/src/test/ui/rfc1623.stderr b/src/test/ui/rfc1623.stderr index 2835e47fa45..e95e68c8e6d 100644 --- a/src/test/ui/rfc1623.stderr +++ b/src/test/ui/rfc1623.stderr @@ -1,12 +1,11 @@ -error[E0308]: mismatched types +error: implementation of `FnOnce` is not general enough --> $DIR/rfc1623.rs:24:8 | LL | f: &id, - | ^^^ one type is more general than the other + | ^^^ implementation of `FnOnce` is not general enough | - = note: expected type `FnOnce<(&'a Foo<'b>,)>` - found type `FnOnce<(&Foo<'_>,)>` + = note: `fn(&'2 Foo<'_>) -> &'2 Foo<'_> {id::<&'2 Foo<'_>>}` must implement `FnOnce<(&'1 Foo<'b>,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 Foo<'_>,)>`, for some specific lifetime `'2` error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr index be1dd1a8524..59b14eedc24 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr @@ -24,19 +24,14 @@ note: this closure does not fulfill the lifetime requirements LL | |x| x | ^^^^^ -error[E0308]: mismatched types +error: implementation of `FnOnce` is not general enough --> $DIR/issue-57611-trait-alias.rs:17:16 | LL | type Bar = impl Baz<Self, Self>; - | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough | - = note: expected type `FnOnce<(&X,)>` - found type `FnOnce<(&'static X,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-57611-trait-alias.rs:25:9 - | -LL | |x| x - | ^^^^^ + = note: `[closure@$DIR/issue-57611-trait-alias.rs:25:9: 25:14]` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` error: aborting due to 4 previous errors diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs index 3372b81404e..561528c2abb 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs @@ -15,9 +15,9 @@ struct X; impl Foo for X { type Bar = impl Baz<Self, Self>; - //~^ ERROR mismatched types - //~| ERROR mismatched types - //~| ERROR mismatched types + //~^ ERROR implementation of `FnOnce` is not general enough + //~| ERROR implementation of `FnOnce` is not general enough + //~| ERROR implementation of `FnOnce` is not general enough //~| ERROR mismatched types //~| ERROR mismatched types diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr index 9d9293e958e..59c91d52cca 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr @@ -1,16 +1,11 @@ -error[E0308]: mismatched types +error: implementation of `FnOnce` is not general enough --> $DIR/issue-57611-trait-alias.rs:17:16 | LL | type Bar = impl Baz<Self, Self>; - | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected type `FnOnce<(&X,)>` - found type `FnOnce<(&X,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-57611-trait-alias.rs:25:9 + | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough | -LL | |x| x - | ^^^^^ + = note: `[closure@$DIR/issue-57611-trait-alias.rs:25:9: 25:14]` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` error[E0308]: mismatched types --> $DIR/issue-57611-trait-alias.rs:17:16 @@ -26,19 +21,14 @@ note: this closure does not fulfill the lifetime requirements LL | |x| x | ^^^^^ -error[E0308]: mismatched types +error: implementation of `FnOnce` is not general enough --> $DIR/issue-57611-trait-alias.rs:17:16 | LL | type Bar = impl Baz<Self, Self>; - | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough | - = note: expected type `FnOnce<(&X,)>` - found type `FnOnce<(&'<empty> X,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-57611-trait-alias.rs:25:9 - | -LL | |x| x - | ^^^^^ + = note: `[closure@$DIR/issue-57611-trait-alias.rs:25:9: 25:14]` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` error[E0308]: mismatched types --> $DIR/issue-57611-trait-alias.rs:17:16 @@ -54,19 +44,14 @@ note: this closure does not fulfill the lifetime requirements LL | |x| x | ^^^^^ -error[E0308]: mismatched types +error: implementation of `FnOnce` is not general enough --> $DIR/issue-57611-trait-alias.rs:17:16 | LL | type Bar = impl Baz<Self, Self>; - | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough | - = note: expected type `FnOnce<(&X,)>` - found type `FnOnce<(&'<empty> X,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-57611-trait-alias.rs:25:9 - | -LL | |x| x - | ^^^^^ + = note: `[closure@$DIR/issue-57611-trait-alias.rs:25:9: 25:14]` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` error: aborting due to 5 previous errors diff --git a/src/test/ui/unboxed-closures/issue-30906.nll.stderr b/src/test/ui/unboxed-closures/issue-30906.nll.stderr index 5a2cbab9a15..2db392e8b8b 100644 --- a/src/test/ui/unboxed-closures/issue-30906.nll.stderr +++ b/src/test/ui/unboxed-closures/issue-30906.nll.stderr @@ -1,5 +1,5 @@ error: higher-ranked subtype error - --> $DIR/issue-30906.rs:15:5 + --> $DIR/issue-30906.rs:18:5 | LL | test(Compose(f, |_| {})); | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/unboxed-closures/issue-30906.rs b/src/test/ui/unboxed-closures/issue-30906.rs index 03cce832775..e2d219e4703 100644 --- a/src/test/ui/unboxed-closures/issue-30906.rs +++ b/src/test/ui/unboxed-closures/issue-30906.rs @@ -2,9 +2,12 @@ fn test<F: for<'x> FnOnce<(&'x str,)>>(_: F) {} -struct Compose<F,G>(F,G); -impl<T,F,G> FnOnce<(T,)> for Compose<F,G> -where F: FnOnce<(T,)>, G: FnOnce<(F::Output,)> { +struct Compose<F, G>(F, G); +impl<T, F, G> FnOnce<(T,)> for Compose<F, G> +where + F: FnOnce<(T,)>, + G: FnOnce<(F::Output,)>, +{ type Output = G::Output; extern "rust-call" fn call_once(self, (x,): (T,)) -> G::Output { (self.1)((self.0)(x)) @@ -12,7 +15,8 @@ where F: FnOnce<(T,)>, G: FnOnce<(F::Output,)> { } fn bad<T>(f: fn(&'static str) -> T) { - test(Compose(f, |_| {})); //~ ERROR: mismatched types + test(Compose(f, |_| {})); + //~^ ERROR: implementation of `FnOnce` is not general enough } fn main() {} diff --git a/src/test/ui/unboxed-closures/issue-30906.stderr b/src/test/ui/unboxed-closures/issue-30906.stderr index ecf3a96b5a8..35b1e454c02 100644 --- a/src/test/ui/unboxed-closures/issue-30906.stderr +++ b/src/test/ui/unboxed-closures/issue-30906.stderr @@ -1,17 +1,11 @@ -error[E0308]: mismatched types - --> $DIR/issue-30906.rs:15:5 +error: implementation of `FnOnce` is not general enough + --> $DIR/issue-30906.rs:18:5 | LL | test(Compose(f, |_| {})); - | ^^^^ lifetime mismatch + | ^^^^ implementation of `FnOnce` is not general enough | - = note: expected type `FnOnce<(&'x str,)>` - found type `FnOnce<(&str,)>` -note: the lifetime requirement is introduced here - --> $DIR/issue-30906.rs:3:12 - | -LL | fn test<F: for<'x> FnOnce<(&'x str,)>>(_: F) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `fn(&'2 str) -> T` must implement `FnOnce<(&'1 str,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 str,)>`, for some specific lifetime `'2` error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. |
