about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPavel Grigorenko <GrigorenkoPV@ya.ru>2024-09-01 03:42:18 +0300
committerPavel Grigorenko <GrigorenkoPV@ya.ru>2024-09-06 15:47:52 +0300
commitdcfc71310d560a77b4813f60511c2b15c5125b80 (patch)
tree844862fd277f4b9d95cfcaf73c4040090f8b004b
parente38764d73b84eb625102233623e79f36515345e2 (diff)
downloadrust-dcfc71310d560a77b4813f60511c2b15c5125b80.tar.gz
rust-dcfc71310d560a77b4813f60511c2b15c5125b80.zip
elided_named_lifetimes: add suggestions
-rw-r--r--compiler/rustc_lint/messages.ftl2
-rw-r--r--compiler/rustc_lint/src/context/diagnostics.rs44
-rw-r--r--compiler/rustc_lint/src/lints.rs2
-rw-r--r--tests/ui/async-await/issues/issue-63388-1.stderr4
-rw-r--r--tests/ui/const-generics/type-dependent/issue-71348.full.stderr4
-rw-r--r--tests/ui/const-generics/type-dependent/issue-71348.min.stderr4
-rw-r--r--tests/ui/consts/min_const_fn/min_const_fn.stderr9
-rw-r--r--tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr4
-rw-r--r--tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr4
-rw-r--r--tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr4
-rw-r--r--tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr4
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr4
-rw-r--r--tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr4
-rw-r--r--tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr19
-rw-r--r--tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr8
-rw-r--r--tests/ui/lint/elided-named-lifetimes/static.stderr19
-rw-r--r--tests/ui/object-lifetime/object-lifetime-default-elision.stderr4
-rw-r--r--tests/ui/self/elision/ignore-non-reference-lifetimes.stderr9
-rw-r--r--tests/ui/self/self_lifetime-async.stderr9
-rw-r--r--tests/ui/self/self_lifetime.stderr9
-rw-r--r--tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr4
-rw-r--r--tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr4
23 files changed, 166 insertions, 16 deletions
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 759320b9eb6..fe211355ac3 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -256,6 +256,8 @@ lint_elided_named_lifetime = elided lifetime has a name
     .label_elided = this elided lifetime gets resolved as `{$name}`
     .label_named = lifetime `{$name}` declared here
 
+lint_elided_named_lifetime_suggestion = consider specifying it explicitly
+
 lint_enum_intrinsics_mem_discriminant =
     the return value of `mem::discriminant` is unspecified when called with a non-enum type
     .note = the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `{$ty_param}`, which is not an enum
diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs
index b1c1e4f4dd6..a1a371a032e 100644
--- a/compiler/rustc_lint/src/context/diagnostics.rs
+++ b/compiler/rustc_lint/src/context/diagnostics.rs
@@ -7,6 +7,7 @@ use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
 use rustc_errors::{
     elided_lifetime_in_path_suggestion, Applicability, Diag, DiagArgValue, LintDiagnostic,
 };
+use rustc_hir::MissingLifetimeKind;
 use rustc_middle::middle::stability;
 use rustc_session::lint::{BuiltinLintDiag, ElidedLifetimeResolution};
 use rustc_session::Session;
@@ -14,7 +15,8 @@ use rustc_span::symbol::kw;
 use rustc_span::BytePos;
 use tracing::debug;
 
-use crate::lints;
+use crate::fluent_generated;
+use crate::lints::{self, ElidedNamedLifetime};
 
 mod check_cfg;
 
@@ -442,20 +444,32 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
         BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by } => {
             lints::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by }.decorate_lint(diag)
         }
-        BuiltinLintDiag::ElidedNamedLifetimes { elided: (elided, _kind), resolution } => {
-            match resolution {
-                ElidedLifetimeResolution::Static => lints::ElidedNamedLifetime {
-                    elided,
-                    name: kw::StaticLifetime,
-                    named_declaration: None,
-                },
-                ElidedLifetimeResolution::Param(name, declaration) => lints::ElidedNamedLifetime {
-                    elided,
-                    name,
-                    named_declaration: Some(declaration),
-                },
-            }
-            .decorate_lint(diag)
+        BuiltinLintDiag::ElidedNamedLifetimes { elided: (span, kind), resolution } => {
+            let (name, named_declaration) = match resolution {
+                ElidedLifetimeResolution::Static => (kw::StaticLifetime, None),
+                ElidedLifetimeResolution::Param(name, declaration) => (name, Some(declaration)),
+            };
+            ElidedNamedLifetime { span, name, named_declaration }.decorate_lint(diag);
+
+            let (applicability, suggestion) = match kind {
+                MissingLifetimeKind::Underscore => {
+                    (Applicability::MachineApplicable, format!("{name}"))
+                }
+                MissingLifetimeKind::Ampersand => {
+                    (Applicability::MachineApplicable, format!("&{name} "))
+                }
+                MissingLifetimeKind::Comma => (Applicability::Unspecified, format!("<{name}, ")),
+                MissingLifetimeKind::Brackets => (
+                    Applicability::Unspecified,
+                    format!("{}<{name}>", sess.source_map().span_to_snippet(span).unwrap()),
+                ),
+            };
+            diag.span_suggestion_verbose(
+                span,
+                fluent_generated::lint_elided_named_lifetime_suggestion,
+                suggestion,
+                applicability,
+            );
         }
     }
 }
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 9050f36acba..426d671f8e0 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -2627,7 +2627,7 @@ pub(crate) struct ElidedLifetimesInPaths {
 #[diag(lint_elided_named_lifetime)]
 pub(crate) struct ElidedNamedLifetime {
     #[label(lint_label_elided)]
-    pub elided: Span,
+    pub span: Span,
     pub name: Symbol,
     #[label(lint_label_named)]
     pub named_declaration: Option<Span>,
diff --git a/tests/ui/async-await/issues/issue-63388-1.stderr b/tests/ui/async-await/issues/issue-63388-1.stderr
index ef74bfe3237..c8b55977faf 100644
--- a/tests/ui/async-await/issues/issue-63388-1.stderr
+++ b/tests/ui/async-await/issues/issue-63388-1.stderr
@@ -8,6 +8,10 @@ LL |     ) -> &dyn Foo
    |          ^ this elided lifetime gets resolved as `'a`
    |
    = note: `#[warn(elided_named_lifetimes)]` on by default
+help: consider specifying it explicitly
+   |
+LL |     ) -> &'a dyn Foo
+   |          ~~~
 
 error[E0621]: explicit lifetime required in the type of `foo`
   --> $DIR/issue-63388-1.rs:13:5
diff --git a/tests/ui/const-generics/type-dependent/issue-71348.full.stderr b/tests/ui/const-generics/type-dependent/issue-71348.full.stderr
index 177ff20fbf9..8d1c1ea23a8 100644
--- a/tests/ui/const-generics/type-dependent/issue-71348.full.stderr
+++ b/tests/ui/const-generics/type-dependent/issue-71348.full.stderr
@@ -5,6 +5,10 @@ LL |     fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Ta
    |            -- lifetime `'a` declared here                          ^ this elided lifetime gets resolved as `'a`
    |
    = note: `#[warn(elided_named_lifetimes)]` on by default
+help: consider specifying it explicitly
+   |
+LL |     fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<'a, N>>::Target
+   |                                                                    ~~~~
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr
index 5aee282952a..57da3ce21ce 100644
--- a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr
+++ b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr
@@ -5,6 +5,10 @@ LL |     fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Ta
    |            -- lifetime `'a` declared here                          ^ this elided lifetime gets resolved as `'a`
    |
    = note: `#[warn(elided_named_lifetimes)]` on by default
+help: consider specifying it explicitly
+   |
+LL |     fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<'a, N>>::Target
+   |                                                                    ~~~~
 
 error: `&'static str` is forbidden as the type of a const generic parameter
   --> $DIR/issue-71348.rs:10:24
diff --git a/tests/ui/consts/min_const_fn/min_const_fn.stderr b/tests/ui/consts/min_const_fn/min_const_fn.stderr
index 4b348a182b8..b7db403ad16 100644
--- a/tests/ui/consts/min_const_fn/min_const_fn.stderr
+++ b/tests/ui/consts/min_const_fn/min_const_fn.stderr
@@ -8,6 +8,10 @@ LL |     const fn get_lt(&'a self) -> &T { &self.0 }
    |                                  ^ this elided lifetime gets resolved as `'a`
    |
    = note: `#[warn(elided_named_lifetimes)]` on by default
+help: consider specifying it explicitly
+   |
+LL |     const fn get_lt(&'a self) -> &'a T { &self.0 }
+   |                                  ~~~
 
 warning: elided lifetime has a name
   --> $DIR/min_const_fn.rs:48:42
@@ -17,6 +21,11 @@ LL | impl<'a, T> Foo<T> {
 ...
 LL |     const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
    |                                          ^ this elided lifetime gets resolved as `'a`
+   |
+help: consider specifying it explicitly
+   |
+LL |     const fn get_mut_lt(&'a mut self) -> &'a mut T { &mut self.0 }
+   |                                          ~~~
 
 error[E0493]: destructor of `Foo<T>` cannot be evaluated at compile-time
   --> $DIR/min_const_fn.rs:37:25
diff --git a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr
index d0f8f7689d1..ccea9d5e6e9 100644
--- a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr
+++ b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr
@@ -17,6 +17,10 @@ LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
    |                    -- lifetime `'a` declared here  ^^ this elided lifetime gets resolved as `'a`
    |
    = note: `#[warn(elided_named_lifetimes)]` on by default
+help: consider specifying it explicitly
+   |
+LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
+   |                                                    ~~
 
 error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
   --> $DIR/impl-fn-hrtb-bounds.rs:4:41
diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
index 50a9f3ebeab..a60f3986843 100644
--- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
+++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
@@ -5,6 +5,10 @@ LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
    |      -- lifetime `'a` declared here            ^^ this elided lifetime gets resolved as `'a`
    |
    = note: `#[warn(elided_named_lifetimes)]` on by default
+help: consider specifying it explicitly
+   |
+LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + 'a) {
+   |                                                ~~
 
 error[E0792]: expected generic lifetime parameter, found `'_`
   --> $DIR/impl-fn-predefined-lifetimes.rs:7:9
diff --git a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr
index bff3ffd934a..ec0f0708b15 100644
--- a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr
+++ b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr
@@ -5,6 +5,10 @@ LL | pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator<Item =
    |             -- lifetime `'a` declared here                                       ^ this elided lifetime gets resolved as `'a`
    |
    = note: `#[warn(elided_named_lifetimes)]` on by default
+help: consider specifying it explicitly
+   |
+LL | pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator<Item = (u32, &'a u32)> {
+   |                                                                                  ~~~
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
index f835d2655bb..a7512158661 100644
--- a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
+++ b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
@@ -114,6 +114,10 @@ LL | fn m<'a>(_: &'a Foo<'a>) -> &str { "" }
    |      lifetime `'a` declared here
    |
    = note: `#[warn(elided_named_lifetimes)]` on by default
+help: consider specifying it explicitly
+   |
+LL | fn m<'a>(_: &'a Foo<'a>) -> &'a str { "" }
+   |                             ~~~
 
 error: aborting due to 7 previous errors; 1 warning emitted
 
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr
index 2d5d4fb0e72..0943e0cc0d9 100644
--- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr
@@ -7,6 +7,10 @@ LL |   fn foo<'a>(&'a self, x: &i32) -> &i32 {
    |          lifetime `'a` declared here
    |
    = note: `#[warn(elided_named_lifetimes)]` on by default
+help: consider specifying it explicitly
+   |
+LL |   fn foo<'a>(&'a self, x: &i32) -> &'a i32 {
+   |                                    ~~~
 
 error[E0621]: explicit lifetime required in the type of `x`
   --> $DIR/ex1-return-one-existing-name-if-else-using-impl-3.rs:9:36
diff --git a/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr b/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr
index 8c5426a60cb..5af5123c032 100644
--- a/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr
+++ b/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr
@@ -9,6 +9,10 @@ note: the lint level is defined here
    |
 LL | #![deny(elided_named_lifetimes)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
+help: consider specifying it explicitly
+   |
+LL |     pub fn get_mut(&'static self, x: &mut u8) -> &'static mut u8 {
+   |                                                  ~~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr b/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr
index 249ae146b16..6abaad7f5d2 100644
--- a/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr
+++ b/tests/ui/lint/elided-named-lifetimes/missing-lifetime-kind.stderr
@@ -11,6 +11,10 @@ note: the lint level is defined here
    |
 LL | #![deny(elided_named_lifetimes)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
+help: consider specifying it explicitly
+   |
+LL | fn ampersand<'a>(x: &'a u8) -> &'a u8 {
+   |                                ~~~
 
 error: elided lifetime has a name
   --> $DIR/missing-lifetime-kind.rs:10:31
@@ -19,6 +23,11 @@ LL | fn brackets<'a>(x: &'a u8) -> Brackets {
    |             --                ^^^^^^^^ this elided lifetime gets resolved as `'a`
    |             |
    |             lifetime `'a` declared here
+   |
+help: consider specifying it explicitly
+   |
+LL | fn brackets<'a>(x: &'a u8) -> Brackets<'a> {
+   |                               ~~~~~~~~~~~~
 
 error: elided lifetime has a name
   --> $DIR/missing-lifetime-kind.rs:17:33
@@ -27,6 +36,11 @@ LL | fn comma<'a>(x: &'a u8) -> Comma<u8> {
    |          --                     ^ this elided lifetime gets resolved as `'a`
    |          |
    |          lifetime `'a` declared here
+   |
+help: consider specifying it explicitly
+   |
+LL | fn comma<'a>(x: &'a u8) -> Comma<'a, u8> {
+   |                                 ~~~~
 
 error: elided lifetime has a name
   --> $DIR/missing-lifetime-kind.rs:22:34
@@ -35,6 +49,11 @@ LL | fn underscore<'a>(x: &'a u8) -> &'_ u8 {
    |               --                 ^^ this elided lifetime gets resolved as `'a`
    |               |
    |               lifetime `'a` declared here
+   |
+help: consider specifying it explicitly
+   |
+LL | fn underscore<'a>(x: &'a u8) -> &'a u8 {
+   |                                  ~~
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr b/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr
index c465aab1a03..cbc1b862caa 100644
--- a/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr
+++ b/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr
@@ -9,6 +9,10 @@ note: the lint level is defined here
    |
 LL | #[warn(elided_named_lifetimes)]
    |        ^^^^^^^^^^^^^^^^^^^^^^
+help: consider specifying it explicitly
+   |
+LL |     fn bar(x: &'static u8) -> &'static u8 {
+   |                               ~~~~~~~~
 
 error: elided lifetime has a name
   --> $DIR/not-tied-to-crate.rs:11:31
@@ -21,6 +25,10 @@ note: the lint level is defined here
    |
 LL |     #[deny(elided_named_lifetimes)]
    |            ^^^^^^^^^^^^^^^^^^^^^^
+help: consider specifying it explicitly
+   |
+LL |     fn baz(x: &'static u8) -> &'static u8 {
+   |                               ~~~~~~~~
 
 error: aborting due to 1 previous error; 1 warning emitted
 
diff --git a/tests/ui/lint/elided-named-lifetimes/static.stderr b/tests/ui/lint/elided-named-lifetimes/static.stderr
index d2e9776cb4f..6c3944e5ea5 100644
--- a/tests/ui/lint/elided-named-lifetimes/static.stderr
+++ b/tests/ui/lint/elided-named-lifetimes/static.stderr
@@ -9,24 +9,43 @@ note: the lint level is defined here
    |
 LL | #![deny(elided_named_lifetimes)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
+help: consider specifying it explicitly
+   |
+LL | fn ampersand(x: &'static u8) -> &'static u8 {
+   |                                 ~~~~~~~~
 
 error: elided lifetime has a name
   --> $DIR/static.rs:23:32
    |
 LL | fn brackets(x: &'static u8) -> Brackets {
    |                                ^^^^^^^^ this elided lifetime gets resolved as `'static`
+   |
+help: consider specifying it explicitly
+   |
+LL | fn brackets(x: &'static u8) -> Brackets<'static> {
+   |                                ~~~~~~~~~~~~~~~~~
 
 error: elided lifetime has a name
   --> $DIR/static.rs:30:34
    |
 LL | fn comma(x: &'static u8) -> Comma<u8> {
    |                                  ^ this elided lifetime gets resolved as `'static`
+   |
+help: consider specifying it explicitly
+   |
+LL | fn comma(x: &'static u8) -> Comma<'static, u8> {
+   |                                  ~~~~~~~~~
 
 error: elided lifetime has a name
   --> $DIR/static.rs:35:35
    |
 LL | fn underscore(x: &'static u8) -> &'_ u8 {
    |                                   ^^ this elided lifetime gets resolved as `'static`
+   |
+help: consider specifying it explicitly
+   |
+LL | fn underscore(x: &'static u8) -> &'static u8 {
+   |                                   ~~~~~~~
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/object-lifetime/object-lifetime-default-elision.stderr b/tests/ui/object-lifetime/object-lifetime-default-elision.stderr
index b44a184c684..7d239a54eda 100644
--- a/tests/ui/object-lifetime/object-lifetime-default-elision.stderr
+++ b/tests/ui/object-lifetime/object-lifetime-default-elision.stderr
@@ -7,6 +7,10 @@ LL | fn load2<'a>(ss: &'a dyn SomeTrait) -> &dyn SomeTrait {
    |          lifetime `'a` declared here
    |
    = note: `#[warn(elided_named_lifetimes)]` on by default
+help: consider specifying it explicitly
+   |
+LL | fn load2<'a>(ss: &'a dyn SomeTrait) -> &'a dyn SomeTrait {
+   |                                        ~~~
 
 error: lifetime may not live long enough
   --> $DIR/object-lifetime-default-elision.rs:73:5
diff --git a/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr b/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr
index 4465dbae529..460d2ce2cc9 100644
--- a/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr
+++ b/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr
@@ -5,12 +5,21 @@ LL |     fn a<'a>(self: Self, a: &'a str) -> &str {
    |          -- lifetime `'a` declared here ^ this elided lifetime gets resolved as `'a`
    |
    = note: `#[warn(elided_named_lifetimes)]` on by default
+help: consider specifying it explicitly
+   |
+LL |     fn a<'a>(self: Self, a: &'a str) -> &'a str {
+   |                                         ~~~
 
 warning: elided lifetime has a name
   --> $DIR/ignore-non-reference-lifetimes.rs:10:44
    |
 LL |     fn b<'a>(self: Foo<'b>, a: &'a str) -> &str {
    |          -- lifetime `'a` declared here    ^ this elided lifetime gets resolved as `'a`
+   |
+help: consider specifying it explicitly
+   |
+LL |     fn b<'a>(self: Foo<'b>, a: &'a str) -> &'a str {
+   |                                            ~~~
 
 warning: 2 warnings emitted
 
diff --git a/tests/ui/self/self_lifetime-async.stderr b/tests/ui/self/self_lifetime-async.stderr
index 32de3fd18c9..fd167cf392f 100644
--- a/tests/ui/self/self_lifetime-async.stderr
+++ b/tests/ui/self/self_lifetime-async.stderr
@@ -7,12 +7,21 @@ LL |     async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
    |                  lifetime `'b` declared here
    |
    = note: `#[warn(elided_named_lifetimes)]` on by default
+help: consider specifying it explicitly
+   |
+LL |     async fn foo<'b>(self: &'b Foo<'a>) -> &'b () { self.0 }
+   |                                            ~~~
 
 warning: elided lifetime has a name
   --> $DIR/self_lifetime-async.rs:12:52
    |
 LL |     async fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg }
    |                  -- lifetime `'a` declared here    ^ this elided lifetime gets resolved as `'a`
+   |
+help: consider specifying it explicitly
+   |
+LL |     async fn bar<'a>(self: &Alias, arg: &'a ()) -> &'a () { arg }
+   |                                                    ~~~
 
 warning: 2 warnings emitted
 
diff --git a/tests/ui/self/self_lifetime.stderr b/tests/ui/self/self_lifetime.stderr
index cd8f4d8adf8..52189084f04 100644
--- a/tests/ui/self/self_lifetime.stderr
+++ b/tests/ui/self/self_lifetime.stderr
@@ -7,12 +7,21 @@ LL |     fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
    |            lifetime `'b` declared here
    |
    = note: `#[warn(elided_named_lifetimes)]` on by default
+help: consider specifying it explicitly
+   |
+LL |     fn foo<'b>(self: &'b Foo<'a>) -> &'b () { self.0 }
+   |                                      ~~~
 
 warning: elided lifetime has a name
   --> $DIR/self_lifetime.rs:13:46
    |
 LL |     fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg }
    |            -- lifetime `'a` declared here    ^ this elided lifetime gets resolved as `'a`
+   |
+help: consider specifying it explicitly
+   |
+LL |     fn bar<'a>(self: &Alias, arg: &'a ()) -> &'a () { arg }
+   |                                              ~~~
 
 warning: 2 warnings emitted
 
diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
index 30f4509d49d..92f774767c8 100644
--- a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
+++ b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
@@ -131,6 +131,10 @@ LL | fn resolved_anonymous<'a, T: 'a>(f: impl Fn(&'a str) -> &T) {
    |                       -- lifetime `'a` declared here    ^ this elided lifetime gets resolved as `'a`
    |
    = note: `#[warn(elided_named_lifetimes)]` on by default
+help: consider specifying it explicitly
+   |
+LL | fn resolved_anonymous<'a, T: 'a>(f: impl Fn(&'a str) -> &'a T) {
+   |                                                         ~~~
 
 error[E0658]: anonymous lifetimes in `impl Trait` are unstable
   --> $DIR/impl-trait-missing-lifetime-gated.rs:6:35
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
index ea01dcd5020..baa5fa949ec 100644
--- a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
@@ -13,6 +13,10 @@ LL | fn ok2<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_ + 'a
    |        -- lifetime `'a` declared here                          ^^ this elided lifetime gets resolved as `'a`
    |
    = note: `#[warn(elided_named_lifetimes)]` on by default
+help: consider specifying it explicitly
+   |
+LL | fn ok2<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a + 'a
+   |                                                                ~~
 
 error[E0700]: hidden type for `impl FnOnce()` captures lifetime that does not appear in bounds
   --> $DIR/missing-lifetimes-in-signature.rs:19:5
diff --git a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
index e2c21f1636b..73a362d28e7 100644
--- a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
+++ b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
@@ -7,6 +7,10 @@ LL | fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x }
    |             lifetime `'a` declared here
    |
    = note: `#[warn(elided_named_lifetimes)]` on by default
+help: consider specifying it explicitly
+   |
+LL | fn defining<'a, T>(x: &'a i32) -> Opaque<'a, T> { x }
+   |                                         ~~~~
 
 error[E0700]: hidden type for `Opaque2<T>` captures lifetime that does not appear in bounds
   --> $DIR/missing_lifetime_bound.rs:5:47