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

NLL: Implicit reborrow hides error "Cannot move out of Struct with destructor" #52059

Closed
lqd opened this issue Jul 4, 2018 · 4 comments · Fixed by #54310
Closed

NLL: Implicit reborrow hides error "Cannot move out of Struct with destructor" #52059

lqd opened this issue Jul 4, 2018 · 4 comments · Fixed by #54310
Assignees
Labels
A-NLL Area: Non-lexical lifetimes (NLL) NLL-diagnostics Working towards the "diagnostic parity" goal

Comments

@lqd
Copy link
Member

lqd commented Jul 4, 2018

Found while triaging the NLL crater run, in Servo's url crate.

Playground

There's a Drop impl preventing , so the error should at least mention it. But the implicit reborrow self.url hides this error with a '*self.url' does not live long enough one.

Changing the impl to

impl<'a> S<'a> {
    fn finish(self) -> &'a mut String {
        let p = self.url;
        p
    }
}

gives a better error message: self.url cannot move out of type "S<'_>", which implements the "Drop" trait.

@lqd lqd added A-NLL Area: Non-lexical lifetimes (NLL) NLL-diagnostics Working towards the "diagnostic parity" goal labels Jul 4, 2018
@matthewjasper matthewjasper self-assigned this Jul 8, 2018
@pnkfelix
Copy link
Member

assigning to self, hoping to investigate this week

@pnkfelix pnkfelix self-assigned this Sep 11, 2018
@pnkfelix
Copy link
Member

(to be clear, even an explicit reborrow would produce the error message that is being deemed inferior here...)

@pnkfelix
Copy link
Member

To be even more clear: the error here isn't about the illegality of moving out of a struct with a destructor, because the code is not doing any such move.

What the code is doing is borrowing into the interior of a struct with a destructor, and that borrow outlives the lifetime of the struct. Thus the struct's Drop impl might mutably access the borrowed (i.e. aliased) state, violating the rule that all such &mut-accesses are unaliased.


That's not to say that the given error message cannot be improved.

In particular, it might be better if it said something like:

15 |         self.url 
   |         ^^^^^^^^ borrow extends past lifetime of value 
16 |     }
   |     - `self` dropped here while `self.url` still borrowed
   |
   = note: `self` is of type `S<'_>`, which implements `Drop`; thus 
           dropping `self` requires exclusive access to `self.url`.

@pnkfelix
Copy link
Member

Okay I think I have a patch to fix this. And it seems like it improves some of our other diagnostics elsewhere. Will post PR soonish.

bors added a commit that referenced this issue 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
@matthewjasper matthewjasper added I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness and removed I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness labels Sep 5, 2019
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
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants