Auto merge of #54310 - pnkfelix:issue-52059-report-borrow-drop-conflict, r=nikomatsakis

Report when borrow could cause `&mut` aliasing during Drop

We were already issuing an error for the cases where this cropped up, so this is not fixing any soundness holes. The previous diagnostic just wasn't accurately describing the problem in the user's code.

Fix #52059
This commit is contained in:
bors 2018-09-23 04:06:15 +00:00
commit 7714c430ae
16 changed files with 346 additions and 73 deletions

View file

@ -1,13 +1,13 @@
error[E0597]: `local.inner` does not live long enough
error[E0713]: borrow may still be in use when destructor runs
--> $DIR/borrowck-fn-in-const-c.rs:27:16
|
LL | return &local.inner; //~ ERROR does not live long enough
| ^^^^^^^^^^^^ borrowed value does not live long enough
| ^^^^^^^^^^^^
LL | }
| - `local.inner` dropped here while still borrowed
| - here, drop of `local` needs exclusive access to `local.inner`, because the type `DropString` implements the `Drop` trait
|
= note: borrowed value must be valid for the static lifetime...
error: aborting due to previous error
For more information about this error, try `rustc --explain E0597`.
For more information about this error, try `rustc --explain E0713`.

View file

@ -1,11 +1,11 @@
warning[E0597]: `*s.0` does not live long enough
warning[E0713]: borrow may still be in use when destructor runs
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:63:5
|
LL | &mut *s.0 //[nll]~ ERROR `*s.0` does not live long enough [E0597]
| ^^^^^^^^^ borrowed value does not live long enough
LL | &mut *s.0 //[nll]~ ERROR borrow may still be in use when destructor runs [E0713]
| ^^^^^^^^^
...
LL | }
| - `*s.0` dropped here while still borrowed
| - 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 62:14...
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:62:14
@ -16,14 +16,14 @@ LL | fn scribbled<'a>(s: Scribble<'a>) -> &'a mut u32 {
It represents potential unsoundness in your code.
This warning will become a hard error in the future.
warning[E0597]: `*s.0` does not live long enough
warning[E0713]: borrow may still be in use when destructor runs
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:73:5
|
LL | &mut *(*s).0 //[nll]~ ERROR `*s.0` does not live long enough [E0597]
| ^^^^^^^^^^^^ borrowed value does not live long enough
LL | &mut *(*s).0 //[nll]~ ERROR borrow may still be in use when destructor runs [E0713]
| ^^^^^^^^^^^^
...
LL | }
| - `*s.0` dropped here while still borrowed
| - 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
@ -34,14 +34,14 @@ LL | fn boxed_scribbled<'a>(s: Box<Scribble<'a>>) -> &'a mut u32 {
It represents potential unsoundness in your code.
This warning will become a hard error in the future.
warning[E0597]: `*s.0` does not live long enough
warning[E0713]: borrow may still be in use when destructor runs
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:83:5
|
LL | &mut *(**s).0 //[nll]~ ERROR `*s.0` does not live long enough [E0597]
| ^^^^^^^^^^^^^ borrowed value does not live long enough
LL | &mut *(**s).0 //[nll]~ ERROR borrow may still be in use when destructor runs [E0713]
| ^^^^^^^^^^^^^
...
LL | }
| - `*s.0` dropped here while still borrowed
| - 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
@ -66,4 +66,4 @@ LL | | }
error: aborting due to previous error
For more information about this error, try `rustc --explain E0597`.
For more information about this error, try `rustc --explain E0713`.

View file

