about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-03-02 04:30:04 +0100
committerGitHub <noreply@github.com>2022-03-02 04:30:04 +0100
commit2b72ecbb42f6df96b038f0e1123219c3e39917e8 (patch)
tree736020da076c7f7a796626f1e80148b06ddc90d9
parentf0c4da49983aa699f715caf681e3154b445fb60b (diff)
parent1b08cba310c64a4db7398baabd8fd8c0dce01c2e (diff)
downloadrust-2b72ecbb42f6df96b038f0e1123219c3e39917e8.tar.gz
rust-2b72ecbb42f6df96b038f0e1123219c3e39917e8.zip
Rollup merge of #94464 - kckeiks:lifetime-elision-mismatch-hint-for-traits, r=estebank
Suggest adding a new lifetime parameter when two elided lifetimes should match up for traits and impls.

Suggest adding a new lifetime parameter when two elided lifetimes should match up for functions in traits and impls.

Issue #94462
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs106
-rw-r--r--src/test/ui/issues/issue-17728.stderr6
-rw-r--r--src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr6
-rw-r--r--src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr6
-rw-r--r--src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr6
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr12
-rw-r--r--src/test/ui/self/elision/lt-ref-self.stderr36
-rw-r--r--src/test/ui/self/elision/ref-mut-self.stderr36
-rw-r--r--src/test/ui/self/elision/ref-mut-struct.stderr30
-rw-r--r--src/test/ui/self/elision/ref-self.stderr42
-rw-r--r--src/test/ui/self/elision/ref-struct.stderr30
11 files changed, 264 insertions, 52 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs
index bbbb0f79acc..d7e88d02595 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs
@@ -166,59 +166,61 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
             if lifetime_sub.name.is_elided() && lifetime_sup.name.is_elided() {
                 if let Some(anon_reg) = self.tcx().is_suitable_region(sub) {
                     let hir_id = self.tcx().hir().local_def_id_to_hir_id(anon_reg.def_id);
-                    if let hir::Node::Item(&hir::Item {
-                        kind: hir::ItemKind::Fn(_, ref generics, ..),
-                        ..
-                    }) = self.tcx().hir().get(hir_id)
-                    {
-                        let (suggestion_param_name, introduce_new) = generics
-                            .params
-                            .iter()
-                            .find(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }))
-                            .and_then(|p| self.tcx().sess.source_map().span_to_snippet(p.span).ok())
-                            .map(|name| (name, false))
-                            .unwrap_or_else(|| ("'a".to_string(), true));
-
-                        let mut suggestions = vec![
-                            if let hir::LifetimeName::Underscore = lifetime_sub.name {
-                                (lifetime_sub.span, suggestion_param_name.clone())
-                            } else {
-                                (
-                                    lifetime_sub.span.shrink_to_hi(),
-                                    suggestion_param_name.clone() + " ",
-                                )
-                            },
-                            if let hir::LifetimeName::Underscore = lifetime_sup.name {
-                                (lifetime_sup.span, suggestion_param_name.clone())
-                            } else {
-                                (
-                                    lifetime_sup.span.shrink_to_hi(),
-                                    suggestion_param_name.clone() + " ",
-                                )
-                            },
-                        ];
-
-                        if introduce_new {
-                            let new_param_suggestion = match &generics.params {
-                                [] => (generics.span, format!("<{}>", suggestion_param_name)),
-                                [first, ..] => (
-                                    first.span.shrink_to_lo(),
-                                    format!("{}, ", suggestion_param_name),
-                                ),
-                            };
-
-                            suggestions.push(new_param_suggestion);
-                        }
-
-                        err.multipart_suggestion(
-                            "consider introducing a named lifetime parameter",
-                            suggestions,
-                            Applicability::MaybeIncorrect,
-                        );
-                        err.note(
-                            "each elided lifetime in input position becomes a distinct lifetime",
-                        );
+
+                    let node = self.tcx().hir().get(hir_id);
+                    let is_impl = matches!(&node, hir::Node::ImplItem(_));
+                    let generics = match node {
+                        hir::Node::Item(&hir::Item {
+                            kind: hir::ItemKind::Fn(_, ref generics, ..),
+                            ..
+                        })
+                        | hir::Node::TraitItem(&hir::TraitItem { ref generics, .. })
+                        | hir::Node::ImplItem(&hir::ImplItem { ref generics, .. }) => generics,
+                        _ => return,
+                    };
+
+                    let (suggestion_param_name, introduce_new) = generics
+                        .params
+                        .iter()
+                        .find(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }))
+                        .and_then(|p| self.tcx().sess.source_map().span_to_snippet(p.span).ok())
+                        .map(|name| (name, false))
+                        .unwrap_or_else(|| ("'a".to_string(), true));
+
+                    let mut suggestions = vec![
+                        if let hir::LifetimeName::Underscore = lifetime_sub.name {
+                            (lifetime_sub.span, suggestion_param_name.clone())
+                        } else {
+                            (lifetime_sub.span.shrink_to_hi(), suggestion_param_name.clone() + " ")
+                        },
+                        if let hir::LifetimeName::Underscore = lifetime_sup.name {
+                            (lifetime_sup.span, suggestion_param_name.clone())
+                        } else {
+                            (lifetime_sup.span.shrink_to_hi(), suggestion_param_name.clone() + " ")
+                        },
+                    ];
+
+                    if introduce_new {
+                        let new_param_suggestion = match &generics.params {
+                            [] => (generics.span, format!("<{}>", suggestion_param_name)),
+                            [first, ..] => {
+                                (first.span.shrink_to_lo(), format!("{}, ", suggestion_param_name))
+                            }
+                        };
+
+                        suggestions.push(new_param_suggestion);
+                    }
+
+                    let mut sugg = String::from("consider introducing a named lifetime parameter");
+                    if is_impl {
+                        sugg.push_str(" and update trait if needed");
                     }
+                    err.multipart_suggestion(
+                        sugg.as_str(),
+                        suggestions,
+                        Applicability::MaybeIncorrect,
+                    );
+                    err.note("each elided lifetime in input position becomes a distinct lifetime");
                 }
             }
         }
diff --git a/src/test/ui/issues/issue-17728.stderr b/src/test/ui/issues/issue-17728.stderr
index 50e3b853fcb..943c63667e0 100644
--- a/src/test/ui/issues/issue-17728.stderr
+++ b/src/test/ui/issues/issue-17728.stderr
@@ -8,6 +8,12 @@ LL |     fn attemptTraverse(&self, room: &Room, directionStr: &str) -> Result<&R
 ...
 LL |             Some(entry) => Ok(entry),
    |                            ^^^^^^^^^ ...but data from `room` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter
+   |
+LL |     fn attemptTraverse<'a>(&'a self, room: &'a Room, directionStr: &str) -> Result<&Room, &str> {
+   |                       ++++  ++              ++
 
 error[E0308]: `match` arms have incompatible types
   --> $DIR/issue-17728.rs:109:14
diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr
index 199f880b3c4..636904aefb4 100644
--- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr
+++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr
@@ -7,6 +7,12 @@ LL |   fn foo<'a>(&self, x: &i32) -> &i32 {
    |                        this parameter and the return type are declared with different lifetimes...
 LL |     x
    |     ^ ...but data from `x` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |   fn foo<'a>(&'a self, x: &'a i32) -> &i32 {
+   |               ++           ++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr
index 838f43b3774..474eadb7f92 100644
--- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr
+++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr
@@ -7,6 +7,12 @@ LL |     fn foo<'a>(&self, x: &Foo) -> &Foo {
    |                          this parameter and the return type are declared with different lifetimes...
 LL |         if true { x } else { self }
    |                   ^ ...but data from `x` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn foo<'a>(&'a self, x: &'a Foo) -> &Foo {
+   |                 ++           ++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr
index e8b0208f092..68893781dc2 100644
--- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr
+++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr
@@ -5,6 +5,12 @@ LL |     fn foo(x: &mut Vec<&u8>, y: &u8) {
    |                        ---      --- these two types are declared with different lifetimes...
 LL |         x.push(y);
    |                ^ ...but data from `y` flows into `x` here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) {
+   |           ++++              ++          ++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr
index 6bb7ad7cdc7..64a57469510 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr
@@ -5,6 +5,12 @@ LL |     fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
    |                              ----     ----   ^ ...but data from `f` is returned here
    |                              |
    |                              this parameter and the return type are declared with different lifetimes...
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn a<'a>(self: Pin<&'a Foo>, f: &'a Foo) -> &Foo { f }
+   |         ++++            ++           ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:8:76
@@ -13,6 +19,12 @@ LL |     fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self,
    |                               ----              -----------------          ^ ...but data from `f` is returned here
    |                               |
    |                               this parameter and the return type are declared with different lifetimes...
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn c<'a>(self: Pin<&'a Self>, f: &'a Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
+   |         ++++            ++            ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:13:58
diff --git a/src/test/ui/self/elision/lt-ref-self.stderr b/src/test/ui/self/elision/lt-ref-self.stderr
index f392580d422..5764ab03c55 100644
--- a/src/test/ui/self/elision/lt-ref-self.stderr
+++ b/src/test/ui/self/elision/lt-ref-self.stderr
@@ -7,6 +7,12 @@ LL |     fn ref_self(&self, f: &u32) -> &u32 {
    |                           this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 {
+   |                ++++  ++           ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/lt-ref-self.rs:17:9
@@ -17,6 +23,12 @@ LL |     fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                                 this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 {
+   |                ++++        ++           ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/lt-ref-self.rs:21:9
@@ -27,6 +39,12 @@ LL |     fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                                          this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &u32 {
+   |                    ++++            ++            ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/lt-ref-self.rs:25:9
@@ -37,6 +55,12 @@ LL |     fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                                          this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &u32 {
+   |                    ++++            ++            ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/lt-ref-self.rs:29:9
@@ -47,6 +71,12 @@ LL |     fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                                   this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn box_box_ref_Self<'a>(self: Box<Box<&'a Self>>, f: &'a u32) -> &u32 {
+   |                        ++++                ++             ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/lt-ref-self.rs:33:9
@@ -57,6 +87,12 @@ LL |     fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                               this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn box_pin_Self<'a>(self: Box<Pin<&'a Self>>, f: &'a u32) -> &u32 {
+   |                    ++++                ++             ++
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/self/elision/ref-mut-self.stderr b/src/test/ui/self/elision/ref-mut-self.stderr
index 46d849741eb..416719a08e0 100644
--- a/src/test/ui/self/elision/ref-mut-self.stderr
+++ b/src/test/ui/self/elision/ref-mut-self.stderr
@@ -7,6 +7,12 @@ LL |     fn ref_self(&mut self, f: &u32) -> &u32 {
    |                               this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn ref_self<'a>(&'a mut self, f: &'a u32) -> &u32 {
+   |                ++++  ++               ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-self.rs:17:9
@@ -17,6 +23,12 @@ LL |     fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
    |                                     this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn ref_Self<'a>(self: &'a mut Self, f: &'a u32) -> &u32 {
+   |                ++++        ++               ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-self.rs:21:9
@@ -27,6 +39,12 @@ LL |     fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
    |                                              this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn box_ref_Self<'a>(self: Box<&'a mut Self>, f: &'a u32) -> &u32 {
+   |                    ++++            ++                ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-self.rs:25:9
@@ -37,6 +55,12 @@ LL |     fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
    |                                              this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn pin_ref_Self<'a>(self: Pin<&'a mut Self>, f: &'a u32) -> &u32 {
+   |                    ++++            ++                ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-self.rs:29:9
@@ -47,6 +71,12 @@ LL |     fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
    |                                                       this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn box_box_ref_Self<'a>(self: Box<Box<&'a mut Self>>, f: &'a u32) -> &u32 {
+   |                        ++++                ++                 ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-self.rs:33:9
@@ -57,6 +87,12 @@ LL |     fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
    |                                                       this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn box_pin_ref_Self<'a>(self: Box<Pin<&'a mut Self>>, f: &'a u32) -> &u32 {
+   |                        ++++                ++                 ++
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/self/elision/ref-mut-struct.stderr b/src/test/ui/self/elision/ref-mut-struct.stderr
index c824f2cac98..6ca9ab1b2c7 100644
--- a/src/test/ui/self/elision/ref-mut-struct.stderr
+++ b/src/test/ui/self/elision/ref-mut-struct.stderr
@@ -7,6 +7,12 @@ LL |     fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
    |                                         this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn ref_Struct<'a>(self: &'a mut Struct, f: &'a u32) -> &u32 {
+   |                  ++++        ++                 ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-struct.rs:15:9
@@ -17,6 +23,12 @@ LL |     fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
    |                                                  this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn box_ref_Struct<'a>(self: Box<&'a mut Struct>, f: &'a u32) -> &u32 {
+   |                      ++++            ++                  ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-struct.rs:19:9
@@ -27,6 +39,12 @@ LL |     fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
    |                                                  this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn pin_ref_Struct<'a>(self: Pin<&'a mut Struct>, f: &'a u32) -> &u32 {
+   |                      ++++            ++                  ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-struct.rs:23:9
@@ -37,6 +55,12 @@ LL |     fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
    |                                                           this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn box_box_ref_Struct<'a>(self: Box<Box<&'a mut Struct>>, f: &'a u32) -> &u32 {
+   |                          ++++                ++                   ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-struct.rs:27:9
@@ -47,6 +71,12 @@ LL |     fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
    |                                                           this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn box_pin_ref_Struct<'a>(self: Box<Pin<&'a mut Struct>>, f: &'a u32) -> &u32 {
+   |                          ++++                ++                   ++
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/self/elision/ref-self.stderr b/src/test/ui/self/elision/ref-self.stderr
index 8343c8d349e..955222f7655 100644
--- a/src/test/ui/self/elision/ref-self.stderr
+++ b/src/test/ui/self/elision/ref-self.stderr
@@ -7,6 +7,12 @@ LL |     fn ref_self(&self, f: &u32) -> &u32 {
    |                           this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 {
+   |                ++++  ++           ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-self.rs:27:9
@@ -17,6 +23,12 @@ LL |     fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                                 this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 {
+   |                ++++        ++           ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-self.rs:31:9
@@ -27,6 +39,12 @@ LL |     fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                                          this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &u32 {
+   |                    ++++            ++            ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-self.rs:35:9
@@ -37,6 +55,12 @@ LL |     fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                                          this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &u32 {
+   |                    ++++            ++            ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-self.rs:39:9
@@ -47,6 +71,12 @@ LL |     fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                                   this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn box_box_ref_Self<'a>(self: Box<Box<&'a Self>>, f: &'a u32) -> &u32 {
+   |                        ++++                ++             ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-self.rs:43:9
@@ -57,6 +87,12 @@ LL |     fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                                   this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn box_pin_ref_Self<'a>(self: Box<Pin<&'a Self>>, f: &'a u32) -> &u32 {
+   |                        ++++                ++             ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-self.rs:47:9
@@ -67,6 +103,12 @@ LL |     fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
    |                                                       this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn wrap_ref_Self_Self<'a>(self: Wrap<&'a Self, Self>, f: &'a u8) -> &u8 {
+   |                          ++++             ++                  ++
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/self/elision/ref-struct.stderr b/src/test/ui/self/elision/ref-struct.stderr
index a6967309143..c80993fe8c4 100644
--- a/src/test/ui/self/elision/ref-struct.stderr
+++ b/src/test/ui/self/elision/ref-struct.stderr
@@ -7,6 +7,12 @@ LL |     fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |                                     this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn ref_Struct<'a>(self: &'a Struct, f: &'a u32) -> &u32 {
+   |                  ++++        ++             ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-struct.rs:15:9
@@ -17,6 +23,12 @@ LL |     fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
    |                                              this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn box_ref_Struct<'a>(self: Box<&'a Struct>, f: &'a u32) -> &u32 {
+   |                      ++++            ++              ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-struct.rs:19:9
@@ -27,6 +39,12 @@ LL |     fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
    |                                              this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn pin_ref_Struct<'a>(self: Pin<&'a Struct>, f: &'a u32) -> &u32 {
+   |                      ++++            ++              ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-struct.rs:23:9
@@ -37,6 +55,12 @@ LL |     fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
    |                                                       this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn box_box_ref_Struct<'a>(self: Box<Box<&'a Struct>>, f: &'a u32) -> &u32 {
+   |                          ++++                ++               ++
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-struct.rs:27:9
@@ -47,6 +71,12 @@ LL |     fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
    |                                                   this parameter and the return type are declared with different lifetimes...
 LL |         f
    |         ^ ...but data from `f` is returned here
+   |
+   = note: each elided lifetime in input position becomes a distinct lifetime
+help: consider introducing a named lifetime parameter and update trait if needed
+   |
+LL |     fn box_pin_Struct<'a>(self: Box<Pin<&'a Struct>>, f: &'a u32) -> &u32 {
+   |                      ++++                ++               ++
 
 error: aborting due to 5 previous errors