diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 7b0a91986b3a3..5d56744805f89 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -98,7 +98,7 @@ pub(super) fn note_and_explain_region( // uh oh, hope no user ever sees THIS ty::ReEmpty(ui) => (format!("the empty lifetime in universe {:?}", ui), None), - ty::RePlaceholder(_) => ("any other region".to_string(), None), + ty::RePlaceholder(_) => return, // FIXME(#13998) RePlaceholder should probably print like // ReFree rather than dumping Debug output on the user. @@ -1675,6 +1675,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.check_and_note_conflicting_crates(diag, terr); self.tcx.note_and_explain_type_err(diag, terr, cause, span, body_owner_def_id.to_def_id()); + if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values { + if let ty::Closure(def_id, _) = exp_found.expected.skip_binder().self_ty().kind() { + if let Some(def_id) = def_id.as_local() { + let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id); + let span = self.tcx.hir().span(hir_id); + diag.span_note(span, "this closure does not fulfill the lifetime requirements"); + } + } + } + // It reads better to have the error origin as the final // thing. self.note_error_origin(diag, cause, exp_found); diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 7fb94332cad5c..c88869abc29e4 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -1,6 +1,7 @@ use crate::infer::error_reporting::{note_and_explain_region, ObligationCauseExt}; use crate::infer::{self, InferCtxt, SubregionOrigin}; use rustc_errors::{struct_span_err, DiagnosticBuilder}; +use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{self, Region}; @@ -107,14 +108,37 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { infer::Subtype(box trace) => { let terr = TypeError::RegionsDoesNotOutlive(sup, sub); let mut err = self.report_and_explain_type_error(trace, &terr); - note_and_explain_region(self.tcx, &mut err, "", sup, "..."); - note_and_explain_region( - self.tcx, - &mut err, - "...does not necessarily outlive ", - sub, - "", - ); + match (sub, sup) { + (ty::RePlaceholder(_), ty::RePlaceholder(_)) => {} + (ty::RePlaceholder(_), _) => { + note_and_explain_region( + self.tcx, + &mut err, + "", + sup, + " doesn't meet the lifetime requirements", + ); + } + (_, ty::RePlaceholder(_)) => { + note_and_explain_region( + self.tcx, + &mut err, + "the required lifetime does not necessarily outlive ", + sub, + "", + ); + } + _ => { + note_and_explain_region(self.tcx, &mut err, "", sup, "..."); + note_and_explain_region( + self.tcx, + &mut err, + "...does not necessarily outlive ", + sub, + "", + ); + } + } err } infer::Reborrow(span) => { @@ -286,13 +310,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { sup: Region<'tcx>, ) -> DiagnosticBuilder<'tcx> { // I can't think how to do better than this right now. -nikomatsakis + debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure"); match placeholder_origin { + infer::Subtype(box ref trace) + if matches!( + &trace.cause.code.peel_derives(), + ObligationCauseCode::BindingObligation(..) + ) => + { + // Hack to get around the borrow checker because trace.cause has an `Rc`. + if let ObligationCauseCode::BindingObligation(_, span) = + &trace.cause.code.peel_derives() + { + let span = *span; + let mut err = self.report_concrete_failure(placeholder_origin, sub, sup); + err.span_note(span, "the lifetime requirement is introduced here"); + err + } else { + unreachable!() + } + } infer::Subtype(box trace) => { let terr = TypeError::RegionsPlaceholderMismatch; - self.report_and_explain_type_error(trace, &terr) + return self.report_and_explain_type_error(trace, &terr); } - - _ => self.report_concrete_failure(placeholder_origin, sub, sup), + _ => return self.report_concrete_failure(placeholder_origin, sub, sup), } } } 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..e2847b6b72b86 100644 --- a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr +++ b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr @@ -2,10 +2,15 @@ error[E0308]: mismatched types --> $DIR/higher-ranked-projection.rs:25:5 | LL | foo(()); - | ^^^ one type is more general than the other + | ^^^ lifetime mismatch | = note: expected type `&'a ()` found type `&()` +note: the lifetime requirement is introduced here + --> $DIR/higher-ranked-projection.rs:15:33 + | +LL | where for<'a> &'a T: Mirror + | ^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/generator/resume-arg-late-bound.stderr b/src/test/ui/generator/resume-arg-late-bound.stderr index dc0864165abf4..63411b59280bb 100644 --- a/src/test/ui/generator/resume-arg-late-bound.stderr +++ b/src/test/ui/generator/resume-arg-late-bound.stderr @@ -2,19 +2,47 @@ error[E0308]: mismatched types --> $DIR/resume-arg-late-bound.rs:15:5 | LL | test(gen); - | ^^^^ one type is more general than the other + | ^^^^ lifetime mismatch | = note: expected type `for<'a> Generator<&'a mut bool>` found type `Generator<&mut bool>` +note: the required lifetime does not necessarily outlive the anonymous lifetime #1 defined on the body at 11:15 + --> $DIR/resume-arg-late-bound.rs:11:15 + | +LL | let gen = |arg: &mut bool| { + | _______________^ +LL | | yield (); +LL | | *arg = true; +LL | | }; + | |_____^ +note: the lifetime requirement is introduced here + --> $DIR/resume-arg-late-bound.rs:8:17 + | +LL | fn test(a: impl for<'a> Generator<&'a mut bool>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/resume-arg-late-bound.rs:15:5 | LL | test(gen); - | ^^^^ one type is more general than the other + | ^^^^ lifetime mismatch | = note: expected type `for<'a> Generator<&'a mut bool>` found type `Generator<&mut bool>` +note: the anonymous lifetime #1 defined on the body at 11:15 doesn't meet the lifetime requirements + --> $DIR/resume-arg-late-bound.rs:11:15 + | +LL | let gen = |arg: &mut bool| { + | _______________^ +LL | | yield (); +LL | | *arg = true; +LL | | }; + | |_____^ +note: the lifetime requirement is introduced here + --> $DIR/resume-arg-late-bound.rs:8:17 + | +LL | fn test(a: impl for<'a> Generator<&'a mut bool>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr index 1ceb0c99e90e9..ed810d443bef7 100644 --- a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr +++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr @@ -2,19 +2,39 @@ error[E0308]: mismatched types --> $DIR/hrtb-perfect-forwarding.rs:46:5 | LL | foo_hrtb_bar_not(&mut t); - | ^^^^^^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^ lifetime mismatch | = 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> + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/hrtb-perfect-forwarding.rs:46:5 | LL | foo_hrtb_bar_not(&mut t); - | ^^^^^^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^ 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 + | +LL | where T : for<'a> Foo<&'a isize> + Bar<&'b isize> + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-26217.stderr b/src/test/ui/issues/issue-26217.stderr index b1625536d4202..f5c641be2d47c 100644 --- a/src/test/ui/issues/issue-26217.stderr +++ b/src/test/ui/issues/issue-26217.stderr @@ -3,8 +3,6 @@ error[E0477]: the type `&'a i32` does not fulfill the required lifetime | LL | foo::<&'a i32>(); | ^^^^^^^^^^^^^^ - | - = note: type must outlive any other region error: aborting due to previous error diff --git a/src/test/ui/issues/issue-57843.stderr b/src/test/ui/issues/issue-57843.stderr index 01edb9507a3a7..7699e97da99ad 100644 --- a/src/test/ui/issues/issue-57843.stderr +++ b/src/test/ui/issues/issue-57843.stderr @@ -6,6 +6,11 @@ LL | Foo(Box::new(|_| ())); | = 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(|_| ())); + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/lifetimes/issue-79187-2.nll.stderr b/src/test/ui/lifetimes/issue-79187-2.nll.stderr new file mode 100644 index 0000000000000..4970c579e7b98 --- /dev/null +++ b/src/test/ui/lifetimes/issue-79187-2.nll.stderr @@ -0,0 +1,44 @@ +error: lifetime may not live long enough + --> $DIR/issue-79187-2.rs:9:24 + | +LL | take_foo(|a: &i32| a); + | - - ^ returning this value requires that `'1` must outlive `'2` + | | | + | | return type of closure is &'2 i32 + | let's call the lifetime of this reference `'1` + +error: lifetime may not live long enough + --> $DIR/issue-79187-2.rs:10:34 + | +LL | take_foo(|a: &i32| -> &i32 { a }); + | - - ^ returning this value requires that `'1` must outlive `'2` + | | | + | | let's call the lifetime of this reference `'2` + | let's call the lifetime of this reference `'1` + +error: higher-ranked subtype error + --> $DIR/issue-79187-2.rs:8:5 + | +LL | take_foo(|a| a); + | ^^^^^^^^^^^^^^^ + +error: higher-ranked subtype error + --> $DIR/issue-79187-2.rs:8:5 + | +LL | take_foo(|a| a); + | ^^^^^^^^^^^^^^^ + +error: higher-ranked subtype error + --> $DIR/issue-79187-2.rs:9:5 + | +LL | take_foo(|a: &i32| a); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: higher-ranked subtype error + --> $DIR/issue-79187-2.rs:10:5 + | +LL | take_foo(|a: &i32| -> &i32 { a }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/lifetimes/issue-79187-2.rs b/src/test/ui/lifetimes/issue-79187-2.rs new file mode 100644 index 0000000000000..29d108facab3f --- /dev/null +++ b/src/test/ui/lifetimes/issue-79187-2.rs @@ -0,0 +1,23 @@ +trait Foo {} + +impl Foo for F where F: Fn(&i32) -> &i32 {} + +fn take_foo(_: impl Foo) {} + +fn main() { + take_foo(|a| a); //~ ERROR mismatched types + take_foo(|a: &i32| a); //~ ERROR mismatched types + take_foo(|a: &i32| -> &i32 { a }); //~ ERROR mismatched types + + // OK + take_foo(identity(|a| a)); + take_foo(identity(|a: &i32| a)); + take_foo(identity(|a: &i32| -> &i32 { a })); + + fn identity(t: F) -> F + where + F: Fn(&i32) -> &i32, + { + t + } +} diff --git a/src/test/ui/lifetimes/issue-79187-2.stderr b/src/test/ui/lifetimes/issue-79187-2.stderr new file mode 100644 index 0000000000000..a156c74fb3304 --- /dev/null +++ b/src/test/ui/lifetimes/issue-79187-2.stderr @@ -0,0 +1,60 @@ +error[E0308]: mismatched types + --> $DIR/issue-79187-2.rs:8:5 + | +LL | take_foo(|a| a); + | ^^^^^^^^ lifetime mismatch + | + = note: expected type `for<'r> Fn<(&'r i32,)>` + found type `Fn<(&i32,)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/issue-79187-2.rs:8:14 + | +LL | take_foo(|a| a); + | ^^^^^ +note: the lifetime requirement is introduced here + --> $DIR/issue-79187-2.rs:5:21 + | +LL | fn take_foo(_: impl Foo) {} + | ^^^ + +error[E0308]: mismatched types + --> $DIR/issue-79187-2.rs:9:5 + | +LL | take_foo(|a: &i32| a); + | ^^^^^^^^ lifetime mismatch + | + = note: expected reference `&i32` + found reference `&i32` +note: the anonymous lifetime #1 defined on the body at 9:14 doesn't meet the lifetime requirements + --> $DIR/issue-79187-2.rs:9:14 + | +LL | take_foo(|a: &i32| a); + | ^^^^^^^^^^^ +note: the lifetime requirement is introduced here + --> $DIR/issue-79187-2.rs:5:21 + | +LL | fn take_foo(_: impl Foo) {} + | ^^^ + +error[E0308]: mismatched types + --> $DIR/issue-79187-2.rs:10:5 + | +LL | take_foo(|a: &i32| -> &i32 { a }); + | ^^^^^^^^ lifetime mismatch + | + = note: expected reference `&i32` + found reference `&i32` +note: the anonymous lifetime #1 defined on the body at 10:14 doesn't meet the lifetime requirements + --> $DIR/issue-79187-2.rs:10:14 + | +LL | take_foo(|a: &i32| -> &i32 { a }); + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: the lifetime requirement is introduced here + --> $DIR/issue-79187-2.rs:5:21 + | +LL | fn take_foo(_: impl Foo) {} + | ^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/lifetimes/issue-79187.nll.stderr b/src/test/ui/lifetimes/issue-79187.nll.stderr new file mode 100644 index 0000000000000..aa8809dbc95f7 --- /dev/null +++ b/src/test/ui/lifetimes/issue-79187.nll.stderr @@ -0,0 +1,14 @@ +error: higher-ranked subtype error + --> $DIR/issue-79187.rs:5:5 + | +LL | thing(f); + | ^^^^^^^^ + +error: higher-ranked subtype error + --> $DIR/issue-79187.rs:5:5 + | +LL | thing(f); + | ^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/lifetimes/issue-79187.rs b/src/test/ui/lifetimes/issue-79187.rs new file mode 100644 index 0000000000000..bf331d8a6068e --- /dev/null +++ b/src/test/ui/lifetimes/issue-79187.rs @@ -0,0 +1,6 @@ +fn thing(x: impl FnOnce(&u32)) {} + +fn main() { + let f = |_| (); + thing(f); //~ERROR mismatched types +} diff --git a/src/test/ui/lifetimes/issue-79187.stderr b/src/test/ui/lifetimes/issue-79187.stderr new file mode 100644 index 0000000000000..63f501e08fce4 --- /dev/null +++ b/src/test/ui/lifetimes/issue-79187.stderr @@ -0,0 +1,22 @@ +error[E0308]: mismatched types + --> $DIR/issue-79187.rs:5:5 + | +LL | thing(f); + | ^^^^^ lifetime mismatch + | + = 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)) {} + | ^^^^^^^^^^^^ + +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.stderr b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr index 0af44d21196db..02ba60f7f4b73 100644 --- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr @@ -26,37 +26,77 @@ error[E0308]: mismatched types --> $DIR/closure-arg-type-mismatch.rs:10:5 | LL | baz(f); - | ^^^ one type is more general than the other + | ^^^ lifetime mismatch | = note: expected type `for<'r> Fn<(*mut &'r u32,)>` found type `Fn<(*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 + | +LL | fn baz(_: F) {} + | ^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/closure-arg-type-mismatch.rs:10:5 | LL | baz(f); - | ^^^ one type is more general than the other + | ^^^ 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 + | +LL | fn baz(_: F) {} + | ^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/closure-arg-type-mismatch.rs:10:5 | LL | baz(f); - | ^^^ one type is more general than the other + | ^^^ lifetime mismatch | = note: expected type `for<'r> Fn<(*mut &'r u32,)>` found type `Fn<(*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 + | +LL | fn baz(_: F) {} + | ^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/closure-arg-type-mismatch.rs:10:5 | LL | baz(f); - | ^^^ one type is more general than the other + | ^^^ 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 + | +LL | fn baz(_: F) {} + | ^^^^^^^^^^^^^ error: aborting due to 7 previous errors diff --git a/src/test/ui/mismatched_types/closure-mismatch.stderr b/src/test/ui/mismatched_types/closure-mismatch.stderr index 149f505dc6f57..c41bece3c196f 100644 --- a/src/test/ui/mismatched_types/closure-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-mismatch.stderr @@ -2,10 +2,20 @@ error[E0308]: mismatched types --> $DIR/closure-mismatch.rs:8:5 | LL | baz(|_| ()); - | ^^^ one type is more general than the other + | ^^^ lifetime mismatch | = note: expected type `for<'r> Fn<(&'r (),)>` found type `Fn<(&(),)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/closure-mismatch.rs:8:9 + | +LL | baz(|_| ()); + | ^^^^^^ +note: the lifetime requirement is introduced here + --> $DIR/closure-mismatch.rs:5:11 + | +LL | fn baz(_: T) {} + | ^^^ error: aborting due to previous error 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 790aea87510e6..be1dd1a8524c8 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 @@ -18,6 +18,11 @@ LL | type Bar = impl Baz; | = note: expected type `for<'r> Fn<(&'r X,)>` found type `Fn<(&'static X,)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/issue-57611-trait-alias.rs:25:9 + | +LL | |x| x + | ^^^^^ error[E0308]: mismatched types --> $DIR/issue-57611-trait-alias.rs:17:16 @@ -27,6 +32,11 @@ LL | type Bar = impl Baz; | = 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 + | ^^^^^ error: aborting due to 4 previous errors 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 5e2a8db02867f..9d9293e958eeb 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 @@ -6,6 +6,11 @@ LL | type Bar = impl Baz; | = 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 + | +LL | |x| x + | ^^^^^ error[E0308]: mismatched types --> $DIR/issue-57611-trait-alias.rs:17:16 @@ -15,6 +20,11 @@ LL | type Bar = impl Baz; | = note: expected type `for<'r> Fn<(&'r X,)>` found type `Fn<(&' X,)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/issue-57611-trait-alias.rs:25:9 + | +LL | |x| x + | ^^^^^ error[E0308]: mismatched types --> $DIR/issue-57611-trait-alias.rs:17:16 @@ -24,6 +34,11 @@ LL | type Bar = impl Baz; | = 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 + | +LL | |x| x + | ^^^^^ error[E0308]: mismatched types --> $DIR/issue-57611-trait-alias.rs:17:16 @@ -33,6 +48,11 @@ LL | type Bar = impl Baz; | = note: expected type `for<'r> Fn<(&'r X,)>` found type `Fn<(&' X,)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/issue-57611-trait-alias.rs:25:9 + | +LL | |x| x + | ^^^^^ error[E0308]: mismatched types --> $DIR/issue-57611-trait-alias.rs:17:16 @@ -42,6 +62,11 @@ LL | type Bar = impl Baz; | = 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 + | +LL | |x| x + | ^^^^^ error: aborting due to 5 previous errors diff --git a/src/test/ui/unboxed-closures/issue-30906.stderr b/src/test/ui/unboxed-closures/issue-30906.stderr index 5f343ff74a1c5..ecf3a96b5a8dc 100644 --- a/src/test/ui/unboxed-closures/issue-30906.stderr +++ b/src/test/ui/unboxed-closures/issue-30906.stderr @@ -2,10 +2,15 @@ error[E0308]: mismatched types --> $DIR/issue-30906.rs:15:5 | LL | test(Compose(f, |_| {})); - | ^^^^ one type is more general than the other + | ^^^^ lifetime mismatch | = 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 FnOnce<(&'x str,)>>(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error