about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs7
-rw-r--r--src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs26
-rw-r--r--src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr21
3 files changed, 53 insertions, 1 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 84aa19aedeb..63f8a7293d8 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, T>(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 00000000000..c6802ac6cc7
--- /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<F, T>(&self, f: F)
+    where
+        F: FnOnce(&Foo<'a>) -> T,
+        F: 'a,
+    {}
+}
+
+trait Test {
+    fn test(&self);
+}
+
+fn func<T: Test>(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 00000000000..c7def9b668d
--- /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<T: Test>(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<T: Test>(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
+