mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-01 19:23:50 +00:00
1775e7b93d
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 { | ++ ``` |
||
---|---|---|
.. | ||
alias-async.rs | ||
alias.rs | ||
assoc-async.rs | ||
assoc.rs | ||
lt-alias-async.rs | ||
lt-alias.rs | ||
lt-assoc-async.rs | ||
lt-assoc.rs | ||
lt-ref-self-async.fixed | ||
lt-ref-self-async.rs | ||
lt-ref-self-async.stderr | ||
lt-ref-self.fixed | ||
lt-ref-self.rs | ||
lt-ref-self.stderr | ||
lt-self-async.rs | ||
lt-self.rs | ||
lt-struct-async.rs | ||
lt-struct.rs | ||
multiple-ref-self-async.rs | ||
multiple-ref-self.rs | ||
nested-item.rs | ||
nested-item.stderr | ||
README.md | ||
ref-alias-async.rs | ||
ref-alias.rs | ||
ref-assoc-async.rs | ||
ref-assoc.rs | ||
ref-mut-alias-async.rs | ||
ref-mut-alias.rs | ||
ref-mut-self-async.rs | ||
ref-mut-self-async.stderr | ||
ref-mut-self.fixed | ||
ref-mut-self.rs | ||
ref-mut-self.stderr | ||
ref-mut-struct-async.rs | ||
ref-mut-struct-async.stderr | ||
ref-mut-struct.fixed | ||
ref-mut-struct.rs | ||
ref-mut-struct.stderr | ||
ref-self-async.rs | ||
ref-self-async.stderr | ||
ref-self.fixed | ||
ref-self.rs | ||
ref-self.stderr | ||
ref-struct-async.rs | ||
ref-struct-async.stderr | ||
ref-struct.fixed | ||
ref-struct.rs | ||
ref-struct.stderr | ||
self-async.rs | ||
self.rs | ||
struct-async.rs | ||
struct.rs |
Test cases intended to document behavior and try to exhaustively explore the combinations.
Confidence
These tests are not yet considered 100% normative, in that some aspects of the current behavior are not desirable. This is expressed in the "confidence" field in the following table. Values:
Confidence | Interpretation |
---|---|
100% | this will remain recommended behavior |
75% | unclear whether we will continue to accept this |
50% | this will likely be deprecated but remain valid |
25% | this could change in the future |
0% | this is definitely bogus and will likely change in the future in some way |
Tests
Test file | Self type |
Pattern | Current elision behavior | Confidence |
---|---|---|---|---|
self.rs |
Struct |
Self |
ignore self parameter |
100% |
struct.rs |
Struct |
Struct |
ignore self parameter |
100% |
alias.rs |
Struct |
Alias |
ignore self parameter |
100% |
ref-self.rs |
Struct |
&Self |
take lifetime from &Self |
100% |
ref-mut-self.rs |
Struct |
&mut Self |
take lifetime from &mut Self |
100% |
ref-struct.rs |
Struct |
&Struct |
take lifetime from &Self |
50% |
ref-mut-struct.rs |
Struct |
&mut Struct |
take lifetime from &mut Self |
50% |
ref-alias.rs |
Struct |
&Alias |
ignore Alias |
0% |
ref-mut-alias.rs |
Struct |
&mut Alias |
ignore Alias |
0% |
lt-self.rs |
Struct<'a> |
Self |
ignore Self (and hence 'a ) |
25% |
lt-struct.rs |
Struct<'a> |
Self |
ignore Self (and hence 'a ) |
0% |
lt-alias.rs |
Alias<'a> |
Self |
ignore Self (and hence 'a ) |
0% |
lt-ref-self.rs |
Struct<'a> |
&Self |
take lifetime from &Self |
75% |
In each case, we test the following patterns:
self: XXX
self: Box<XXX>
self: Pin<XXX>
self: Box<Box<XXX>>
self: Box<Pin<XXX>>
In the non-reference cases, Pin
causes errors so we substitute Rc
.
async fn
For each of the tests above we also check that async fn
behaves as an fn
would.
These tests are in files named *-async.rs
.
Legends:
- ✓ ⟹ Yes / Pass
- X ⟹ No
- α ⟹ lifetime mismatch
- β ⟹ cannot infer an appropriate lifetime
- γ ⟹ missing lifetime specifier
async file |
Pass? | Conforms to fn ? |
How does it diverge? fn ⟶ async fn |
---|---|---|---|
self-async.rs |
✓ | ✓ | N/A |
struct-async.rs |
✓ | ✓ | N/A |
alias-async.rs |
✓ | ✓ | N/A |
assoc-async.rs |
✓ | ✓ | N/A |
ref-self-async.rs |
X | ✓ | N/A |
ref-mut-self-async.rs |
X | ✓ | N/A |
ref-struct-async.rs |
X | ✓ | N/A |
ref-mut-struct-async.rs |
X | ✓ | N/A |
ref-alias-async.rs |
✓ | ✓ | N/A |
ref-assoc-async.rs |
✓ | ✓ | N/A |
ref-mut-alias-async.rs |
✓ | ✓ | N/A |
lt-self-async.rs |
✓ | ✓ | N/A |
lt-struct-async.rs |
✓ | ✓ | N/A |
lt-alias-async.rs |
✓ | ✓ | N/A |
lt-assoc-async.rs |
✓ | ✓ | N/A |
lt-ref-self-async.rs |
X | ✓ | N/A |