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] attr-0.1.0 regression #53569

Closed
nikomatsakis opened this issue Aug 21, 2018 · 7 comments
Closed

[nll] attr-0.1.0 regression #53569

nikomatsakis opened this issue Aug 21, 2018 · 7 comments
Assignees
Labels
A-NLL Area: Non-lexical lifetimes (NLL) NLL-complete Working towards the "valid code works" goal

Comments

@nikomatsakis
Copy link
Contributor

Found during a crater run

Minimized reproduction

@nikomatsakis nikomatsakis added A-NLL Area: Non-lexical lifetimes (NLL) WG-compiler-nll NLL-complete Working towards the "valid code works" goal labels Aug 21, 2018
@nikomatsakis nikomatsakis added this to the Rust 2018 RC milestone Aug 21, 2018
@matthewjasper matthewjasper self-assigned this Aug 21, 2018
@matthewjasper
Copy link
Contributor

Assigning myself since I've done some work in this locally. But I have a lot going on ATM, so anyone else can feel free to take it.

The issue is the same as #47917, #49822 and #52782 but for enums. I have plans to move all of this checking to happen in/after places_conflict which should also handle this case correctly.

@nikomatsakis
Copy link
Contributor Author

nikomatsakis commented Aug 21, 2018

Further minimized:

#![feature(nll)]
#![allow(dead_code)]

struct S<'a> {
    value: &'a Value,
}

struct Value {
    data: u32,
}

impl<'a> S<'a> {
    fn get(&self) -> Result<&'a mut Value, String> {
        unimplemented!();
    }

    fn at(&self)  {
        let v = self.get();
        if let Ok(Value { ref mut data }) = v {
            let _res : &'a u32 = data;
        }
    }
}

fn main() {
}

@nikomatsakis
Copy link
Contributor Author

Hmm, looking a bit more closely, I would say that this is a subtle situation. I agree with @matthewjasper that this is basically a "dangly paths" situation (cc #52782). That said, @matthewjasper, I'm not sure I understood the fix you were proposing. =)

Let me lay out what is happening, as best as I understand it:

  • First, the call to self.get returns a Result<&'0 mut Value, String>
  • Then, the let _res: &'a u32 = ... forces '0: 'a
  • Finally, we execute Drop(v) -- this is considered an error because there is an outstanding loan of v.as<Ok>.0.
    • This is basically a correct error -- we should not drop things when their interior is borrowed
    • However, in this case, Drop itself does not have a destructor -- the destructor is on String, and of course if String is being dropped, then this is an Err case, and hence we know that the borrow never happened.

@nikomatsakis
Copy link
Contributor Author

@nikomatsakis
Copy link
Contributor Author

Removing nomination but we do have to settle on a plan

@Mark-Simulacrum
Copy link
Member

@nikomatsakis @matthewjasper @pnkfelix It's not clear to me that this has sufficient momentum or decision-making to land for RC1 -- should this be pushed back to RC2, or is this truly a blocking issue?

@pnkfelix
Copy link
Member

(Since not everyone will follow the comments on every linked PR: this can be addressed by PR #54324, but we closed that because we are anticipating a better, broader fix from @matthewjasper , previewed here: master...matthewjasper:better-drop-access )

bors added a commit that referenced this issue Sep 24, 2018
[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
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-complete Working towards the "valid code works" goal
Projects
None yet
Development

No branches or pull requests

4 participants