Auto merge of #54509 - matthewjasper:better-drop-access, r=pnkfelix
[NLL] Rework checking for borrows conflicting with drops Previously, we would split the drop access into multiple checks for each field of a struct/tuple/closure and through `Box` dereferences. This changes this to check if the borrow is accessed by the drop in `places_conflict`. We also now handle enums containing `Drop` types. Closes #53569 r? @nikomatsakis cc @pnkfelix
This commit is contained in:
commit
a072d1bca6
21 changed files with 282 additions and 416 deletions
|
|
@ -8,8 +8,6 @@ LL | }
|
|||
| |
|
||||
| `v` dropped here while still borrowed
|
||||
| borrow later used here, when `v` is dropped
|
||||
|
|
||||
= note: values in a scope are dropped in the opposite order they are defined
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ LL | }
|
|||
| |
|
||||
| `*cell` dropped here while still borrowed
|
||||
| borrow later used here, when `gen` is dropped
|
||||
|
|
||||
= note: values in a scope are dropped in the opposite order they are defined
|
||||
|
||||
error[E0597]: `ref_` does not live long enough
|
||||
--> $DIR/dropck.rs:22:11
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ LL | &mut *(*s).0 //[nll]~ ERROR borrow may still be in use when destructor
|
|||
| ^^^^^^^^^^^^
|
||||
...
|
||||
LL | }
|
||||
| - here, drop of `*s` needs exclusive access to `*s.0`, because the type `Scribble<'_>` implements the `Drop` trait
|
||||
| - here, drop of `s` needs exclusive access to `*s.0`, because the type `Scribble<'_>` implements the `Drop` trait
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 72:20...
|
||||
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:72:20
|
||||
|
|
@ -41,7 +41,7 @@ LL | &mut *(**s).0 //[nll]~ ERROR borrow may still be in use when destructor
|
|||
| ^^^^^^^^^^^^^
|
||||
...
|
||||
LL | }
|
||||
| - here, drop of `**s` needs exclusive access to `*s.0`, because the type `Scribble<'_>` implements the `Drop` trait
|
||||
| - here, drop of `s` needs exclusive access to `*s.0`, because the type `Scribble<'_>` implements the `Drop` trait
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 82:26...
|
||||
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:82:26
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ LL | &mut *(*s).0 //[nll]~ ERROR borrow may still be in use when destructor
|
|||
| ^^^^^^^^^^^^
|
||||
...
|
||||
LL | }
|
||||
| - here, drop of `*s` needs exclusive access to `*s.0`, because the type `Scribble<'_>` implements the `Drop` trait
|
||||
| - here, drop of `s` needs exclusive access to `*s.0`, because the type `Scribble<'_>` implements the `Drop` trait
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 72:20...
|
||||
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:72:20
|
||||
|
|
@ -35,7 +35,7 @@ LL | &mut *(**s).0 //[nll]~ ERROR borrow may still be in use when destructor
|
|||
| ^^^^^^^^^^^^^
|
||||
...
|
||||
LL | }
|
||||
| - here, drop of `**s` needs exclusive access to `*s.0`, because the type `Scribble<'_>` implements the `Drop` trait
|
||||
| - here, drop of `s` needs exclusive access to `*s.0`, because the type `Scribble<'_>` implements the `Drop` trait
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 82:26...
|
||||
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:82:26
|
||||
|
|
|
|||
51
src/test/ui/nll/enum-drop-access.rs
Normal file
51
src/test/ui/nll/enum-drop-access.rs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#![feature(nll)]
|
||||
|
||||
enum DropOption<T> {
|
||||
Some(T),
|
||||
None,
|
||||
}
|
||||
|
||||
impl<T> Drop for DropOption<T> {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
// Dropping opt could access the value behind the reference,
|
||||
fn drop_enum(opt: DropOption<&mut i32>) -> Option<&mut i32> {
|
||||
match opt {
|
||||
DropOption::Some(&mut ref mut r) => { //~ ERROR
|
||||
Some(r)
|
||||
},
|
||||
DropOption::None => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn optional_drop_enum(opt: Option<DropOption<&mut i32>>) -> Option<&mut i32> {
|
||||
match opt {
|
||||
Some(DropOption::Some(&mut ref mut r)) => { //~ ERROR
|
||||
Some(r)
|
||||
},
|
||||
Some(DropOption::None) | None => None,
|
||||
}
|
||||
}
|
||||
|
||||
// Ok, dropping opt doesn't access the reference
|
||||
fn optional_tuple(opt: Option<(&mut i32, String)>) -> Option<&mut i32> {
|
||||
match opt {
|
||||
Some((&mut ref mut r, _)) => {
|
||||
Some(r)
|
||||
},
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
// Ok, dropping res doesn't access the Ok case.
|
||||
fn different_variants(res: Result<&mut i32, String>) -> Option<&mut i32> {
|
||||
match res {
|
||||
Ok(&mut ref mut r) => {
|
||||
Some(r)
|
||||
},
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
45
src/test/ui/nll/enum-drop-access.stderr
Normal file
45
src/test/ui/nll/enum-drop-access.stderr
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
error[E0713]: borrow may still be in use when destructor runs
|
||||
--> $DIR/enum-drop-access.rs:15:31
|
||||
|
|
||||
LL | DropOption::Some(&mut ref mut r) => { //~ ERROR
|
||||
| ^^^^^^^^^
|
||||
...
|
||||
LL | }
|
||||
| - here, drop of `opt` needs exclusive access to `*opt.0`, because the type `DropOption<&mut i32>` implements the `Drop` trait
|
||||
|
|
||||
note: borrowed value must be valid for the anonymous lifetime #1 defined on the function body at 13:1...
|
||||
--> $DIR/enum-drop-access.rs:13:1
|
||||
|
|
||||
LL | / fn drop_enum(opt: DropOption<&mut i32>) -> Option<&mut i32> {
|
||||
LL | | match opt {
|
||||
LL | | DropOption::Some(&mut ref mut r) => { //~ ERROR
|
||||
LL | | Some(r)
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error[E0713]: borrow may still be in use when destructor runs
|
||||
--> $DIR/enum-drop-access.rs:24:36
|
||||
|
|
||||
LL | Some(DropOption::Some(&mut ref mut r)) => { //~ ERROR
|
||||
| ^^^^^^^^^
|
||||
...
|
||||
LL | }
|
||||
| - here, drop of `opt` needs exclusive access to `*opt.0.0`, because the type `DropOption<&mut i32>` implements the `Drop` trait
|
||||
|
|
||||
note: borrowed value must be valid for the anonymous lifetime #1 defined on the function body at 22:1...
|
||||
--> $DIR/enum-drop-access.rs:22:1
|
||||
|
|
||||
LL | / fn optional_drop_enum(opt: Option<DropOption<&mut i32>>) -> Option<&mut i32> {
|
||||
LL | | match opt {
|
||||
LL | | Some(DropOption::Some(&mut ref mut r)) => { //~ ERROR
|
||||
LL | | Some(r)
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0713`.
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
error[E0713]: borrow may still be in use when destructor runs
|
||||
--> $DIR/borrowck-ref-into-rvalue.rs:14:14
|
||||
error[E0597]: borrowed value does not live long enough
|
||||
--> $DIR/borrowck-ref-into-rvalue.rs:13:11
|
||||
|
|
||||
LL | Some(ref m) => {
|
||||
| ^^^^^
|
||||
LL | match Some("Hello".to_string()) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough
|
||||
...
|
||||
LL | }
|
||||
| - drop of temporary value occurs here
|
||||
| - temporary value only lives until here
|
||||
LL | println!("{}", *msg);
|
||||
| ---- borrow later used here
|
||||
|
|
||||
|
|
@ -13,4 +13,4 @@ LL | println!("{}", *msg);
|
|||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0713`.
|
||||
For more information about this error, try `rustc --explain E0597`.
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ LL | }
|
|||
| |
|
||||
| `b2` dropped here while still borrowed
|
||||
| borrow later used here, when `b1` is dropped
|
||||
|
|
||||
= note: values in a scope are dropped in the opposite order they are defined
|
||||
|
||||
error[E0597]: `b3` does not live long enough
|
||||
--> $DIR/dropck_arr_cycle_checked.rs:105:24
|
||||
|
|
@ -21,6 +23,8 @@ LL | }
|
|||
| |
|
||||
| `b3` dropped here while still borrowed
|
||||
| borrow later used here, when `b1` is dropped
|
||||
|
|
||||
= note: values in a scope are dropped in the opposite order they are defined
|
||||
|
||||
error[E0597]: `b1` does not live long enough
|
||||
--> $DIR/dropck_arr_cycle_checked.rs:111:24
|
||||
|
|
|
|||
|
|
@ -23,8 +23,6 @@ LL | }
|
|||
| |
|
||||
| `d1` dropped here while still borrowed
|
||||
| borrow later used here, when `d1` is dropped
|
||||
|
|
||||
= note: values in a scope are dropped in the opposite order they are defined
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ LL | }
|
|||
| |
|
||||
| `c2` dropped here while still borrowed
|
||||
| borrow later used here, when `c1` is dropped
|
||||
|
|
||||
= note: values in a scope are dropped in the opposite order they are defined
|
||||
|
||||
error[E0597]: `c3` does not live long enough
|
||||
--> $DIR/dropck_vec_cycle_checked.rs:115:24
|
||||
|
|
@ -21,6 +23,8 @@ LL | }
|
|||
| |
|
||||
| `c3` dropped here while still borrowed
|
||||
| borrow later used here, when `c1` is dropped
|
||||
|
|
||||
= note: values in a scope are dropped in the opposite order they are defined
|
||||
|
||||
error[E0597]: `c1` does not live long enough
|
||||
--> $DIR/dropck_vec_cycle_checked.rs:121:24
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ LL | }
|
|||
| |
|
||||
| `x` dropped here while still borrowed
|
||||
| borrow later used here, when `y` is dropped
|
||||
|
|
||||
= note: values in a scope are dropped in the opposite order they are defined
|
||||
|
||||
error[E0597]: `x` does not live long enough
|
||||
--> $DIR/issue-29106.rs:33:25
|
||||
|
|
@ -19,6 +21,8 @@ LL | }
|
|||
| |
|
||||
| `x` dropped here while still borrowed
|
||||
| borrow later used here, when `y` is dropped
|
||||
|
|
||||
= note: values in a scope are dropped in the opposite order they are defined
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ LL | }
|
|||
| borrow later used here, when `foo` is dropped
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
= note: values in a scope are dropped in the opposite order they are defined
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ LL | }
|
|||
| |
|
||||
| `c2` dropped here while still borrowed
|
||||
| borrow later used here, when `c1` is dropped
|
||||
|
|
||||
= note: values in a scope are dropped in the opposite order they are defined
|
||||
|
||||
error[E0597]: `c1` does not live long enough
|
||||
--> $DIR/vec-must-not-hide-type-from-dropck.rs:129:24
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ LL | }
|
|||
| |
|
||||
| `factorial` dropped here while still borrowed
|
||||
| borrow later used here, when `factorial` is dropped
|
||||
|
|
||||
= note: values in a scope are dropped in the opposite order they are defined
|
||||
|
||||
error[E0506]: cannot assign to `factorial` because it is borrowed
|
||||
--> $DIR/unboxed-closures-failed-recursive-fn-1.rs:30:5
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue