Fix erroneous loop diagnostic in nll
This commit fixes the logic of detecting when a use happen in a later iteration of where a borrow was defined Fixes #53773
This commit is contained in:
parent
cbc865defd
commit
801c3f060f
13 changed files with 205 additions and 73 deletions
|
|
@ -5,7 +5,7 @@ LL | for &x in &vector {
|
|||
| -------
|
||||
| |
|
||||
| immutable borrow occurs here
|
||||
| immutable borrow used here, in later iteration of loop
|
||||
| immutable borrow later used here
|
||||
LL | let cap = vector.capacity();
|
||||
LL | vector.extend(repeat(0)); //~ ERROR cannot borrow
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
|
||||
|
|
@ -17,7 +17,7 @@ LL | for &x in &vector {
|
|||
| -------
|
||||
| |
|
||||
| immutable borrow occurs here
|
||||
| immutable borrow used here, in later iteration of loop
|
||||
| immutable borrow later used here
|
||||
...
|
||||
LL | vector[1] = 5; //~ ERROR cannot borrow
|
||||
| ^^^^^^ mutable borrow occurs here
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@ LL | borrow(&*v); //[ast]~ ERROR cannot borrow
|
|||
| ^^^ immutable borrow occurs here
|
||||
...
|
||||
LL | *x = box 5;
|
||||
| -- mutable borrow used here, in later iteration of loop
|
||||
| -- mutable borrow later used here
|
||||
|
||||
error[E0502]: cannot borrow `*v` as immutable because it is also borrowed as mutable
|
||||
--> $DIR/borrowck-lend-flow-loop.rs:109:16
|
||||
|
|
||||
LL | **x += 1;
|
||||
| -------- mutable borrow used here, in later iteration of loop
|
||||
| -------- mutable borrow later used here
|
||||
LL | borrow(&*v); //[ast]~ ERROR cannot borrow
|
||||
| ^^^ immutable borrow occurs here
|
||||
...
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time
|
|||
LL | 1 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
|
||||
| ---- ^^^^^^ second mutable borrow occurs here
|
||||
| |
|
||||
| first borrow used here, in later iteration of loop
|
||||
| first borrow later used here
|
||||
...
|
||||
LL | _ => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
|
||||
| ------ first mutable borrow occurs here
|
||||
|
|
@ -13,7 +13,7 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time
|
|||
--> $DIR/borrowck-mut-borrow-linear-errors.rs:15:30
|
||||
|
|
||||
LL | 1 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
|
||||
| ---- first borrow used here, in later iteration of loop
|
||||
| ---- first borrow later used here
|
||||
LL | //[mir]~^ ERROR [E0499]
|
||||
LL | 2 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
|
||||
| ^^^^^^ second mutable borrow occurs here
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time
|
|||
LL | 1 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
|
||||
| ---- ^^^^^^ second mutable borrow occurs here
|
||||
| |
|
||||
| first borrow used here, in later iteration of loop
|
||||
| first borrow later used here
|
||||
...
|
||||
LL | _ => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
|
||||
| ------ first mutable borrow occurs here
|
||||
|
|
@ -13,7 +13,7 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time
|
|||
--> $DIR/borrowck-mut-borrow-linear-errors.rs:15:30
|
||||
|
|
||||
LL | 1 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
|
||||
| ---- first borrow used here, in later iteration of loop
|
||||
| ---- first borrow later used here
|
||||
LL | //[mir]~^ ERROR [E0499]
|
||||
LL | 2 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
|
||||
| ^^^^^^ second mutable borrow occurs here
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ LL | let inner_second = &mut inner_void; //~ ERROR cannot borrow
|
|||
| ^^^^^^^^^^^^^^^ second mutable borrow occurs here
|
||||
LL | inner_second.use_mut();
|
||||
LL | inner_first.use_mut();
|
||||
| ----------- first borrow used here, in later iteration of loop
|
||||
| ----------- first borrow later used here
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ LL | let v: Vec<&str> = line.split_whitespace().collect();
|
|||
| ^^^^ borrowed value does not live long enough
|
||||
...
|
||||
LL | acc += cnt2;
|
||||
| --- borrow used here, in later iteration of loop
|
||||
| --- borrow later used here
|
||||
...
|
||||
LL | }
|
||||
| - `line` dropped here while still borrowed
|
||||
|
|
|
|||
49
src/test/ui/nll/issue-53773.rs
Normal file
49
src/test/ui/nll/issue-53773.rs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#![feature(nll)]
|
||||
|
||||
struct Archive;
|
||||
struct ArchiveIterator<'a> {
|
||||
x: &'a Archive,
|
||||
}
|
||||
struct ArchiveChild<'a> {
|
||||
x: &'a Archive,
|
||||
}
|
||||
|
||||
struct A {
|
||||
raw: &'static mut Archive,
|
||||
}
|
||||
struct Iter<'a> {
|
||||
raw: &'a mut ArchiveIterator<'a>,
|
||||
}
|
||||
struct C<'a> {
|
||||
raw: &'a mut ArchiveChild<'a>,
|
||||
}
|
||||
|
||||
impl A {
|
||||
pub fn iter(&self) -> Iter<'_> {
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
impl Drop for A {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
impl<'a> Drop for C<'a> {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for Iter<'a> {
|
||||
type Item = C<'a>;
|
||||
fn next(&mut self) -> Option<C<'a>> {
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
|
||||
fn error(archive: &A) {
|
||||
let mut members: Vec<&mut ArchiveChild<'_>> = vec![];
|
||||
for child in archive.iter() {
|
||||
members.push(child.raw);
|
||||
//~^ ERROR borrow may still be in use when destructor runs [E0713]
|
||||
}
|
||||
members.len();
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
16
src/test/ui/nll/issue-53773.stderr
Normal file
16
src/test/ui/nll/issue-53773.stderr
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
error[E0713]: borrow may still be in use when destructor runs
|
||||
--> $DIR/issue-53773.rs:43:22
|
||||
|
|
||||
LL | members.push(child.raw);
|
||||
| ^^^^^^^^^
|
||||
LL | //~^ ERROR borrow may still be in use when destructor runs [E0713]
|
||||
LL | }
|
||||
| - here, drop of `child` needs exclusive access to `*child.raw`, because the type `C<'_>` implements the `Drop` trait
|
||||
LL | members.len();
|
||||
| ------- borrow later used here
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0713`.
|
||||
|
|
@ -7,7 +7,7 @@ LL | foo.mutate();
|
|||
| ^^^^^^^^^^^^ mutable borrow occurs here
|
||||
LL | //~^ ERROR cannot borrow `foo` as mutable
|
||||
LL | println!("foo={:?}", *string);
|
||||
| ------- immutable borrow used here, in later iteration of loop
|
||||
| ------- immutable borrow later used here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ error[E0597]: `x` does not live long enough
|
|||
--> $DIR/regions-escape-loop-via-variable.rs:11:13
|
||||
|
|
||||
LL | let x = 1 + *p;
|
||||
| -- borrow used here, in later iteration of loop
|
||||
| -- borrow later used here
|
||||
LL | p = &x;
|
||||
| ^^ borrowed value does not live long enough
|
||||
LL | }
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ LL | while x < 10 { //~ ERROR cannot use `x` because it was mutably borrowed
|
|||
| ^ use of borrowed `x`
|
||||
LL | let mut z = x; //~ ERROR cannot use `x` because it was mutably borrowed
|
||||
LL | _y.push(&mut z);
|
||||
| -- borrow used here, in later iteration of loop
|
||||
| -- borrow later used here
|
||||
|
||||
error[E0503]: cannot use `x` because it was mutably borrowed
|
||||
--> $DIR/regions-escape-loop-via-vec.rs:6:21
|
||||
|
|
@ -18,7 +18,7 @@ LL | while x < 10 { //~ ERROR cannot use `x` because it was mutably borrowed
|
|||
LL | let mut z = x; //~ ERROR cannot use `x` because it was mutably borrowed
|
||||
| ^ use of borrowed `x`
|
||||
LL | _y.push(&mut z);
|
||||
| -- borrow used here, in later iteration of loop
|
||||
| -- borrow later used here
|
||||
|
||||
error[E0597]: `z` does not live long enough
|
||||
--> $DIR/regions-escape-loop-via-vec.rs:7:17
|
||||
|
|
@ -26,7 +26,7 @@ error[E0597]: `z` does not live long enough
|
|||
LL | _y.push(&mut z);
|
||||
| -- ^^^^^^ borrowed value does not live long enough
|
||||
| |
|
||||
| borrow used here, in later iteration of loop
|
||||
| borrow later used here
|
||||
...
|
||||
LL | }
|
||||
| - `z` dropped here while still borrowed
|
||||
|
|
@ -38,7 +38,7 @@ LL | let mut _y = vec![&mut x];
|
|||
| ------ borrow of `x` occurs here
|
||||
...
|
||||
LL | _y.push(&mut z);
|
||||
| -- borrow used here, in later iteration of loop
|
||||
| -- borrow later used here
|
||||
LL | //~^ ERROR `z` does not live long enough
|
||||
LL | x += 1; //~ ERROR cannot assign
|
||||
| ^^^^^^ use of borrowed `x`
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ LL | for x in &mut xs {
|
|||
| -------
|
||||
| |
|
||||
| first mutable borrow occurs here
|
||||
| first borrow used here, in later iteration of loop
|
||||
| first borrow later used here
|
||||
LL | xs.push(1) //~ ERROR cannot borrow `xs`
|
||||
| ^^ second mutable borrow occurs here
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue