Skip to content

Commit c46b820

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 15ce755 commit c46b820

File tree

7 files changed

+219
-7
lines changed

7 files changed

+219
-7
lines changed

compiler/rustc_resolve/src/late.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -2094,8 +2094,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
20942094
// We found `self` elision.
20952095
Set1::One(lifetime) => Elision::Self_(lifetime),
20962096
// `self` itself had ambiguous lifetimes, e.g.
2097-
// &Box<&Self>
2098-
Set1::Many => Elision::None,
2097+
// &Box<&Self>. In this case we won't consider
2098+
// taking an alternative parameter lifetime; just avoid elision
2099+
// entirely.
2100+
Set1::Many => Elision::Err,
20992101
// We do not have `self` elision: disregard the `Elision::Param` that we may
21002102
// have found.
21012103
Set1::Empty => Elision::None,

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

+10-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,23 +20,33 @@ 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
25+
//~^ ERROR lifetime may not live long enough
2526
}
2627

2728
async fn box_wrap_ref_Self_ref_Self(self: Box<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
29+
//~^ ERROR missing lifetime specifier
2830
f
31+
//~^ ERROR lifetime may not live long enough
2932
}
3033

3134
async fn pin_wrap_ref_Self_ref_Self(self: Pin<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
35+
//~^ ERROR missing lifetime specifier
3236
f
37+
//~^ ERROR lifetime may not live long enough
3338
}
3439

3540
async fn box_box_wrap_ref_Self_ref_Self(self: Box<Box<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
41+
//~^ ERROR missing lifetime specifier
3642
f
43+
//~^ ERROR lifetime may not live long enough
3744
}
3845

3946
async fn box_pin_wrap_ref_Self_ref_Self(self: Box<Pin<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
47+
//~^ ERROR missing lifetime specifier
4048
f
49+
//~^ ERROR lifetime may not live long enough
4150
}
4251
}
4352

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
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:28: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:34: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:40: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:46: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: lifetime may not live long enough
62+
--> $DIR/multiple-ref-self-async.rs:24:9
63+
|
64+
LL | async fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 {
65+
| - let's call the lifetime of this reference `'1`
66+
LL |
67+
LL | f
68+
| ^ returning this value requires that `'1` must outlive `'static`
69+
70+
error: lifetime may not live long enough
71+
--> $DIR/multiple-ref-self-async.rs:30:9
72+
|
73+
LL | async fn box_wrap_ref_Self_ref_Self(self: Box<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
74+
| - let's call the lifetime of this reference `'1`
75+
LL |
76+
LL | f
77+
| ^ returning this value requires that `'1` must outlive `'static`
78+
79+
error: lifetime may not live long enough
80+
--> $DIR/multiple-ref-self-async.rs:36:9
81+
|
82+
LL | async fn pin_wrap_ref_Self_ref_Self(self: Pin<Wrap<&Self, &Self>>, f: &u32) -> &u32 {
83+
| - let's call the lifetime of this reference `'1`
84+
LL |
85+
LL | f
86+
| ^ returning this value requires that `'1` must outlive `'static`
87+
88+
error: lifetime may not live long enough
89+
--> $DIR/multiple-ref-self-async.rs:42:9
90+
|
91+
LL | async fn box_box_wrap_ref_Self_ref_Self(self: Box<Box<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
92+
| - let's call the lifetime of this reference `'1`
93+
LL |
94+
LL | f
95+
| ^ returning this value requires that `'1` must outlive `'static`
96+
97+
error: lifetime may not live long enough
98+
--> $DIR/multiple-ref-self-async.rs:48:9
99+
|
100+
LL | async fn box_pin_wrap_ref_Self_ref_Self(self: Box<Pin<Wrap<&Self, &Self>>>, f: &u32) -> &u32 {
101+
| - let's call the lifetime of this reference `'1`
102+
LL |
103+
LL | f
104+
| ^ returning this value requires that `'1` must outlive `'static`
105+
106+
error: aborting due to 10 previous errors
107+
108+
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)