@ -1,11 +1,11 @@
error[E0597]: `*s.0` does not live long enough
error[E0713]: borrow may still be in use when destructor runs
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:63:5
|
LL | &mut *s.0 //[nll]~ ERROR `*s.0` does not live long enough [E0597]
| ^^^^^^^^^ borrowed value does not live long enough
LL | &mut *s.0 //[nll]~ ERROR borrow may still be in use when destructor runs [E0713]
| ^^^^^^^^^
...
LL | }
| - `*s.0` dropped here while still borrowed
| - 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 62:14...
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:62:14
@ -13,14 +13,14 @@ note: borrowed value must be valid for the lifetime 'a as defined on the functio
LL | fn scribbled<'a>(s: Scribble<'a>) -> &'a mut u32 {
| ^^
error[E0597]: `*s.0` does not live long enough
error[E0713]: borrow may still be in use when destructor runs
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:73:5
|
LL | &mut *(*s).0 //[nll]~ ERROR `*s.0` does not live long enough [E0597]
| ^^^^^^^^^^^^ borrowed value does not live long enough
LL | &mut *(*s).0 //[nll]~ ERROR borrow may still be in use when destructor runs [E0713]
| ^^^^^^^^^^^^
...
LL | }
| - `*s.0` dropped here while still borrowed
| - 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
@ -28,14 +28,14 @@ note: borrowed value must be valid for the lifetime 'a as defined on the functio
LL | fn boxed_scribbled<'a>(s: Box<Scribble<'a>>) -> &'a mut u32 {
| ^^
error[E0597]: `*s.0` does not live long enough
error[E0713]: borrow may still be in use when destructor runs
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:83:5
|
LL | &mut *(**s).0 //[nll]~ ERROR `*s.0` does not live long enough [E0597]
| ^^^^^^^^^^^^^ borrowed value does not live long enough
LL | &mut *(**s).0 //[nll]~ ERROR borrow may still be in use when destructor runs [E0713]
| ^^^^^^^^^^^^^
...
LL | }
| - `*s.0` dropped here while still borrowed
| - 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
@ -45,4 +45,4 @@ LL | fn boxed_boxed_scribbled<'a>(s: Box<Box<Scribble<'a>>>) -> &'a mut u32 {
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0597`.
For more information about this error, try `rustc --explain E0713`.

View file

@ -60,8 +60,8 @@ fn boxed_boxed_borrowed_scribble<'a>(s: Box<Box<&'a mut Scribble>>) -> &'a mut u
// this should be an error. (Which is perhaps the essence of why
// rust-lang/rust#45696 arose in the first place.)
fn scribbled<'a>(s: Scribble<'a>) -> &'a mut u32 {
&mut *s.0 //[nll]~ ERROR `*s.0` does not live long enough [E0597]
//[migrate]~^ WARNING `*s.0` does not live long enough [E0597]
&mut *s.0 //[nll]~ ERROR borrow may still be in use when destructor runs [E0713]
//[migrate]~^ WARNING borrow may still be in use when destructor runs [E0713]
//[migrate]~| WARNING This error has been downgraded to a warning for backwards compatibility
}
@ -70,8 +70,8 @@ fn scribbled<'a>(s: Scribble<'a>) -> &'a mut u32 {
// (But again, AST-borrowck was not smart enogh to know that this
// should be an error.)
fn boxed_scribbled<'a>(s: Box<Scribble<'a>>) -> &'a mut u32 {
&mut *(*s).0 //[nll]~ ERROR `*s.0` does not live long enough [E0597]
//[migrate]~^ WARNING `*s.0` does not live long enough [E0597]
&mut *(*s).0 //[nll]~ ERROR borrow may still be in use when destructor runs [E0713]
//[migrate]~^ WARNING borrow may still be in use when destructor runs [E0713]
//[migrate]~| WARNING This error has been downgraded to a warning for backwards compatibility
}
@ -80,8 +80,8 @@ fn boxed_scribbled<'a>(s: Box<Scribble<'a>>) -> &'a mut u32 {
// (But again, AST-borrowck was not smart enogh to know that this
// should be an error.)
fn boxed_boxed_scribbled<'a>(s: Box<Box<Scribble<'a>>>) -> &'a mut u32 {
&mut *(**s).0 //[nll]~ ERROR `*s.0` does not live long enough [E0597]
//[migrate]~^ WARNING `*s.0` does not live long enough [E0597]
&mut *(**s).0 //[nll]~ ERROR borrow may still be in use when destructor runs [E0713]
//[migrate]~^ WARNING borrow may still be in use when destructor runs [E0713]
//[migrate]~| WARNING This error has been downgraded to a warning for backwards compatibility
}

View file

@ -19,7 +19,7 @@ struct VecWrapper<'a>(&'a mut S);
struct S(Box<u32>);
fn get_dangling<'a>(v: VecWrapper<'a>) -> &'a u32 {
let s_inner: &'a S = &*v.0; //~ ERROR `*v.0` does not live long enough
let s_inner: &'a S = &*v.0; //~ ERROR borrow may still be in use when destructor runs [E0713]
&s_inner.0
}

View file

@ -1,11 +1,11 @@
error[E0597]: `*v.0` does not live long enough
error[E0713]: borrow may still be in use when destructor runs
--> $DIR/issue-31567.rs:22:26
|
LL | let s_inner: &'a S = &*v.0; //~ ERROR `*v.0` does not live long enough
| ^^^^^ borrowed value does not live long enough
LL | let s_inner: &'a S = &*v.0; //~ ERROR borrow may still be in use when destructor runs [E0713]
| ^^^^^
LL | &s_inner.0
LL | }
| - `*v.0` dropped here while still borrowed
| - here, drop of `v` needs exclusive access to `*v.0`, because the type `VecWrapper<'_>` implements the `Drop` trait
|
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 21:17...
--> $DIR/issue-31567.rs:21:17
@ -15,4 +15,4 @@ LL | fn get_dangling<'a>(v: VecWrapper<'a>) -> &'a u32 {
error: aborting due to previous error
For more information about this error, try `rustc --explain E0597`.
For more information about this error, try `rustc --explain E0713`.

