Skip to content

Commit 53b9afd

Browse files
committed
Tweak suggested lifetimes to modify return type instead of &self receiver
Do not suggest constraining the `&self` param, but rather the return type. If that is wrong (because it is not sufficient), a follow up error will tell the user to fix it. This way we lower the chances of *over* constraining, but still get the cake of "correctly" contrained in two steps. This is a correct suggestion: ``` error: lifetime may not live long enough --> $DIR/ex3-both-anon-regions-return-type-is-anon.rs:9:9 | LL | fn foo<'a>(&self, x: &i32) -> &i32 { | - - let's call the lifetime of this reference `'1` | | | let's call the lifetime of this reference `'2` LL | x | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | LL | fn foo<'a>(&self, x: &'a i32) -> &'a i32 { | ++ ++ ``` While this is incomplete because it should suggestino `&'a self` ``` error: lifetime may not live long enough --> $DIR/ex3-both-anon-regions-self-is-anon.rs:7:19 | LL | fn foo<'a>(&self, x: &Foo) -> &Foo { | - - let's call the lifetime of this reference `'1` | | | let's call the lifetime of this reference `'2` LL | if true { x } else { self } | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | LL | fn foo<'a>(&self, x: &'a Foo) -> &'a Foo { | ++ ++ ``` but the follow up error is ``` error: lifetime may not live long enough --> tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs:7:30 | 6 | fn foo<'a>(&self, x: &'a Foo) -> &'a Foo { | -- - let's call the lifetime of this reference `'1` | | | lifetime `'a` defined here 7 | if true { x } else { self } | ^^^^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | 6 | fn foo<'a>(&'a self, x: &'a Foo) -> &'a Foo { | ++ ```
1 parent 1289cfe commit 53b9afd

18 files changed

+111
-105
lines changed

compiler/rustc_infer/src/errors/mod.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -484,13 +484,19 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> {
484484
suggestions: vec![],
485485
suggestion_param_name: suggestion_param_name.clone(),
486486
};
487-
visitor.visit_ty(self.ty_sub);
488-
visitor.visit_ty(self.ty_sup);
489487
if let Some(fn_decl) = node.fn_decl()
490488
&& let hir::FnRetTy::Return(ty) = fn_decl.output
491489
{
492490
visitor.visit_ty(ty);
493491
}
492+
if visitor.suggestions.is_empty() {
493+
// Do not suggest constraining the `&self` param, but rather the return type.
494+
// If that is wrong (because it is not sufficient), a follow up error will tell the
495+
// user to fix it. This way we lower the chances of *over* constraining, but still
496+
// get the cake of "correctly" contrained in two steps.
497+
visitor.visit_ty(self.ty_sup);
498+
}
499+
visitor.visit_ty(self.ty_sub);
494500
if visitor.suggestions.is_empty() {
495501
return false;
496502
}

tests/ui/lifetimes/issue-17728.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ LL | Some(entry) => Ok(entry),
2929
|
3030
help: consider introducing a named lifetime parameter
3131
|
32-
LL | fn attemptTraverse<'a>(&'a self, room: &'a Room, directionStr: &str) -> Result<&'a Room, &'a str> {
33-
| ++++ ++ ++ ++ ++
32+
LL | fn attemptTraverse<'a>(&self, room: &'a Room, directionStr: &str) -> Result<&'a Room, &'a str> {
33+
| ++++ ++ ++ ++
3434

3535
error: aborting due to 2 previous errors
3636

tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.fixed

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ struct Foo {
55
}
66

77
impl Foo {
8-
fn foo<'a>(&'a self, x: &'a i32) -> &'a i32 {
8+
fn foo<'a>(&self, x: &'a i32) -> &'a i32 {
99
x
1010
//~^ ERROR lifetime may not live long enough
1111
}

tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ LL | x
1010
|
1111
help: consider introducing a named lifetime parameter and update trait if needed
1212
|
13-
LL | fn foo<'a>(&'a self, x: &'a i32) -> &'a i32 {
14-
| ++ ++
13+
LL | fn foo<'a>(&self, x: &'a i32) -> &'a i32 {
14+
| ++
1515

1616
error: aborting due to 1 previous error
1717

tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.fixed

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ struct Foo {
55
}
66

77
impl Foo {
8-
fn foo<'a>(&'a self, x: &'a i32) -> &'a i32 {
8+
fn foo<'a>(&self, x: &'a i32) -> &'a i32 {
99
x
1010
//~^ ERROR lifetime may not live long enough
1111
}

tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ LL | x
1010
|
1111
help: consider introducing a named lifetime parameter and update trait if needed
1212
|
13-
LL | fn foo<'a>(&'a self, x: &'a i32) -> &'a i32 {
14-
| ++ ++ ++
13+
LL | fn foo<'a>(&self, x: &'a i32) -> &'a i32 {
14+
| ++ ++
1515

1616
error: aborting due to 1 previous error
1717

tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ LL | if true { x } else { self }
1010
|
1111
help: consider introducing a named lifetime parameter and update trait if needed
1212
|
13-
LL | fn foo<'a>(&'a self, x: &'a Foo) -> &'a Foo {
14-
| ++ ++ ++
13+
LL | fn foo<'a>(&self, x: &'a Foo) -> &'a Foo {
14+
| ++ ++
1515

1616
error: aborting due to 1 previous error
1717

tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ LL | f
1010
|
1111
help: consider introducing a named lifetime parameter and update trait if needed
1212
|
13-
LL | fn a<'a>(self: Pin<&'a Foo>, f: &'a Foo) -> &'a Foo {
14-
| ++++ ++ ++ ++
13+
LL | fn a<'a>(self: Pin<&Foo>, f: &'a Foo) -> &'a Foo {
14+
| ++++ ++ ++
1515

1616
error: lifetime may not live long enough
1717
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:14:9
@@ -25,8 +25,8 @@ LL | (self, f)
2525
|
2626
help: consider introducing a named lifetime parameter and update trait if needed
2727
|
28-
LL | fn c<'a>(self: Pin<&'a Self>, f: &'a Foo, g: &Foo) -> (Pin<&'a Foo>, &'a Foo) {
29-
| ++++ ++ ++ ++ ++
28+
LL | fn c<'a>(self: Pin<&Self>, f: &'a Foo, g: &Foo) -> (Pin<&'a Foo>, &'a Foo) {
29+
| ++++ ++ ++ ++
3030

3131
error: lifetime may not live long enough
3232
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:21:9
@@ -40,8 +40,8 @@ LL | arg
4040
|
4141
help: consider introducing a named lifetime parameter and update trait if needed
4242
|
43-
LL | fn bar<'a>(self: Alias<&'a Self>, arg: &'a ()) -> &'a () {
44-
| ++ ++
43+
LL | fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &'a () {
44+
| ++
4545

4646
error: aborting due to 3 previous errors
4747

tests/ui/self/elision/lt-ref-self.fixed

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,34 @@ struct Struct<'a> {
1010
impl<'a> Struct<'a> {
1111
// Test using `&self` sugar:
1212

13-
fn ref_self<'b>(&'b self, f: &'b u32) -> &'b u32 {
13+
fn ref_self<'b>(&self, f: &'b u32) -> &'b u32 {
1414
f
1515
//~^ ERROR lifetime may not live long enough
1616
}
1717

1818
// Test using `&Self` explicitly:
1919

20-
fn ref_Self<'b>(self: &'b Self, f: &'b u32) -> &'b u32 {
20+
fn ref_Self<'b>(self: &Self, f: &'b u32) -> &'b u32 {
2121
f
2222
//~^ ERROR lifetime may not live long enough
2323
}
2424

25-
fn box_ref_Self<'b>(self: Box<&'b Self>, f: &'b u32) -> &'b u32 {
25+
fn box_ref_Self<'b>(self: Box<&Self>, f: &'b u32) -> &'b u32 {
2626
f
2727
//~^ ERROR lifetime may not live long enough
2828
}
2929

30-
fn pin_ref_Self<'b>(self: Pin<&'b Self>, f: &'b u32) -> &'b u32 {
30+
fn pin_ref_Self<'b>(self: Pin<&Self>, f: &'b u32) -> &'b u32 {
3131
f
3232
//~^ ERROR lifetime may not live long enough
3333
}
3434

35-
fn box_box_ref_Self<'b>(self: Box<Box<&'b Self>>, f: &'b u32) -> &'b u32 {
35+
fn box_box_ref_Self<'b>(self: Box<Box<&Self>>, f: &'b u32) -> &'b u32 {
3636
f
3737
//~^ ERROR lifetime may not live long enough
3838
}
3939

40-
fn box_pin_Self<'b>(self: Box<Pin<&'b Self>>, f: &'b u32) -> &'b u32 {
40+
fn box_pin_Self<'b>(self: Box<Pin<&Self>>, f: &'b u32) -> &'b u32 {
4141
f
4242
//~^ ERROR lifetime may not live long enough
4343
}

tests/ui/self/elision/lt-ref-self.stderr

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ LL | f
1010
|
1111
help: consider introducing a named lifetime parameter and update trait if needed
1212
|
13-
LL | fn ref_self<'b>(&'b self, f: &'b u32) -> &'b u32 {
14-
| ++++ ++ ++ ++
13+
LL | fn ref_self<'b>(&self, f: &'b u32) -> &'b u32 {
14+
| ++++ ++ ++
1515

1616
error: lifetime may not live long enough
1717
--> $DIR/lt-ref-self.rs:21:9
@@ -25,8 +25,8 @@ LL | f
2525
|
2626
help: consider introducing a named lifetime parameter and update trait if needed
2727
|
28-
LL | fn ref_Self<'b>(self: &'b Self, f: &'b u32) -> &'b u32 {
29-
| ++++ ++ ++ ++
28+
LL | fn ref_Self<'b>(self: &Self, f: &'b u32) -> &'b u32 {
29+
| ++++ ++ ++
3030

3131
error: lifetime may not live long enough
3232
--> $DIR/lt-ref-self.rs:26:9
@@ -40,8 +40,8 @@ LL | f
4040
|
4141
help: consider introducing a named lifetime parameter and update trait if needed
4242
|
43-
LL | fn box_ref_Self<'b>(self: Box<&'b Self>, f: &'b u32) -> &'b u32 {
44-
| ++++ ++ ++ ++
43+
LL | fn box_ref_Self<'b>(self: Box<&Self>, f: &'b u32) -> &'b u32 {
44+
| ++++ ++ ++
4545

4646
error: lifetime may not live long enough
4747
--> $DIR/lt-ref-self.rs:31:9
@@ -55,8 +55,8 @@ LL | f
5555
|
5656
help: consider introducing a named lifetime parameter and update trait if needed
5757
|
58-
LL | fn pin_ref_Self<'b>(self: Pin<&'b Self>, f: &'b u32) -> &'b u32 {
59-
| ++++ ++ ++ ++
58+
LL | fn pin_ref_Self<'b>(self: Pin<&Self>, f: &'b u32) -> &'b u32 {
59+
| ++++ ++ ++
6060

6161
error: lifetime may not live long enough
6262
--> $DIR/lt-ref-self.rs:36:9
@@ -70,8 +70,8 @@ LL | f
7070
|
7171
help: consider introducing a named lifetime parameter and update trait if needed
7272
|
73-
LL | fn box_box_ref_Self<'b>(self: Box<Box<&'b Self>>, f: &'b u32) -> &'b u32 {
74-
| ++++ ++ ++ ++
73+
LL | fn box_box_ref_Self<'b>(self: Box<Box<&Self>>, f: &'b u32) -> &'b u32 {
74+
| ++++ ++ ++
7575

7676
error: lifetime may not live long enough
7777
--> $DIR/lt-ref-self.rs:41:9
@@ -85,8 +85,8 @@ LL | f
8585
|
8686
help: consider introducing a named lifetime parameter and update trait if needed
8787
|
88-
LL | fn box_pin_Self<'b>(self: Box<Pin<&'b Self>>, f: &'b u32) -> &'b u32 {
89-
| ++++ ++ ++ ++
88+
LL | fn box_pin_Self<'b>(self: Box<Pin<&Self>>, f: &'b u32) -> &'b u32 {
89+
| ++++ ++ ++
9090

9191
error: aborting due to 6 previous errors
9292

tests/ui/self/elision/ref-mut-self.fixed

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,34 @@ struct Struct {}
88
impl Struct {
99
// Test using `&mut self` sugar:
1010

11-
fn ref_self<'a>(&'a mut self, f: &'a u32) -> &'a u32 {
11+
fn ref_self<'a>(&mut self, f: &'a u32) -> &'a u32 {
1212
f
1313
//~^ ERROR lifetime may not live long enough
1414
}
1515

1616
// Test using `&mut Self` explicitly:
1717

18-
fn ref_Self<'a>(self: &'a mut Self, f: &'a u32) -> &'a u32 {
18+
fn ref_Self<'a>(self: &mut Self, f: &'a u32) -> &'a u32 {
1919
f
2020
//~^ ERROR lifetime may not live long enough
2121
}
2222

23-
fn box_ref_Self<'a>(self: Box<&'a mut Self>, f: &'a u32) -> &'a u32 {
23+
fn box_ref_Self<'a>(self: Box<&mut Self>, f: &'a u32) -> &'a u32 {
2424
f
2525
//~^ ERROR lifetime may not live long enough
2626
}
2727

28-
fn pin_ref_Self<'a>(self: Pin<&'a mut Self>, f: &'a u32) -> &'a u32 {
28+
fn pin_ref_Self<'a>(self: Pin<&mut Self>, f: &'a u32) -> &'a u32 {
2929
f
3030
//~^ ERROR lifetime may not live long enough
3131
}
3232

33-
fn box_box_ref_Self<'a>(self: Box<Box<&'a mut Self>>, f: &'a u32) -> &'a u32 {
33+
fn box_box_ref_Self<'a>(self: Box<Box<&mut Self>>, f: &'a u32) -> &'a u32 {
3434
f
3535
//~^ ERROR lifetime may not live long enough
3636
}
3737

38-
fn box_pin_ref_Self<'a>(self: Box<Pin<&'a mut Self>>, f: &'a u32) -> &'a u32 {
38+
fn box_pin_ref_Self<'a>(self: Box<Pin<&mut Self>>, f: &'a u32) -> &'a u32 {
3939
f
4040
//~^ ERROR lifetime may not live long enough
4141
}

tests/ui/self/elision/ref-mut-self.stderr

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ LL | f
1010
|
1111
help: consider introducing a named lifetime parameter and update trait if needed
1212
|
13-
LL | fn ref_self<'a>(&'a mut self, f: &'a u32) -> &'a u32 {
14-
| ++++ ++ ++ ++
13+
LL | fn ref_self<'a>(&mut self, f: &'a u32) -> &'a u32 {
14+
| ++++ ++ ++
1515

1616
error: lifetime may not live long enough
1717
--> $DIR/ref-mut-self.rs:19:9
@@ -25,8 +25,8 @@ LL | f
2525
|
2626
help: consider introducing a named lifetime parameter and update trait if needed
2727
|
28-
LL | fn ref_Self<'a>(self: &'a mut Self, f: &'a u32) -> &'a u32 {
29-
| ++++ ++ ++ ++
28+
LL | fn ref_Self<'a>(self: &mut Self, f: &'a u32) -> &'a u32 {
29+
| ++++ ++ ++
3030

3131
error: lifetime may not live long enough
3232
--> $DIR/ref-mut-self.rs:24:9
@@ -40,8 +40,8 @@ LL | f
4040
|
4141
help: consider introducing a named lifetime parameter and update trait if needed
4242
|
43-
LL | fn box_ref_Self<'a>(self: Box<&'a mut Self>, f: &'a u32) -> &'a u32 {
44-
| ++++ ++ ++ ++
43+
LL | fn box_ref_Self<'a>(self: Box<&mut Self>, f: &'a u32) -> &'a u32 {
44+
| ++++ ++ ++
4545

4646
error: lifetime may not live long enough
4747
--> $DIR/ref-mut-self.rs:29:9
@@ -55,8 +55,8 @@ LL | f
5555
|
5656
help: consider introducing a named lifetime parameter and update trait if needed
5757
|
58-
LL | fn pin_ref_Self<'a>(self: Pin<&'a mut Self>, f: &'a u32) -> &'a u32 {
59-
| ++++ ++ ++ ++
58+
LL | fn pin_ref_Self<'a>(self: Pin<&mut Self>, f: &'a u32) -> &'a u32 {
59+
| ++++ ++ ++
6060

6161
error: lifetime may not live long enough
6262
--> $DIR/ref-mut-self.rs:34:9
@@ -70,8 +70,8 @@ LL | f
7070
|
7171
help: consider introducing a named lifetime parameter and update trait if needed
7272
|
73-
LL | fn box_box_ref_Self<'a>(self: Box<Box<&'a mut Self>>, f: &'a u32) -> &'a u32 {
74-
| ++++ ++ ++ ++
73+
LL | fn box_box_ref_Self<'a>(self: Box<Box<&mut Self>>, f: &'a u32) -> &'a u32 {
74+
| ++++ ++ ++
7575

7676
error: lifetime may not live long enough
7777
--> $DIR/ref-mut-self.rs:39:9
@@ -85,8 +85,8 @@ LL | f
8585
|
8686
help: consider introducing a named lifetime parameter and update trait if needed
8787
|
88-
LL | fn box_pin_ref_Self<'a>(self: Box<Pin<&'a mut Self>>, f: &'a u32) -> &'a u32 {
89-
| ++++ ++ ++ ++
88+
LL | fn box_pin_ref_Self<'a>(self: Box<Pin<&mut Self>>, f: &'a u32) -> &'a u32 {
89+
| ++++ ++ ++
9090

9191
error: aborting due to 6 previous errors
9292

tests/ui/self/elision/ref-mut-struct.fixed

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,27 @@ struct Struct {}
88
impl Struct {
99
// Test using `&mut Struct` explicitly:
1010

11-
fn ref_Struct<'a>(self: &'a mut Struct, f: &'a u32) -> &'a u32 {
11+
fn ref_Struct<'a>(self: &mut Struct, f: &'a u32) -> &'a u32 {
1212
f
1313
//~^ ERROR lifetime may not live long enough
1414
}
1515

16-
fn box_ref_Struct<'a>(self: Box<&'a mut Struct>, f: &'a u32) -> &'a u32 {
16+
fn box_ref_Struct<'a>(self: Box<&mut Struct>, f: &'a u32) -> &'a u32 {
1717
f
1818
//~^ ERROR lifetime may not live long enough
1919
}
2020

21-
fn pin_ref_Struct<'a>(self: Pin<&'a mut Struct>, f: &'a u32) -> &'a u32 {
21+
fn pin_ref_Struct<'a>(self: Pin<&mut Struct>, f: &'a u32) -> &'a u32 {
2222
f
2323
//~^ ERROR lifetime may not live long enough
2424
}
2525

26-
fn box_box_ref_Struct<'a>(self: Box<Box<&'a mut Struct>>, f: &'a u32) -> &'a u32 {
26+
fn box_box_ref_Struct<'a>(self: Box<Box<&mut Struct>>, f: &'a u32) -> &'a u32 {
2727
f
2828
//~^ ERROR lifetime may not live long enough
2929
}
3030

31-
fn box_pin_ref_Struct<'a>(self: Box<Pin<&'a mut Struct>>, f: &'a u32) -> &'a u32 {
31+
fn box_pin_ref_Struct<'a>(self: Box<Pin<&mut Struct>>, f: &'a u32) -> &'a u32 {
3232
f
3333
//~^ ERROR lifetime may not live long enough
3434
}

0 commit comments

Comments
 (0)