From 120049fab4e293c19fa1c5a09d68f89bcd940b36 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Sun, 5 May 2024 03:42:47 +0000 Subject: Always constrain the return type in lifetime suggestion ``` error: lifetime may not live long enough --> f205.rs:8:16 | 7 | fn resolve_symbolic_reference(&self, reference: Option) -> Option { | - --------- has type `Option>` | | | let's call the lifetime of this reference `'2` 8 | return reference; | ^^^^^^^^^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter | 7 | fn resolve_symbolic_reference<'a>(&'a self, reference: Option>) -> Option> { | ++++ ++ ++++ ++++ ``` The correct suggestion would be ``` help: consider introducing a named lifetime parameter | 7 | fn resolve_symbolic_reference<'a>(&self, reference: Option>) -> Option> { | ++++ ++++ ++++ ``` but we are not doing the analysis to detect that yet. If we constrain `&'a self`, then the return type with a borrow will implicitly take its lifetime from `'a`, it is better to make it explicit in the suggestion, in case that `&self` *doesn't* need to be `'a`, but the return does. --- compiler/rustc_infer/src/errors/mod.rs | 5 ++++ tests/ui/lifetimes/issue-17728.stderr | 4 ++-- ...rn-one-existing-name-return-type-is-anon.stderr | 4 ++-- ...x3-both-anon-regions-return-type-is-anon.stderr | 4 ++-- .../ex3-both-anon-regions-self-is-anon.stderr | 4 ++-- ...bitrary_self_types_pin_lifetime_mismatch.stderr | 12 +++++----- tests/ui/self/elision/lt-ref-self.stderr | 24 +++++++++---------- tests/ui/self/elision/ref-mut-self.stderr | 24 +++++++++---------- tests/ui/self/elision/ref-mut-struct.stderr | 20 ++++++++-------- tests/ui/self/elision/ref-self.stderr | 28 +++++++++++----------- tests/ui/self/elision/ref-struct.stderr | 20 ++++++++-------- 11 files changed, 77 insertions(+), 72 deletions(-) diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 03947239896..4db79af10a5 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -450,6 +450,11 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> { }; visitor.visit_ty(self.ty_sub); visitor.visit_ty(self.ty_sup); + if let Some(fn_decl) = node.fn_decl() + && let hir::FnRetTy::Return(ty) = fn_decl.output + { + visitor.visit_ty(ty); + } if visitor.suggestions.is_empty() { return false; } diff --git a/tests/ui/lifetimes/issue-17728.stderr b/tests/ui/lifetimes/issue-17728.stderr index 23547f722a1..da4ce2dd291 100644 --- a/tests/ui/lifetimes/issue-17728.stderr +++ b/tests/ui/lifetimes/issue-17728.stderr @@ -29,8 +29,8 @@ LL | Some(entry) => Ok(entry), | help: consider introducing a named lifetime parameter | -LL | fn attemptTraverse<'a>(&'a self, room: &'a Room, directionStr: &str) -> Result<&Room, &str> { - | ++++ ++ ++ +LL | fn attemptTraverse<'a>(&'a self, room: &'a Room, directionStr: &str) -> Result<&'a Room, &'a str> { + | ++++ ++ ++ ++ ++ error: aborting due to 2 previous errors diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr index cdcdc0c07e3..5cfa5717224 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr @@ -11,8 +11,8 @@ LL | x | help: consider introducing a named lifetime parameter and update trait if needed | -LL | fn foo<'a>(&'a self, x: &'a i32) -> &i32 { - | ++ +LL | fn foo<'a>(&'a self, x: &'a i32) -> &'a i32 { + | ++ ++ error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr index e934ce7c040..fd15d516999 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr @@ -10,8 +10,8 @@ LL | x | help: consider introducing a named lifetime parameter and update trait if needed | -LL | fn foo<'a>(&'a self, x: &'a i32) -> &i32 { - | ++ ++ +LL | fn foo<'a>(&'a self, x: &'a i32) -> &'a i32 { + | ++ ++ ++ error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr index dde271d100c..0a312cf93c8 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr @@ -10,8 +10,8 @@ LL | if true { x } else { self } | help: consider introducing a named lifetime parameter and update trait if needed | -LL | fn foo<'a>(&'a self, x: &'a Foo) -> &Foo { - | ++ ++ +LL | fn foo<'a>(&'a self, x: &'a Foo) -> &'a Foo { + | ++ ++ ++ error: aborting due to 1 previous error diff --git a/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr b/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr index bbb2ef4641e..3e2bbd37f33 100644 --- a/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr +++ b/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr @@ -9,8 +9,8 @@ LL | fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } | 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 } - | ++++ ++ ++ +LL | fn a<'a>(self: Pin<&'a Foo>, f: &'a Foo) -> &'a Foo { f } + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:9:69 @@ -23,8 +23,8 @@ LL | fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, | 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) } - | ++++ ++ ++ +LL | fn c<'a>(self: Pin<&'a Self>, f: &'a Foo, g: &Foo) -> (Pin<&'a Foo>, &'a Foo) { (self, f) } + | ++++ ++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:15:58 @@ -36,8 +36,8 @@ LL | fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } | help: consider introducing a named lifetime parameter and update trait if needed | -LL | fn bar<'a>(self: Alias<&'a Self>, arg: &'a ()) -> &() { arg } - | ++ +LL | fn bar<'a>(self: Alias<&'a Self>, arg: &'a ()) -> &'a () { arg } + | ++ ++ error: aborting due to 3 previous errors diff --git a/tests/ui/self/elision/lt-ref-self.stderr b/tests/ui/self/elision/lt-ref-self.stderr index 216737a2c73..5eaaa7698b6 100644 --- a/tests/ui/self/elision/lt-ref-self.stderr +++ b/tests/ui/self/elision/lt-ref-self.stderr @@ -10,8 +10,8 @@ LL | f | help: consider introducing a named lifetime parameter and update trait if needed | -LL | fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 { - | ++++ ++ ++ +LL | fn ref_self<'a>(&'a self, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:18:9 @@ -25,8 +25,8 @@ LL | f | help: consider introducing a named lifetime parameter and update trait if needed | -LL | fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 { - | ++++ ++ ++ +LL | fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:23:9 @@ -40,8 +40,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:28:9 @@ -55,8 +55,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:33:9 @@ -70,8 +70,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn box_box_ref_Self<'a>(self: Box>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:38:9 @@ -85,8 +85,8 @@ LL | f | help: consider introducing a named lifetime parameter and update trait if needed | -LL | fn box_pin_Self<'a>(self: Box>, f: &'a u32) -> &u32 { - | ++++ ++ ++ +LL | fn box_pin_Self<'a>(self: Box>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: aborting due to 6 previous errors diff --git a/tests/ui/self/elision/ref-mut-self.stderr b/tests/ui/self/elision/ref-mut-self.stderr index 12b64a3f6dc..8fea05e493d 100644 --- a/tests/ui/self/elision/ref-mut-self.stderr +++ b/tests/ui/self/elision/ref-mut-self.stderr @@ -10,8 +10,8 @@ LL | f | help: consider introducing a named lifetime parameter and update trait if needed | -LL | fn ref_self<'a>(&'a mut self, f: &'a u32) -> &u32 { - | ++++ ++ ++ +LL | fn ref_self<'a>(&'a mut self, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:18:9 @@ -25,8 +25,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn ref_Self<'a>(self: &'a mut Self, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:23:9 @@ -40,8 +40,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn box_ref_Self<'a>(self: Box<&'a mut Self>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:28:9 @@ -55,8 +55,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn pin_ref_Self<'a>(self: Pin<&'a mut Self>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:33:9 @@ -70,8 +70,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn box_box_ref_Self<'a>(self: Box>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:38:9 @@ -85,8 +85,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn box_pin_ref_Self<'a>(self: Box>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: aborting due to 6 previous errors diff --git a/tests/ui/self/elision/ref-mut-struct.stderr b/tests/ui/self/elision/ref-mut-struct.stderr index cde16ce8ba4..26dcfcb6dd0 100644 --- a/tests/ui/self/elision/ref-mut-struct.stderr +++ b/tests/ui/self/elision/ref-mut-struct.stderr @@ -10,8 +10,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn ref_Struct<'a>(self: &'a mut Struct, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-struct.rs:16:9 @@ -25,8 +25,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn box_ref_Struct<'a>(self: Box<&'a mut Struct>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-struct.rs:21:9 @@ -40,8 +40,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn pin_ref_Struct<'a>(self: Pin<&'a mut Struct>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-struct.rs:26:9 @@ -55,8 +55,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn box_box_ref_Struct<'a>(self: Box>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-struct.rs:31:9 @@ -70,8 +70,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn box_pin_ref_Struct<'a>(self: Box>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: aborting due to 5 previous errors diff --git a/tests/ui/self/elision/ref-self.stderr b/tests/ui/self/elision/ref-self.stderr index 35693257c99..8654032b047 100644 --- a/tests/ui/self/elision/ref-self.stderr +++ b/tests/ui/self/elision/ref-self.stderr @@ -10,8 +10,8 @@ LL | f | help: consider introducing a named lifetime parameter and update trait if needed | -LL | fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 { - | ++++ ++ ++ +LL | fn ref_self<'a>(&'a self, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self.rs:28:9 @@ -25,8 +25,8 @@ LL | f | help: consider introducing a named lifetime parameter and update trait if needed | -LL | fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 { - | ++++ ++ ++ +LL | fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self.rs:33:9 @@ -40,8 +40,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self.rs:38:9 @@ -55,8 +55,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self.rs:43:9 @@ -70,8 +70,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn box_box_ref_Self<'a>(self: Box>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self.rs:48:9 @@ -85,8 +85,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn box_pin_ref_Self<'a>(self: Box>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self.rs:53:9 @@ -100,8 +100,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn wrap_ref_Self_Self<'a>(self: Wrap<&'a Self, Self>, f: &'a u8) -> &'a u8 { + | ++++ ++ ++ ++ error: aborting due to 7 previous errors diff --git a/tests/ui/self/elision/ref-struct.stderr b/tests/ui/self/elision/ref-struct.stderr index a3d3cebeba9..653ecc612d5 100644 --- a/tests/ui/self/elision/ref-struct.stderr +++ b/tests/ui/self/elision/ref-struct.stderr @@ -10,8 +10,8 @@ LL | f | help: consider introducing a named lifetime parameter and update trait if needed | -LL | fn ref_Struct<'a>(self: &'a Struct, f: &'a u32) -> &u32 { - | ++++ ++ ++ +LL | fn ref_Struct<'a>(self: &'a Struct, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-struct.rs:16:9 @@ -25,8 +25,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn box_ref_Struct<'a>(self: Box<&'a Struct>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-struct.rs:21:9 @@ -40,8 +40,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn pin_ref_Struct<'a>(self: Pin<&'a Struct>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-struct.rs:26:9 @@ -55,8 +55,8 @@ LL | f | 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 { - | ++++ ++ ++ +LL | fn box_box_ref_Struct<'a>(self: Box>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-struct.rs:31:9 @@ -70,8 +70,8 @@ LL | f | help: consider introducing a named lifetime parameter and update trait if needed | -LL | fn box_pin_Struct<'a>(self: Box>, f: &'a u32) -> &u32 { - | ++++ ++ ++ +LL | fn box_pin_Struct<'a>(self: Box>, f: &'a u32) -> &'a u32 { + | ++++ ++ ++ ++ error: aborting due to 5 previous errors -- cgit 1.4.1-3-g733a5