about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs94
-rw-r--r--tests/ui/error-codes/E0311.fixed13
-rw-r--r--tests/ui/error-codes/E0311.rs4
-rw-r--r--tests/ui/error-codes/E0311.stderr10
-rw-r--r--tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.fixed13
-rw-r--r--tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs4
-rw-r--r--tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr10
-rw-r--r--tests/ui/suggestions/lifetimes/issue-105544.fixed45
-rw-r--r--tests/ui/suggestions/lifetimes/issue-105544.rs45
-rw-r--r--tests/ui/suggestions/lifetimes/issue-105544.stderr110
-rw-r--r--tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.fixed29
-rw-r--r--tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs3
-rw-r--r--tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr10
-rw-r--r--tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr14
14 files changed, 365 insertions, 39 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 66db1a2f928..9747f360eca 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2144,18 +2144,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         // suggest adding an explicit lifetime bound to it.
         let generics = self.tcx.generics_of(generic_param_scope);
         // type_param_span is (span, has_bounds)
+        let mut is_synthetic = false;
+        let mut ast_generics = None;
         let type_param_span = match bound_kind {
             GenericKind::Param(ref param) => {
                 // Account for the case where `param` corresponds to `Self`,
                 // which doesn't have the expected type argument.
                 if !(generics.has_self && param.index == 0) {
                     let type_param = generics.type_param(param, self.tcx);
+                    is_synthetic = type_param.kind.is_synthetic();
                     type_param.def_id.as_local().map(|def_id| {
                         // Get the `hir::Param` to verify whether it already has any bounds.
                         // We do this to avoid suggesting code that ends up as `T: 'a'b`,
                         // instead we suggest `T: 'a + 'b` in that case.
                         let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
-                        let ast_generics = self.tcx.hir().get_generics(hir_id.owner.def_id);
+                        ast_generics = self.tcx.hir().get_generics(hir_id.owner.def_id);
                         let bounds =
                             ast_generics.and_then(|g| g.bounds_span_for_suggestions(def_id));
                         // `sp` only covers `T`, change it so that it covers
@@ -2187,11 +2190,64 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 .unwrap_or("'lt".to_string())
         };
 
-        let add_lt_sugg = generics
-            .params
-            .first()
-            .and_then(|param| param.def_id.as_local())
-            .map(|def_id| (self.tcx.def_span(def_id).shrink_to_lo(), format!("{}, ", new_lt)));
+        let mut add_lt_suggs: Vec<Option<_>> = vec![];
+        if is_synthetic {
+            if let Some(ast_generics) = ast_generics {
+                let named_lifetime_param_exist = ast_generics.params.iter().any(|p| {
+                    matches!(
+                        p.kind,
+                        hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }
+                    )
+                });
+                if named_lifetime_param_exist && let [param, ..] = ast_generics.params
+                {
+                    add_lt_suggs.push(Some((
+                        self.tcx.def_span(param.def_id).shrink_to_lo(),
+                        format!("{new_lt}, "),
+                    )));
+                } else {
+                    add_lt_suggs
+                        .push(Some((ast_generics.span.shrink_to_hi(), format!("<{new_lt}>"))));
+                }
+            }
+        } else {
+            if let [param, ..] = &generics.params[..] && let Some(def_id) = param.def_id.as_local()
+            {
+                add_lt_suggs
+                    .push(Some((self.tcx.def_span(def_id).shrink_to_lo(), format!("{new_lt}, "))));
+            }
+        }
+
+        if let Some(ast_generics) = ast_generics {
+            for p in ast_generics.params {
+                if p.is_elided_lifetime() {
+                    if self
+                        .tcx
+                        .sess
+                        .source_map()
+                        .span_to_prev_source(p.span.shrink_to_hi())
+                        .ok()
+                        .map_or(false, |s| *s.as_bytes().last().unwrap() == b'&')
+                    {
+                        add_lt_suggs
+                            .push(Some(
+                                (
+                                    p.span.shrink_to_hi(),
+                                    if let Ok(snip) = self.tcx.sess.source_map().span_to_next_source(p.span)
+                                        && snip.starts_with(' ')
+                                    {
+                                        format!("{new_lt}")
+                                    } else {
+                                        format!("{new_lt} ")
+                                    }
+                                )
+                            ));
+                    } else {
+                        add_lt_suggs.push(Some((p.span.shrink_to_hi(), format!("<{new_lt}>"))));
+                    }
+                }
+            }
+        }
 
         let labeled_user_string = match bound_kind {
             GenericKind::Param(ref p) => format!("the parameter type `{}`", p),
@@ -2215,20 +2271,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             );
         }
 
-        fn binding_suggestion<S: fmt::Display>(
+        fn binding_suggestion<'tcx, S: fmt::Display>(
             err: &mut Diagnostic,
             type_param_span: Option<(Span, bool)>,
-            bound_kind: GenericKind<'_>,
+            bound_kind: GenericKind<'tcx>,
             sub: S,
-            add_lt_sugg: Option<(Span, String)>,
+            add_lt_suggs: Vec<Option<(Span, String)>>,
         ) {
             let msg = "consider adding an explicit lifetime bound";
             if let Some((sp, has_lifetimes)) = type_param_span {
                 let suggestion =
                     if has_lifetimes { format!(" + {}", sub) } else { format!(": {}", sub) };
                 let mut suggestions = vec![(sp, suggestion)];
-                if let Some(add_lt_sugg) = add_lt_sugg {
-                    suggestions.push(add_lt_sugg);
+                for add_lt_sugg in add_lt_suggs {
+                    if let Some(add_lt_sugg) = add_lt_sugg {
+                        suggestions.push(add_lt_sugg);
+                    }
                 }
                 err.multipart_suggestion_verbose(
                     format!("{msg}..."),
@@ -2252,9 +2310,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     };
                     let mut sugg =
                         vec![(sp, suggestion), (span.shrink_to_hi(), format!(" + {}", new_lt))];
-                    if let Some(lt) = add_lt_sugg.clone() {
-                        sugg.push(lt);
-                        sugg.rotate_right(1);
+                    for add_lt_sugg in add_lt_suggs.clone() {
+                        if let Some(lt) = add_lt_sugg {
+                            sugg.push(lt);
+                            sugg.rotate_right(1);
+                        }
                     }
                     // `MaybeIncorrect` due to issue #41966.
                     err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect);
@@ -2358,7 +2418,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 // for the bound is not suitable for suggestions when `-Zverbose` is set because it
                 // uses `Debug` output, so we handle it specially here so that suggestions are
                 // always correct.
-                binding_suggestion(&mut err, type_param_span, bound_kind, name, None);
+                binding_suggestion(&mut err, type_param_span, bound_kind, name, vec![]);
                 err
             }
 
@@ -2371,7 +2431,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     "{} may not live long enough",
                     labeled_user_string
                 );
-                binding_suggestion(&mut err, type_param_span, bound_kind, "'static", None);
+                binding_suggestion(&mut err, type_param_span, bound_kind, "'static", vec![]);
                 err
             }
 
@@ -2410,7 +2470,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                                 type_param_span,
                                 bound_kind,
                                 new_lt,
-                                add_lt_sugg,
+                                add_lt_suggs,
                             );
                         }
                     }
diff --git a/tests/ui/error-codes/E0311.fixed b/tests/ui/error-codes/E0311.fixed
new file mode 100644
index 00000000000..4410a4d707a
--- /dev/null
+++ b/tests/ui/error-codes/E0311.fixed
@@ -0,0 +1,13 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+fn no_restriction<'a, T: 'a>(x: &'a ()) -> &() {
+    with_restriction::<T>(x) //~ ERROR E0311
+}
+
+fn with_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
+    x
+}
+
+fn main() {}
diff --git a/tests/ui/error-codes/E0311.rs b/tests/ui/error-codes/E0311.rs
index 566b518b433..99e454f4d75 100644
--- a/tests/ui/error-codes/E0311.rs
+++ b/tests/ui/error-codes/E0311.rs
@@ -1,3 +1,7 @@
+// run-rustfix
+
+#![allow(warnings)]
+
 fn no_restriction<T>(x: &()) -> &() {
     with_restriction::<T>(x) //~ ERROR E0311
 }
diff --git a/tests/ui/error-codes/E0311.stderr b/tests/ui/error-codes/E0311.stderr
index 9873b5ae6ff..b0e6dd1e272 100644
--- a/tests/ui/error-codes/E0311.stderr
+++ b/tests/ui/error-codes/E0311.stderr
@@ -1,23 +1,23 @@
 error[E0311]: the parameter type `T` may not live long enough
-  --> $DIR/E0311.rs:2:5
+  --> $DIR/E0311.rs:6:5
    |
 LL |     with_restriction::<T>(x)
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
 note: the parameter type `T` must be valid for the anonymous lifetime defined here...
-  --> $DIR/E0311.rs:1:25
+  --> $DIR/E0311.rs:5:25
    |
 LL | fn no_restriction<T>(x: &()) -> &() {
    |                         ^^^
 note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/E0311.rs:2:5
+  --> $DIR/E0311.rs:6:5
    |
 LL |     with_restriction::<T>(x)
    |     ^^^^^^^^^^^^^^^^^^^^^
 help: consider adding an explicit lifetime bound...
    |
-LL | fn no_restriction<'a, T: 'a>(x: &()) -> &() {
-   |                   +++  ++++
+LL | fn no_restriction<'a, T: 'a>(x: &'a ()) -> &() {
+   |                   +++  ++++      ++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.fixed b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.fixed
new file mode 100644
index 00000000000..f977f0bd3a8
--- /dev/null
+++ b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.fixed
@@ -0,0 +1,13 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+fn no_restriction<'a, T: 'a>(x: &'a ()) -> &() {
+    with_restriction::<T>(x) //~ ERROR the parameter type `T` may not live long enough
+}
+
+fn with_restriction<'b, T: 'b>(x: &'b ()) -> &'b () {
+    x
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs
index 645bc7db0dd..d6ce112ec93 100644
--- a/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs
+++ b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs
@@ -1,3 +1,7 @@
+// run-rustfix
+
+#![allow(warnings)]
+
 fn no_restriction<T>(x: &()) -> &() {
     with_restriction::<T>(x) //~ ERROR the parameter type `T` may not live long enough
 }
diff --git a/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr
index 31fd8a4d633..2d58d3a02f3 100644
--- a/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr
+++ b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr
@@ -1,23 +1,23 @@
 error[E0311]: the parameter type `T` may not live long enough
-  --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:2:5
+  --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:6:5
    |
 LL |     with_restriction::<T>(x)
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
 note: the parameter type `T` must be valid for the anonymous lifetime defined here...
-  --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:1:25
+  --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:5:25
    |
 LL | fn no_restriction<T>(x: &()) -> &() {
    |                         ^^^
 note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:2:5
+  --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:6:5
    |
 LL |     with_restriction::<T>(x)
    |     ^^^^^^^^^^^^^^^^^^^^^
 help: consider adding an explicit lifetime bound...
    |
-LL | fn no_restriction<'a, T: 'a>(x: &()) -> &() {
-   |                   +++  ++++
+LL | fn no_restriction<'a, T: 'a>(x: &'a ()) -> &() {
+   |                   +++  ++++      ++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/suggestions/lifetimes/issue-105544.fixed b/tests/ui/suggestions/lifetimes/issue-105544.fixed
new file mode 100644
index 00000000000..47087eb4749
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/issue-105544.fixed
@@ -0,0 +1,45 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+fn foo<'a>(d: impl Sized + 'a, p: &'a mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `impl Sized` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+    (d, p)
+    //~^ ERROR the parameter type `impl Sized` may not live long enough
+    //~| NOTE ...so that the type `impl Sized` will meet its required lifetime bounds
+}
+
+fn foo1<'b>(d: impl Sized + 'b, p: &'b mut ()) -> impl Sized + '_ {
+//~^ HELP consider adding an explicit lifetime bound...
+    (d, p) //~ NOTE ...so that the type `impl Sized` will meet its required lifetime bounds
+    //~^ ERROR the parameter type `impl Sized` may not live long enough
+}
+
+fn foo2<'b, 'a>(d: impl Sized + 'a + 'b, p: &'b mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `impl Sized + 'a` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+    (d, p)
+    //~^ ERROR the parameter type `impl Sized + 'a` may not live long enough
+    //~| NOTE ...so that the type `impl Sized + 'a` will meet its required lifetime bounds
+}
+
+fn bar<'a, T : Sized + 'a>(d: T, p: &'a mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `T` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+    (d, p)
+    //~^ ERROR the parameter type `T` may not live long enough
+    //~| NOTE ...so that the type `T` will meet its required lifetime bounds
+}
+
+fn bar1<'b, T : Sized + 'b>(d: T, p: &'b mut ()) -> impl Sized + '_ {
+//~^ HELP consider adding an explicit lifetime bound...
+    (d, p) //~ NOTE ...so that the type `T` will meet its required lifetime bounds
+    //~^ ERROR the parameter type `T` may not live long enough
+}
+
+fn bar2<'b, 'a, T : Sized + 'a + 'b>(d: T, p: &'b mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `T` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+    (d, p)
+    //~^ ERROR the parameter type `T` may not live long enough
+    //~| NOTE ...so that the type `T` will meet its required lifetime bounds
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/lifetimes/issue-105544.rs b/tests/ui/suggestions/lifetimes/issue-105544.rs
new file mode 100644
index 00000000000..bd3bc1ef9bd
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/issue-105544.rs
@@ -0,0 +1,45 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+fn foo(d: impl Sized, p: &mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `impl Sized` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+    (d, p)
+    //~^ ERROR the parameter type `impl Sized` may not live long enough
+    //~| NOTE ...so that the type `impl Sized` will meet its required lifetime bounds
+}
+
+fn foo1<'b>(d: impl Sized, p: &'b mut ()) -> impl Sized + '_ {
+//~^ HELP consider adding an explicit lifetime bound...
+    (d, p) //~ NOTE ...so that the type `impl Sized` will meet its required lifetime bounds
+    //~^ ERROR the parameter type `impl Sized` may not live long enough
+}
+
+fn foo2<'a>(d: impl Sized + 'a, p: &mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `impl Sized + 'a` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+    (d, p)
+    //~^ ERROR the parameter type `impl Sized + 'a` may not live long enough
+    //~| NOTE ...so that the type `impl Sized + 'a` will meet its required lifetime bounds
+}
+
+fn bar<T : Sized>(d: T, p: & mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `T` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+    (d, p)
+    //~^ ERROR the parameter type `T` may not live long enough
+    //~| NOTE ...so that the type `T` will meet its required lifetime bounds
+}
+
+fn bar1<'b, T : Sized>(d: T, p: &'b mut ()) -> impl Sized + '_ {
+//~^ HELP consider adding an explicit lifetime bound...
+    (d, p) //~ NOTE ...so that the type `T` will meet its required lifetime bounds
+    //~^ ERROR the parameter type `T` may not live long enough
+}
+
+fn bar2<'a, T : Sized + 'a>(d: T, p: &mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `T` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+    (d, p)
+    //~^ ERROR the parameter type `T` may not live long enough
+    //~| NOTE ...so that the type `T` will meet its required lifetime bounds
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/lifetimes/issue-105544.stderr b/tests/ui/suggestions/lifetimes/issue-105544.stderr
new file mode 100644
index 00000000000..08fe21b11b5
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/issue-105544.stderr
@@ -0,0 +1,110 @@
+error[E0311]: the parameter type `impl Sized` may not live long enough
+  --> $DIR/issue-105544.rs:7:5
+   |
+LL |     (d, p)
+   |     ^^^^^^
+   |
+note: the parameter type `impl Sized` must be valid for the anonymous lifetime defined here...
+  --> $DIR/issue-105544.rs:5:26
+   |
+LL | fn foo(d: impl Sized, p: &mut ()) -> impl Sized + '_ {
+   |                          ^^^^^^^
+note: ...so that the type `impl Sized` will meet its required lifetime bounds
+  --> $DIR/issue-105544.rs:7:5
+   |
+LL |     (d, p)
+   |     ^^^^^^
+help: consider adding an explicit lifetime bound...
+   |
+LL | fn foo<'a>(d: impl Sized + 'a, p: &'a mut ()) -> impl Sized + '_ {
+   |       ++++               ++++      ++
+
+error[E0309]: the parameter type `impl Sized` may not live long enough
+  --> $DIR/issue-105544.rs:14:5
+   |
+LL |     (d, p)
+   |     ^^^^^^ ...so that the type `impl Sized` will meet its required lifetime bounds
+   |
+help: consider adding an explicit lifetime bound...
+   |
+LL | fn foo1<'b>(d: impl Sized + 'b, p: &'b mut ()) -> impl Sized + '_ {
+   |                           ++++
+
+error[E0311]: the parameter type `impl Sized + 'a` may not live long enough
+  --> $DIR/issue-105544.rs:20:5
+   |
+LL |     (d, p)
+   |     ^^^^^^
+   |
+note: the parameter type `impl Sized + 'a` must be valid for the anonymous lifetime defined here...
+  --> $DIR/issue-105544.rs:18:36
+   |
+LL | fn foo2<'a>(d: impl Sized + 'a, p: &mut ()) -> impl Sized + '_ {
+   |                                    ^^^^^^^
+note: ...so that the type `impl Sized + 'a` will meet its required lifetime bounds
+  --> $DIR/issue-105544.rs:20:5
+   |
+LL |     (d, p)
+   |     ^^^^^^
+help: consider adding an explicit lifetime bound...
+   |
+LL | fn foo2<'b, 'a>(d: impl Sized + 'a + 'b, p: &'b mut ()) -> impl Sized + '_ {
+   |         +++                        ++++      ++
+
+error[E0311]: the parameter type `T` may not live long enough
+  --> $DIR/issue-105544.rs:27:5
+   |
+LL |     (d, p)
+   |     ^^^^^^
+   |
+note: the parameter type `T` must be valid for the anonymous lifetime defined here...
+  --> $DIR/issue-105544.rs:25:28
+   |
+LL | fn bar<T : Sized>(d: T, p: & mut ()) -> impl Sized + '_ {
+   |                            ^^^^^^^^
+note: ...so that the type `T` will meet its required lifetime bounds
+  --> $DIR/issue-105544.rs:27:5
+   |
+LL |     (d, p)
+   |     ^^^^^^
+help: consider adding an explicit lifetime bound...
+   |
+LL | fn bar<'a, T : Sized + 'a>(d: T, p: &'a mut ()) -> impl Sized + '_ {
+   |        +++           ++++            ++
+
+error[E0309]: the parameter type `T` may not live long enough
+  --> $DIR/issue-105544.rs:34:5
+   |
+LL |     (d, p)
+   |     ^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+   |
+help: consider adding an explicit lifetime bound...
+   |
+LL | fn bar1<'b, T : Sized + 'b>(d: T, p: &'b mut ()) -> impl Sized + '_ {
+   |                       ++++
+
+error[E0311]: the parameter type `T` may not live long enough
+  --> $DIR/issue-105544.rs:40:5
+   |
+LL |     (d, p)
+   |     ^^^^^^
+   |
+note: the parameter type `T` must be valid for the anonymous lifetime defined here...
+  --> $DIR/issue-105544.rs:38:38
+   |
+LL | fn bar2<'a, T : Sized + 'a>(d: T, p: &mut ()) -> impl Sized + '_ {
+   |                                      ^^^^^^^
+note: ...so that the type `T` will meet its required lifetime bounds
+  --> $DIR/issue-105544.rs:40:5
+   |
+LL |     (d, p)
+   |     ^^^^^^
+help: consider adding an explicit lifetime bound...
+   |
+LL | fn bar2<'b, 'a, T : Sized + 'a + 'b>(d: T, p: &'b mut ()) -> impl Sized + '_ {
+   |         +++                    ++++            ++
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0309, E0311.
+For more information about an error, try `rustc --explain E0309`.
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.fixed b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.fixed
new file mode 100644
index 00000000000..4013d98c3cf
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.fixed
@@ -0,0 +1,29 @@
+// Regression test for #81650
+// run-rustfix
+
+#![allow(warnings)]
+
+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<'a, T: Test + 'a>(foo: &'a Foo<'a>, t: T) {
+    foo.bar(move |_| {
+    //~^ ERROR the parameter type `T` may not live long enough
+        t.test();
+    });
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs
index c6802ac6cc7..4096d95e5fd 100644
--- a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs
@@ -1,4 +1,7 @@
 // Regression test for #81650
+// run-rustfix
+
+#![allow(warnings)]
 
 struct Foo<'a> {
     x: &'a mut &'a i32,
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr
index 872263fd731..936d87f7968 100644
--- a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr
@@ -1,5 +1,5 @@
 error[E0311]: the parameter type `T` may not live long enough
-  --> $DIR/missing-lifetimes-in-signature-2.rs:20:5
+  --> $DIR/missing-lifetimes-in-signature-2.rs:23:5
    |
 LL | /     foo.bar(move |_| {
 LL | |
@@ -8,12 +8,12 @@ LL | |     });
    | |______^
    |
 note: the parameter type `T` must be valid for the anonymous lifetime defined here...
-  --> $DIR/missing-lifetimes-in-signature-2.rs:19:24
+  --> $DIR/missing-lifetimes-in-signature-2.rs:22:24
    |
 LL | fn func<T: Test>(foo: &Foo, t: T) {
    |                        ^^^
 note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/missing-lifetimes-in-signature-2.rs:20:5
+  --> $DIR/missing-lifetimes-in-signature-2.rs:23:5
    |
 LL | /     foo.bar(move |_| {
 LL | |
@@ -22,8 +22,8 @@ LL | |     });
    | |______^
 help: consider adding an explicit lifetime bound...
    |
-LL | fn func<'a, T: Test + 'a>(foo: &Foo, t: T) {
-   |         +++         ++++
+LL | fn func<'a, T: Test + 'a>(foo: &'a Foo<'a>, t: T) {
+   |         +++         ++++        ++    ++++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
index fa758bf05df..c5c3f7b468c 100644
--- a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
@@ -47,7 +47,7 @@ LL | |     }
    | |_____^
 help: consider adding an explicit lifetime bound...
    |
-LL ~ fn bar<'a, G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+LL ~ fn bar<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_
 LL | where
 LL ~     G: Get<T> + 'a,
    |
@@ -76,8 +76,8 @@ LL | |     }
    | |_____^
 help: consider adding an explicit lifetime bound...
    |
-LL | fn qux<'b, 'a, G: 'a + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
-   |        +++           ++++
+LL | fn qux<'b, 'a, G: 'a + 'b, T>(g: G, dest: &'b mut T) -> impl FnOnce() + '_
+   |        +++           ++++                  ++
 
 error[E0311]: the parameter type `G` may not live long enough
   --> $DIR/missing-lifetimes-in-signature.rs:61:9
@@ -103,8 +103,8 @@ LL | |         }
    | |_________^
 help: consider adding an explicit lifetime bound...
    |
-LL |     fn qux<'c, 'b, G: Get<T> + 'b + 'c, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
-   |            +++                    ++++
+LL |     fn qux<'c, 'b, G: Get<T> + 'b + 'c, T>(g: G, dest: &'c mut T) -> impl FnOnce() + '_ {
+   |            +++                    ++++                  ++
 
 error[E0311]: the parameter type `G` may not live long enough
   --> $DIR/missing-lifetimes-in-signature.rs:73:5
@@ -132,8 +132,8 @@ LL | |     }
    | |_____^
 help: consider adding an explicit lifetime bound...
    |
-LL | fn bat<'b, 'a, G: 'a + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
-   |        +++           ++++
+LL | fn bat<'b, 'a, G: 'a + 'b, T>(g: G, dest: &'b mut T) -> impl FnOnce() + '_ + 'a
+   |        +++           ++++                  ++
 
 error[E0621]: explicit lifetime required in the type of `dest`
   --> $DIR/missing-lifetimes-in-signature.rs:73:5