From 788e4bb4e5e1454904cdf0f80a81d02f88d7612d Mon Sep 17 00:00:00 2001 From: 0yoyoyo <60439919+0yoyoyo@users.noreply.github.com> Date: Fri, 12 Feb 2021 00:40:54 +0900 Subject: [PATCH 1/2] Fix suggestion to introduce explicit lifetime --- .../src/infer/error_reporting/mod.rs | 7 ++++- .../missing-lifetimes-in-signature-2.rs | 26 +++++++++++++++++++ .../missing-lifetimes-in-signature-2.stderr | 21 +++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs create mode 100644 src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 84aa19aedebf8..63f8a7293d899 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2248,13 +2248,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "...", ); if let Some(infer::RelateParamBound(_, t)) = origin { + let return_impl_trait = self + .in_progress_typeck_results + .map(|typeck_results| typeck_results.borrow().hir_owner) + .and_then(|owner| self.tcx.return_type_impl_trait(owner)) + .is_some(); let t = self.resolve_vars_if_possible(t); match t.kind() { // We've got: // fn get_later(g: G, dest: &mut T) -> impl FnOnce() + '_ // suggest: // fn get_later<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a - ty::Closure(_, _substs) | ty::Opaque(_, _substs) => { + ty::Closure(_, _substs) | ty::Opaque(_, _substs) if return_impl_trait => { new_binding_suggestion(&mut err, type_param_span, bound_kind); } _ => { diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs new file mode 100644 index 0000000000000..c6802ac6cc704 --- /dev/null +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs @@ -0,0 +1,26 @@ +// Regression test for #81650 + +struct Foo<'a> { + x: &'a mut &'a i32, +} + +impl<'a> Foo<'a> { + fn bar(&self, f: F) + where + F: FnOnce(&Foo<'a>) -> T, + F: 'a, + {} +} + +trait Test { + fn test(&self); +} + +fn func(foo: &Foo, t: T) { + foo.bar(move |_| { + //~^ ERROR the parameter type `T` may not live long enough + t.test(); + }); +} + +fn main() {} diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr new file mode 100644 index 0000000000000..c7def9b668d9c --- /dev/null +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr @@ -0,0 +1,21 @@ +error[E0311]: the parameter type `T` may not live long enough + --> $DIR/missing-lifetimes-in-signature-2.rs:20:9 + | +LL | fn func(foo: &Foo, t: T) { + | -- help: consider adding an explicit lifetime bound...: `T: 'a +` +LL | foo.bar(move |_| { + | ^^^ + | +note: the parameter type `T` must be valid for the anonymous lifetime #2 defined on the function body at 19:1... + --> $DIR/missing-lifetimes-in-signature-2.rs:19:1 + | +LL | fn func(foo: &Foo, t: T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature-2.rs:20:13: 23:6]` will meet its required lifetime bounds + --> $DIR/missing-lifetimes-in-signature-2.rs:20:9 + | +LL | foo.bar(move |_| { + | ^^^ + +error: aborting due to previous error + From fcce998d564678d7736f8382861f0fbb5e549dd2 Mon Sep 17 00:00:00 2001 From: 0yoyoyo <60439919+0yoyoyo@users.noreply.github.com> Date: Fri, 12 Feb 2021 21:51:00 +0900 Subject: [PATCH 2/2] Add nll test --- .../missing-lifetimes-in-signature-2.nll.stderr | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.nll.stderr diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.nll.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.nll.stderr new file mode 100644 index 0000000000000..b359826cb4ae4 --- /dev/null +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.nll.stderr @@ -0,0 +1,17 @@ +error[E0311]: the parameter type `T` may not live long enough + --> $DIR/missing-lifetimes-in-signature-2.rs:20:5 + | +LL | / foo.bar(move |_| { +LL | | +LL | | t.test(); +LL | | }); + | |______^ + | +note: the parameter type `T` must be valid for the anonymous lifetime #2 defined on the function body at 19:1... + --> $DIR/missing-lifetimes-in-signature-2.rs:19:1 + | +LL | fn func(foo: &Foo, t: T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error +