Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Report when borrow could cause &mut aliasing during Drop #54310

Merged

Conversation

pnkfelix
Copy link
Member

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

…at needs exclusive access.

In particular:

 1. Extend `WriteKind::StorageDeadOrDrop` with state to track whether
    we are running a destructor or just freeing backing storage.  (As
    part of this, when we drop a Box<..<Box<T>..> where `T` does not
    need drop, we now signal that the drop of `T` is a kind of storage
    dead rather than a drop.)

 2. When reporting that a value does not live long enough, check if
    we're doing an "interesting" drop, i.e. we aren't just trivally
    freeing the borrowed state, but rather a user-defined dtor will
    run and potentially require exclusive aces to the borrowed state.

 3. Added a new diagnosic to describe the scenario here.
It is worth pointing out that the reason that so few diagnostics are
effected is because of the filter I put in where it only goes down the
new path if the borrowed place is *not* a prefix of the dropped place.

(Without that filter, a *lot* of the tests would need this change, and
it would probably be a net loss for the UX, since you'd see it even in
cases like borrows of generic types where there is no explicit mention
of `Drop`.)
@rust-highfive
Copy link
Collaborator

r? @michaelwoerister

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 18, 2018
...
LL | }
| - temporary value only lives until here
| - drop of temporary value occurs here
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm I have to admit that this delta (namely losing the printout of the match's input expression) seems unfortunate. I should look into incorporating that into the diagnostic output in cases like this.

Copy link
Contributor

@nikomatsakis nikomatsakis Sep 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Musing on this, I was thinking that it might be a good idea for us to explain why the value is being dropped here. One way I could imagine doing that is:

  • First, find the thing that was borrowed. If it is a user-local, then add a note with that span and say something like:
= note: local variables are dropped when they go out of scope

    let x;
        - `x` declared here
  }
  - `x` goes out of scope here

note sure if we can do notes with multispans like that (cc @estebank) but it seems ideal. Alternatively, we could merge this into the main error.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For temporaries, we would probably give a slightly different error, along the lines of what @mikhail-m1 did in #54164

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nikomatsakis not supported yet, but something I've had in my backlog for a while. Should I prioritize it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@estebank I personally don't think you need to re-prioritize. We can work around its absence, as @nikomatsakis notes...

@memoryruins memoryruins added the A-NLL Area: Non-lexical lifetimes (NLL) label Sep 18, 2018
@rust-highfive

This comment has been minimized.

@pnkfelix pnkfelix added the NLL-diagnostics Working towards the "diagnostic parity" goal label Sep 18, 2018
@rust-highfive

This comment has been minimized.

@pnkfelix
Copy link
Member Author

okay this time i'm going to actually test my example before pushing to the branch

@nikomatsakis
Copy link
Contributor

r? @nikomatsakis

@rust-highfive

This comment has been minimized.

@nikomatsakis
Copy link
Contributor

ok well I think this is a solid step forward. r=me but I would like to do a kind of overview of all of our error messages at some point to think carefully about how to structure them.

@pnkfelix
Copy link
Member Author

And now I'm going so far as to run the error index tests locally too

Sharing how to do it for reference with my future self and anyone else who might care:

% x.py test --stage 2 src/tools/error_index_generator

error[E0106]: missing lifetime specifier
 --> /checkout/obj/build/x86_64-unknown-linux-gnu/test/error-index.md:11424:23
  |
9 | fn demo(s: &mut S) -> &mut String { let p = &mut *(*s).data; p }
  |                       ^ expected lifetime parameter
  |
  = help: this function's return type contains a borrowed value, but the signature does not say which one of `s`'s 2 lifetimes it is borrowed from
@pnkfelix pnkfelix force-pushed the issue-52059-report-borrow-drop-conflict branch from 12ac520 to c9cf499 Compare September 19, 2018 08:32
@pnkfelix
Copy link
Member Author

@bors r=nikomatsakis

@bors
Copy link
Contributor

bors commented Sep 19, 2018

📌 Commit c9cf499 has been approved by nikomatsakis

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 19, 2018
@pnkfelix
Copy link
Member Author

(If this and some of the other NLL diagnostics PRs are still in the queue on Monday, I might go roll them up manually because I know certain ones are going to collide...)

@bors
Copy link
Contributor

bors commented Sep 23, 2018

⌛ Testing commit c9cf499 with merge 7714c43...

bors added a commit that referenced this pull request Sep 23, 2018
…ct, 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
@bors
Copy link
Contributor

bors commented Sep 23, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: nikomatsakis
Pushing 7714c43 to master...

@bors bors merged commit c9cf499 into rust-lang:master Sep 23, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-NLL Area: Non-lexical lifetimes (NLL) NLL-diagnostics Working towards the "diagnostic parity" goal S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

NLL: Implicit reborrow hides error "Cannot move out of Struct with destructor"
7 participants