Skip to content

Commit e62599f

Browse files
committed
Do not elide if there's ambiguity in self lifetime.
This makes a small change as requested in code review, such that if there's ambiguity in the self lifetime, we avoid lifetime elision entirely instead of considering using lifetimes from any of the other parameters. For example, impl Something { fn method(self: &Box<&Self>, something_else: &u32) -> &u32 { ... } } in standard Rust would have assumed the return lifetime was that of &Self; with this PR prior to this commit would have chosen the lifetime of 'something_else', and after this commit would give an error message explaining that the lifetime is ambiguous.
1 parent 8d1958f commit e62599f

File tree

7 files changed

+169
-7
lines changed

7 files changed

+169
-7
lines changed

compiler/rustc_resolve/src/late.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -2136,8 +2136,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
21362136
// We found `self` elision.
21372137
Set1::One(lifetime) => Elision::Self_(lifetime),
21382138
// `self` itself had ambiguous lifetimes, e.g.
2139-
// &Box<&Self>
2140-
Set1::Many => Elision::None,
2139+
// &Box<&Self>. In this case we won't consider
2140+
// taking an alternative parameter lifetime; just avoid elision
2141+
// entirely.
2142+
Set1::Many => Elision::Err,
21412143
// We do not have `self` elision: disregard the `Elision::Param` that we may
21422144
// have found.
21432145
Set1::Empty => Elision::None,

tests/ui/self/elision/multiple-ref-self-async.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
//@ check-pass
21
//@ edition:2018
32

43
#![feature(arbitrary_self_types)]
@@ -21,22 +20,27 @@ impl Struct {
2120
// Test using multiple `&Self`:
2221

2322
async fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 {
23+
//~^ ERROR missing lifetime specifier
2424
f
2525
}
2626

2727
async fn box_wrap_ref_Self_ref_Self(self: Box<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
28+
//~^ ERROR missing lifetime specifier
2829
f
2930
}
3031

3132
async fn pin_wrap_ref_Self_ref_Self(self: Pin<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
33+
//~^ ERROR missing lifetime specifier
3234
f
3335
}
3436

3537
async fn box_box_wrap_ref_Self_ref_Self(self: Box<Box<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
38+
//~^ ERROR missing lifetime specifier
3639
f
3740
}
3841

3942
async fn box_pin_wrap_ref_Self_ref_Self(self: Box<Pin<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
43+
//~^ ERROR missing lifetime specifier
4044
f
4145
}
4246
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
error[E0106]: missing lifetime specifier
2+
--> $DIR/multiple-ref-self-async.rs:22:74
3+
|
4+
LL | async fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 {
5+
| ------------------ --- ^ expected named lifetime parameter
6+
|
7+
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `self`'s 2 lifetimes or `f`
8+
help: consider introducing a named lifetime parameter
9+
|
10+
LL | async fn wrap_ref_Self_ref_Self<'a>(self: Wrap<&'a Self, &'a Self>, f: &'a u8) -> &'a u8 {
11+
| ++++ ++ ++ ++ ++
12+
13+
error[E0106]: missing lifetime specifier
14+
--> $DIR/multiple-ref-self-async.rs:27:84
15+
|
16+
LL | async fn box_wrap_ref_Self_ref_Self(self: Box<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
17+
| ----------------------- ---- ^ expected named lifetime parameter
18+
|
19+
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `self`'s 2 lifetimes or `f`
20+
help: consider introducing a named lifetime parameter
21+
|
22+
LL | async fn box_wrap_ref_Self_ref_Self<'a>(self: Box<Wrap<&'a Self, &'a Self>>, f: &'a u32) -> &'a u32 {
23+
| ++++ ++ ++ ++ ++
24+
25+
error[E0106]: missing lifetime specifier
26+
--> $DIR/multiple-ref-self-async.rs:32:84
27+
|
28+
LL | async fn pin_wrap_ref_Self_ref_Self(self: Pin<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
29+
| ----------------------- ---- ^ expected named lifetime parameter
30+
|
31+
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `self`'s 2 lifetimes or `f`
32+
help: consider introducing a named lifetime parameter
33+
|
34+
LL | async fn pin_wrap_ref_Self_ref_Self<'a>(self: Pin<Wrap<&'a Self, &'a Self>>, f: &'a u32) -> &'a u32 {
35+
| ++++ ++ ++ ++ ++
36+
37+
error[E0106]: missing lifetime specifier
38+
--> $DIR/multiple-ref-self-async.rs:37:93
39+
|
40+
LL | async fn box_box_wrap_ref_Self_ref_Self(self: Box<Box<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
41+
| ---------------------------- ---- ^ expected named lifetime parameter
42+
|
43+
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `self`'s 2 lifetimes or `f`
44+
help: consider introducing a named lifetime parameter
45+
|
46+
LL | async fn box_box_wrap_ref_Self_ref_Self<'a>(self: Box<Box<Wrap<&'a Self, &'a Self>>>, f: &'a u32) -> &'a u32 {
47+
| ++++ ++ ++ ++ ++
48+
49+
error[E0106]: missing lifetime specifier
50+
--> $DIR/multiple-ref-self-async.rs:42:93
51+
|
52+
LL | async fn box_pin_wrap_ref_Self_ref_Self(self: Box<Pin<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
53+
| ---------------------------- ---- ^ expected named lifetime parameter
54+
|
55+
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `self`'s 2 lifetimes or `f`
56+
help: consider introducing a named lifetime parameter
57+
|
58+
LL | async fn box_pin_wrap_ref_Self_ref_Self<'a>(self: Box<Pin<Wrap<&'a Self, &'a Self>>>, f: &'a u32) -> &'a u32 {
59+
| ++++ ++ ++ ++ ++
60+
61+
error: aborting due to 5 previous errors
62+
63+
For more information about this error, try `rustc --explain E0106`.

tests/ui/self/elision/multiple-ref-self.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//@ check-pass
2-
31
#![feature(arbitrary_self_types)]
42
#![allow(non_snake_case)]
53

@@ -20,22 +18,27 @@ impl Struct {
2018
// Test using multiple `&Self`:
2119

2220
fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 {
21+
//~^ ERROR missing lifetime specifier
2322
f
2423
}
2524

2625
fn box_wrap_ref_Self_ref_Self(self: Box<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
26+
//~^ ERROR missing lifetime specifier
2727
f
2828
}
2929

3030
fn pin_wrap_ref_Self_ref_Self(self: Pin<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
31+
//~^ ERROR missing lifetime specifier
3132
f
3233
}
3334

3435
fn box_box_wrap_ref_Self_ref_Self(self: Box<Box<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
36+
//~^ ERROR missing lifetime specifier
3537
f
3638
}
3739

3840
fn box_pin_wrap_ref_Self_ref_Self(self: Box<Pin<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
41+
//~^ ERROR missing lifetime specifier
3942
f
4043
}
4144
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
error[E0106]: missing lifetime specifier
2+
--> $DIR/multiple-ref-self.rs:20:68
3+
|
4+
LL | fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 {
5+
| ------------------ --- ^ expected named lifetime parameter
6+
|
7+
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `self`'s 2 lifetimes or `f`
8+
help: consider introducing a named lifetime parameter
9+
|
10+
LL | fn wrap_ref_Self_ref_Self<'a>(self: Wrap<&'a Self, &'a Self>, f: &'a u8) -> &'a u8 {
11+
| ++++ ++ ++ ++ ++
12+
13+
error[E0106]: missing lifetime specifier
14+
--> $DIR/multiple-ref-self.rs:25:78
15+
|
16+
LL | fn box_wrap_ref_Self_ref_Self(self: Box<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
17+
| ----------------------- ---- ^ expected named lifetime parameter
18+
|
19+
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `self`'s 2 lifetimes or `f`
20+
help: consider introducing a named lifetime parameter
21+
|
22+
LL | fn box_wrap_ref_Self_ref_Self<'a>(self: Box<Wrap<&'a Self, &'a Self>>, f: &'a u32) -> &'a u32 {
23+
| ++++ ++ ++ ++ ++
24+
25+
error[E0106]: missing lifetime specifier
26+
--> $DIR/multiple-ref-self.rs:30:78
27+
|
28+
LL | fn pin_wrap_ref_Self_ref_Self(self: Pin<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
29+
| ----------------------- ---- ^ expected named lifetime parameter
30+
|
31+
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `self`'s 2 lifetimes or `f`
32+
help: consider introducing a named lifetime parameter
33+
|
34+
LL | fn pin_wrap_ref_Self_ref_Self<'a>(self: Pin<Wrap<&'a Self, &'a Self>>, f: &'a u32) -> &'a u32 {
35+
| ++++ ++ ++ ++ ++
36+
37+
error[E0106]: missing lifetime specifier
38+
--> $DIR/multiple-ref-self.rs:35:87
39+
|
40+
LL | fn box_box_wrap_ref_Self_ref_Self(self: Box<Box<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
41+
| ---------------------------- ---- ^ expected named lifetime parameter
42+
|
43+
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `self`'s 2 lifetimes or `f`
44+
help: consider introducing a named lifetime parameter
45+
|
46+
LL | fn box_box_wrap_ref_Self_ref_Self<'a>(self: Box<Box<Wrap<&'a Self, &'a Self>>>, f: &'a u32) -> &'a u32 {
47+
| ++++ ++ ++ ++ ++
48+
49+
error[E0106]: missing lifetime specifier
50+
--> $DIR/multiple-ref-self.rs:40:87
51+
|
52+
LL | fn box_pin_wrap_ref_Self_ref_Self(self: Box<Pin<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
53+
| ---------------------------- ---- ^ expected named lifetime parameter
54+
|
55+
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `self`'s 2 lifetimes or `f`
56+
help: consider introducing a named lifetime parameter
57+
|
58+
LL | fn box_pin_wrap_ref_Self_ref_Self<'a>(self: Box<Pin<Wrap<&'a Self, &'a Self>>>, f: &'a u32) -> &'a u32 {
59+
| ++++ ++ ++ ++ ++
60+
61+
error: aborting due to 5 previous errors
62+
63+
For more information about this error, try `rustc --explain E0106`.

tests/ui/self/elision/ref-self-multi.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//@ run-pass
2-
31
#![feature(arbitrary_self_types)]
42
#![allow(non_snake_case)]
53
#![allow(unused)]
@@ -18,10 +16,12 @@ impl<T, P> Deref for Wrap<T, P> {
1816

1917
impl Struct {
2018
fn ref_box_ref_Self(self: &Box<&Self>, f: &u32) -> &u32 {
19+
//~^ ERROR missing lifetime specifier
2120
f
2221
}
2322

2423
fn ref_wrap_ref_Self(self: &Wrap<&Self, u32>, f: &u32) -> &u32 {
24+
//~^ ERROR missing lifetime specifier
2525
f
2626
}
2727
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error[E0106]: missing lifetime specifier
2+
--> $DIR/ref-self-multi.rs:18:56
3+
|
4+
LL | fn ref_box_ref_Self(self: &Box<&Self>, f: &u32) -> &u32 {
5+
| ----------- ---- ^ expected named lifetime parameter
6+
|
7+
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `self`'s 2 lifetimes or `f`
8+
help: consider introducing a named lifetime parameter
9+
|
10+
LL | fn ref_box_ref_Self<'a>(self: &'a Box<&'a Self>, f: &'a u32) -> &'a u32 {
11+
| ++++ ++ ++ ++ ++
12+
13+
error[E0106]: missing lifetime specifier
14+
--> $DIR/ref-self-multi.rs:23:63
15+
|
16+
LL | fn ref_wrap_ref_Self(self: &Wrap<&Self, u32>, f: &u32) -> &u32 {
17+
| ----------------- ---- ^ expected named lifetime parameter
18+
|
19+
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `self`'s 2 lifetimes or `f`
20+
help: consider introducing a named lifetime parameter
21+
|
22+
LL | fn ref_wrap_ref_Self<'a>(self: &'a Wrap<&'a Self, u32>, f: &'a u32) -> &'a u32 {
23+
| ++++ ++ ++ ++ ++
24+
25+
error: aborting due to 2 previous errors
26+
27+
For more information about this error, try `rustc --explain E0106`.

0 commit comments

Comments
 (0)