View file

@ -0,0 +1,33 @@
// rust-lang/rust#52059: Regardless of whether you are moving out of a
// Drop type or just introducing an inadvertant alias via a borrow of
// one of its fields, it is useful to be reminded of the significance
// of the fact that the type implements Drop.
#![feature(nll)]
#![allow(dead_code)]
pub struct S<'a> { url: &'a mut String }
impl<'a> Drop for S<'a> { fn drop(&mut self) { } }
fn finish_1(s: S) -> &mut String {
s.url
}
//~^^ ERROR borrow may still be in use when destructor runs
fn finish_2(s: S) -> &mut String {
let p = &mut *s.url; p
}
//~^^ ERROR borrow may still be in use when destructor runs
fn finish_3(s: S) -> &mut String {
let p: &mut _ = s.url; p
}
//~^^ ERROR borrow may still be in use when destructor runs
fn finish_4(s: S) -> &mut String {
let p = s.url; p
}
//~^^ ERROR cannot move out of type `S<'_>`, which implements the `Drop` trait
fn main() {}

View file

@ -0,0 +1,61 @@
error[E0713]: borrow may still be in use when destructor runs
--> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:14:5
|
LL | s.url
| ^^^^^
LL | }
| - here, drop of `s` needs exclusive access to `*s.url`, because the type `S<'_>` implements the `Drop` trait
|
note: borrowed value must be valid for the anonymous lifetime #1 defined on the function body at 13:1...
--> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:13:1
|
LL | / fn finish_1(s: S) -> &mut String {
LL | | s.url
LL | | }
| |_^
error[E0713]: borrow may still be in use when destructor runs
--> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:19:13
|
LL | let p = &mut *s.url; p
| ^^^^^^^^^^^
LL | }
| - here, drop of `s` needs exclusive access to `*s.url`, because the type `S<'_>` implements the `Drop` trait
|
note: borrowed value must be valid for the anonymous lifetime #1 defined on the function body at 18:1...
--> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:18:1
|
LL | / fn finish_2(s: S) -> &mut String {
LL | | let p = &mut *s.url; p
LL | | }
| |_^
error[E0713]: borrow may still be in use when destructor runs
--> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:24:21
|
LL | let p: &mut _ = s.url; p
| ^^^^^
LL | }
| - here, drop of `s` needs exclusive access to `*s.url`, because the type `S<'_>` implements the `Drop` trait
|
note: borrowed value must be valid for the anonymous lifetime #1 defined on the function body at 23:1...
--> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:23:1
|
LL | / fn finish_3(s: S) -> &mut String {
LL | | let p: &mut _ = s.url; p
LL | | }
| |_^
error[E0509]: cannot move out of type `S<'_>`, which implements the `Drop` trait
--> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:29:13
|
LL | let p = s.url; p
| ^^^^^
| |
| cannot move out of here
| help: consider borrowing here: `&s.url`
error: aborting due to 4 previous errors
Some errors occurred: E0509, E0713.
For more information about an error, try `rustc --explain E0509`.

View file

@ -1,11 +1,11 @@
error[E0597]: borrowed value does not live long enough
--> $DIR/borrowck-ref-into-rvalue.rs:13:11
error[E0713]: borrow may still be in use when destructor runs
--> $DIR/borrowck-ref-into-rvalue.rs:14:14
|
LL | match Some("Hello".to_string()) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough
LL | Some(ref m) => {
| ^^^^^
...
LL | }
| - temporary value only lives until here
| - drop of temporary value occurs 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 E0597`.
For more information about this error, try `rustc --explain E0713`.

View file

@ -1,17 +1,18 @@
error[E0597]: `foo.data` does not live long enough
error[E0713]: borrow may still be in use when destructor runs
--> $DIR/issue28498-reject-ex1.rs:44:29
|
LL | foo.data[0].1.set(Some(&foo.data[1]));
| ^^^^^^^^ borrowed value does not live long enough
| ^^^^^^^^
...
LL | }
| -
| |
| `foo.data` dropped here while still borrowed
| here, drop of `foo` needs exclusive access to `foo.data`, because the type `Foo<Concrete<'_>>` implements the `Drop` trait
| 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
For more information about this error, try `rustc --explain E0597`.
For more information about this error, try `rustc --explain E0713`.