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:
bors 2018-09-24 14:47:17 +00:00
commit a072d1bca6
21 changed files with 282 additions and 416 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View 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() {}

View 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`.

View file

@ -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`.

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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