From abcccc91430a8bd5648c05439855900800daa0f7 Mon Sep 17 00:00:00 2001 From: Fausto Date: Mon, 28 Feb 2022 18:16:19 -0500 Subject: [PATCH 1/3] Suggest adding a new lifetime parameter when two elided lifetimes should match up for traits and impls. Issue #94462 --- .../nice_region_error/different_lifetimes.rs | 100 +++++++++--------- src/test/ui/issues/issue-17728.stderr | 6 ++ ...th-anon-regions-return-type-is-anon.stderr | 6 ++ .../ex3-both-anon-regions-self-is-anon.stderr | 6 ++ ...-both-anon-regions-using-impl-items.stderr | 6 ++ ...ry_self_types_pin_lifetime_mismatch.stderr | 12 +++ src/test/ui/self/elision/lt-ref-self.stderr | 36 +++++++ src/test/ui/self/elision/ref-mut-self.stderr | 36 +++++++ .../ui/self/elision/ref-mut-struct.stderr | 30 ++++++ src/test/ui/self/elision/ref-self.stderr | 42 ++++++++ src/test/ui/self/elision/ref-struct.stderr | 30 ++++++ 11 files changed, 258 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 bbbb0f79acc3e..8022cd01f87b1 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,55 @@ 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 generics = match self.tcx().hir().get(hir_id) { + 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); } + + err.multipart_suggestion( + "consider introducing a named lifetime parameter", + 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 50e3b853fcb1d..943c63667e05f 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 199f880b3c487..86712a726dd4c 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 + | +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 838f43b37747f..0fdf2e8b20e99 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 + | +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 e8b0208f092f7..27bef1d733145 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 + | +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 6bb7ad7cdc7c2..1fc526ed3ae80 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 + | +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 + | +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 f392580d42209..47531dded070e 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 + | +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 + | +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 + | +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 + | +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>, 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 + | +LL | fn box_box_ref_Self<'a>(self: Box>, 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>, 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 + | +LL | fn box_pin_Self<'a>(self: Box>, 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 46d849741ebe3..b16bde55dc730 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 + | +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 + | +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 + | +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 + | +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>, 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 + | +LL | fn box_box_ref_Self<'a>(self: Box>, 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>, 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 + | +LL | fn box_pin_ref_Self<'a>(self: Box>, 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 c824f2cac983e..288203f674b89 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 + | +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 + | +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 + | +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>, 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 + | +LL | fn box_box_ref_Struct<'a>(self: Box>, 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>, 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 + | +LL | fn box_pin_ref_Struct<'a>(self: Box>, 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 8343c8d349e16..3c4abdcd67d1a 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 + | +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 + | +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 + | +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 + | +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>, 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 + | +LL | fn box_box_ref_Self<'a>(self: Box>, 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>, 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 + | +LL | fn box_pin_ref_Self<'a>(self: Box>, 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 + | +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 a69673091431c..eee073d7a14d5 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 + | +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 + | +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 + | +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>, 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 + | +LL | fn box_box_ref_Struct<'a>(self: Box>, 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>, 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 + | +LL | fn box_pin_Struct<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: aborting due to 5 previous errors From 270730f51403f1e134d918fa0ec1312702569e20 Mon Sep 17 00:00:00 2001 From: Fausto Date: Tue, 1 Mar 2022 13:00:02 -0500 Subject: [PATCH 2/3] add suggestion to update trait if error is in impl --- .../nice_region_error/different_lifetimes.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 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 8022cd01f87b1..d7e88d02595e4 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 @@ -167,7 +167,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { 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); - let generics = match self.tcx().hir().get(hir_id) { + 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, ..), .. @@ -209,8 +211,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { 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( - "consider introducing a named lifetime parameter", + sugg.as_str(), suggestions, Applicability::MaybeIncorrect, ); From 1b08cba310c64a4db7398baabd8fd8c0dce01c2e Mon Sep 17 00:00:00 2001 From: Fausto Date: Tue, 1 Mar 2022 13:07:53 -0500 Subject: [PATCH 3/3] update (bless) test results --- ...x3-both-anon-regions-return-type-is-anon.stderr | 2 +- .../ex3-both-anon-regions-self-is-anon.stderr | 2 +- .../ex3-both-anon-regions-using-impl-items.stderr | 2 +- ...bitrary_self_types_pin_lifetime_mismatch.stderr | 4 ++-- src/test/ui/self/elision/lt-ref-self.stderr | 12 ++++++------ src/test/ui/self/elision/ref-mut-self.stderr | 12 ++++++------ src/test/ui/self/elision/ref-mut-struct.stderr | 10 +++++----- src/test/ui/self/elision/ref-self.stderr | 14 +++++++------- src/test/ui/self/elision/ref-struct.stderr | 10 +++++----- 9 files changed, 34 insertions(+), 34 deletions(-) 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 86712a726dd4c..636904aefb47e 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 @@ -9,7 +9,7 @@ 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 +help: consider introducing a named lifetime parameter and update trait if needed | LL | fn foo<'a>(&'a self, x: &'a i32) -> &i32 { | ++ ++ 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 0fdf2e8b20e99..474eadb7f9236 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 @@ -9,7 +9,7 @@ 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 +help: consider introducing a named lifetime parameter and update trait if needed | LL | fn foo<'a>(&'a self, x: &'a Foo) -> &Foo { | ++ ++ 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 27bef1d733145..68893781dc291 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 @@ -7,7 +7,7 @@ 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 +help: consider introducing a named lifetime parameter and update trait if needed | LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { | ++++ ++ ++ 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 1fc526ed3ae80..64a574695105a 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 @@ -7,7 +7,7 @@ LL | fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } | 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 +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 } | ++++ ++ ++ @@ -21,7 +21,7 @@ LL | fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, | 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 +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) } | ++++ ++ ++ diff --git a/src/test/ui/self/elision/lt-ref-self.stderr b/src/test/ui/self/elision/lt-ref-self.stderr index 47531dded070e..5764ab03c5519 100644 --- a/src/test/ui/self/elision/lt-ref-self.stderr +++ b/src/test/ui/self/elision/lt-ref-self.stderr @@ -9,7 +9,7 @@ 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 +help: consider introducing a named lifetime parameter and update trait if needed | LL | fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 { | ++++ ++ ++ @@ -25,7 +25,7 @@ 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 +help: consider introducing a named lifetime parameter and update trait if needed | LL | fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 { | ++++ ++ ++ @@ -41,7 +41,7 @@ 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 +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 { | ++++ ++ ++ @@ -57,7 +57,7 @@ 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 +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 { | ++++ ++ ++ @@ -73,7 +73,7 @@ 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 +help: consider introducing a named lifetime parameter and update trait if needed | LL | fn box_box_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { | ++++ ++ ++ @@ -89,7 +89,7 @@ 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 +help: consider introducing a named lifetime parameter and update trait if needed | LL | fn box_pin_Self<'a>(self: Box>, f: &'a u32) -> &u32 { | ++++ ++ ++ diff --git a/src/test/ui/self/elision/ref-mut-self.stderr b/src/test/ui/self/elision/ref-mut-self.stderr index b16bde55dc730..416719a08e033 100644 --- a/src/test/ui/self/elision/ref-mut-self.stderr +++ b/src/test/ui/self/elision/ref-mut-self.stderr @@ -9,7 +9,7 @@ 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 +help: consider introducing a named lifetime parameter and update trait if needed | LL | fn ref_self<'a>(&'a mut self, f: &'a u32) -> &u32 { | ++++ ++ ++ @@ -25,7 +25,7 @@ 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 +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 { | ++++ ++ ++ @@ -41,7 +41,7 @@ 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 +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 { | ++++ ++ ++ @@ -57,7 +57,7 @@ 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 +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 { | ++++ ++ ++ @@ -73,7 +73,7 @@ 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 +help: consider introducing a named lifetime parameter and update trait if needed | LL | fn box_box_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { | ++++ ++ ++ @@ -89,7 +89,7 @@ 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 +help: consider introducing a named lifetime parameter and update trait if needed | LL | fn box_pin_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { | ++++ ++ ++ diff --git a/src/test/ui/self/elision/ref-mut-struct.stderr b/src/test/ui/self/elision/ref-mut-struct.stderr index 288203f674b89..6ca9ab1b2c775 100644 --- a/src/test/ui/self/elision/ref-mut-struct.stderr +++ b/src/test/ui/self/elision/ref-mut-struct.stderr @@ -9,7 +9,7 @@ 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 +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 { | ++++ ++ ++ @@ -25,7 +25,7 @@ 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 +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 { | ++++ ++ ++ @@ -41,7 +41,7 @@ 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 +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 { | ++++ ++ ++ @@ -57,7 +57,7 @@ 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 +help: consider introducing a named lifetime parameter and update trait if needed | LL | fn box_box_ref_Struct<'a>(self: Box>, f: &'a u32) -> &u32 { | ++++ ++ ++ @@ -73,7 +73,7 @@ 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 +help: consider introducing a named lifetime parameter and update trait if needed | LL | fn box_pin_ref_Struct<'a>(self: Box>, f: &'a u32) -> &u32 { | ++++ ++ ++ diff --git a/src/test/ui/self/elision/ref-self.stderr b/src/test/ui/self/elision/ref-self.stderr index 3c4abdcd67d1a..955222f765599 100644 --- a/src/test/ui/self/elision/ref-self.stderr +++ b/src/test/ui/self/elision/ref-self.stderr @@ -9,7 +9,7 @@ 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 +help: consider introducing a named lifetime parameter and update trait if needed | LL | fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 { | ++++ ++ ++ @@ -25,7 +25,7 @@ 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 +help: consider introducing a named lifetime parameter and update trait if needed | LL | fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 { | ++++ ++ ++ @@ -41,7 +41,7 @@ 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 +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 { | ++++ ++ ++ @@ -57,7 +57,7 @@ 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 +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 { | ++++ ++ ++ @@ -73,7 +73,7 @@ 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 +help: consider introducing a named lifetime parameter and update trait if needed | LL | fn box_box_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { | ++++ ++ ++ @@ -89,7 +89,7 @@ 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 +help: consider introducing a named lifetime parameter and update trait if needed | LL | fn box_pin_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { | ++++ ++ ++ @@ -105,7 +105,7 @@ 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 +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 { | ++++ ++ ++ diff --git a/src/test/ui/self/elision/ref-struct.stderr b/src/test/ui/self/elision/ref-struct.stderr index eee073d7a14d5..c80993fe8c455 100644 --- a/src/test/ui/self/elision/ref-struct.stderr +++ b/src/test/ui/self/elision/ref-struct.stderr @@ -9,7 +9,7 @@ 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 +help: consider introducing a named lifetime parameter and update trait if needed | LL | fn ref_Struct<'a>(self: &'a Struct, f: &'a u32) -> &u32 { | ++++ ++ ++ @@ -25,7 +25,7 @@ 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 +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 { | ++++ ++ ++ @@ -41,7 +41,7 @@ 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 +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 { | ++++ ++ ++ @@ -57,7 +57,7 @@ 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 +help: consider introducing a named lifetime parameter and update trait if needed | LL | fn box_box_ref_Struct<'a>(self: Box>, f: &'a u32) -> &u32 { | ++++ ++ ++ @@ -73,7 +73,7 @@ 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 +help: consider introducing a named lifetime parameter and update trait if needed | LL | fn box_pin_Struct<'a>(self: Box>, f: &'a u32) -> &u32 { | ++++ ++ ++