Auto merge of #90179 - Nilstrieb:lifetime-elision-mismatch-hint, r=estebank

Add beginner friendly lifetime elision hint to E0623

Address #90170

Suggest adding a new lifetime parameter when two elided lifetimes should match up but don't.

Example:

```
error[E0623]: lifetime mismatch
  --> $DIR/issue-90170-elision-mismatch.rs:2:35
   |
LL | fn foo(slice_a: &mut [u8], slice_b: &mut [u8]) {
   |                 ---------           --------- these two types are declared with different lifetimes...
LL |     core::mem::swap(&mut slice_a, &mut slice_b);
   |                                   ^^^^^^^^^^^^ ...but data from `slice_b` flows into `slice_a` here
   |
   = note: each elided lifetime in input position becomes a distinct lifetime
help: explicitly declare a lifetime and assign it to both
   |
LL | fn foo<'a>(slice_a: &'a mut [u8], slice_b: &'a mut [u8]) {
   |       ++++           ++                     ++

```

for

```rust
fn foo(slice_a: &mut [u8], slice_b: &mut [u8]) {
    core::mem::swap(&mut slice_a, &mut slice_b);
}
```
This commit is contained in:
bors 2021-11-04 00:39:21 +00:00
commit e60e19bc65
11 changed files with 220 additions and 8 deletions

View file

@ -0,0 +1,9 @@
// run-rustfix
pub fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); } //~ ERROR lifetime mismatch
pub fn foo2<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); } //~ ERROR lifetime mismatch
pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); } //~ ERROR lifetime mismatch
fn main() {}

View file

@ -0,0 +1,29 @@
error: lifetime may not live long enough
--> $DIR/issue-90170-elision-mismatch.rs:3:40
|
LL | pub fn foo(x: &mut Vec<&u8>, y: &u8) { x.push(y); }
| - - ^^^^^^^^^ argument requires that `'1` must outlive `'2`
| | |
| | let's call the lifetime of this reference `'1`
| let's call the lifetime of this reference `'2`
error: lifetime may not live long enough
--> $DIR/issue-90170-elision-mismatch.rs:5:44
|
LL | pub fn foo2(x: &mut Vec<&'_ u8>, y: &u8) { x.push(y); }
| - - ^^^^^^^^^ argument requires that `'1` must outlive `'2`
| | |
| | let's call the lifetime of this reference `'1`
| let's call the lifetime of this reference `'2`
error: lifetime may not live long enough
--> $DIR/issue-90170-elision-mismatch.rs:7:63
|
LL | pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&u8>, y: &u8) { x.push(y); }
| - - ^^^^^^^^^ argument requires that `'1` must outlive `'2`
| | |
| | let's call the lifetime of this reference `'1`
| let's call the lifetime of this reference `'2`
error: aborting due to 3 previous errors

View file

@ -0,0 +1,9 @@
// run-rustfix
pub fn foo(x: &mut Vec<&u8>, y: &u8) { x.push(y); } //~ ERROR lifetime mismatch
pub fn foo2(x: &mut Vec<&'_ u8>, y: &u8) { x.push(y); } //~ ERROR lifetime mismatch
pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&u8>, y: &u8) { x.push(y); } //~ ERROR lifetime mismatch
fn main() {}

View file

@ -0,0 +1,45 @@
error[E0623]: lifetime mismatch
--> $DIR/issue-90170-elision-mismatch.rs:3:47
|
LL | pub fn foo(x: &mut Vec<&u8>, y: &u8) { x.push(y); }
| --- --- ^ ...but data from `y` flows into `x` here
| |
| these two types are declared with different lifetimes...
|
= note: each elided lifetime in input position becomes a distinct lifetime
help: consider introducing a named lifetime parameter
|
LL | pub fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
| ++++ ++ ++
error[E0623]: lifetime mismatch
--> $DIR/issue-90170-elision-mismatch.rs:5:51
|
LL | pub fn foo2(x: &mut Vec<&'_ u8>, y: &u8) { x.push(y); }
| ------ --- ^ ...but data from `y` flows into `x` here
| |
| these two types are declared with different lifetimes...
|
= note: each elided lifetime in input position becomes a distinct lifetime
help: consider introducing a named lifetime parameter
|
LL | pub fn foo2<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
| ++++ ~~ ++
error[E0623]: lifetime mismatch
--> $DIR/issue-90170-elision-mismatch.rs:7:70
|
LL | pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&u8>, y: &u8) { x.push(y); }
| --- --- ^ ...but data from `y` flows into `x` here
| |
| these two types are declared with different lifetimes...
|
= note: each elided lifetime in input position becomes a distinct lifetime
help: consider introducing a named lifetime parameter
|
LL | pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
| ++ ++
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0623`.

View file

@ -5,6 +5,12 @@ LL | fn foo(&mut (ref mut v, w): &mut (&u8, &u8), x: &u8) {
| --- --- these two types are declared with different lifetimes...
LL | *v = x;
| ^ ...but data from `x` flows here
|
= note: each elided lifetime in input position becomes a distinct lifetime
help: consider introducing a named lifetime parameter
|
LL | fn foo<'a>(&mut (ref mut v, w): &mut (&'a u8, &u8), x: &'a u8) {
| ++++ ++ ++
error: aborting due to previous error

View file

@ -5,6 +5,12 @@ LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
| --- --- these two types are declared with different lifetimes...
LL | z.push((x,y));
| ^ ...but data flows into `z` here
|
= note: each elided lifetime in input position becomes a distinct lifetime
help: consider introducing a named lifetime parameter
|
LL | fn foo<'a>(z: &mut Vec<(&'a u8,&u8)>, (x, y): (&'a u8, &u8)) {
| ++++ ++ ++
error[E0623]: lifetime mismatch
--> $DIR/ex3-both-anon-regions-3.rs:2:15
@ -13,6 +19,12 @@ LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
| --- --- these two types are declared with different lifetimes...
LL | z.push((x,y));
| ^ ...but data flows into `z` here
|
= note: each elided lifetime in input position becomes a distinct lifetime
help: consider introducing a named lifetime parameter
|
LL | fn foo<'a>(z: &mut Vec<(&u8,&'a u8)>, (x, y): (&u8, &'a u8)) {
| ++++ ++ ++
error: aborting due to 2 previous errors

View file

@ -5,6 +5,12 @@ LL | fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) {
| --- --- these two types are declared with different lifetimes...
LL | y.push(z);
| ^ ...but data from `z` flows into `y` here
|
= note: each elided lifetime in input position becomes a distinct lifetime
help: consider introducing a named lifetime parameter
|
LL | fn foo<'a>(x:fn(&u8, &u8), y: Vec<&'a u8>, z: &'a u8) {
| ++++ ++ ++
error: aborting due to previous error

View file

@ -5,6 +5,12 @@ LL | fn foo(x:Box<dyn Fn(&u8, &u8)> , y: Vec<&u8>, z: &u8) {
| --- --- these two types are declared with different lifetimes...
LL | y.push(z);
| ^ ...but data from `z` flows into `y` here
|
= note: each elided lifetime in input position becomes a distinct lifetime
help: consider introducing a named lifetime parameter
|
LL | fn foo<'a>(x:Box<dyn Fn(&'a u8, &'a u8)> , y: Vec<&u8>, z: &u8) {
| ++++ ++ ++
error: aborting due to previous error

View file

@ -5,6 +5,12 @@ LL | fn foo(x: &mut Vec<&u8>, y: &u8) {
| --- --- these two types are declared with different lifetimes...
LL | x.push(y);
| ^ ...but data from `y` flows into `x` here
|
= note: each elided lifetime in input position becomes a distinct lifetime
help: consider introducing a named lifetime parameter
|
LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) {
| ++++ ++ ++
error: aborting due to previous error

View file

@ -5,6 +5,12 @@ LL | fn foo(x: &mut Vec<&'_ u8>, y: &'_ u8) { x.push(y); }
| ------ ------ ^ ...but data from `y` flows into `x` here
| |
| these two types are declared with different lifetimes...
|
= note: each elided lifetime in input position becomes a distinct lifetime
help: consider introducing a named lifetime parameter
|
LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
| ++++ ~~ ~~
error: aborting due to previous error