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 regression: cannot assign to *self because it is borrowed #46917

Closed
ghost opened this issue Dec 21, 2017 · 1 comment
Closed

NLL regression: cannot assign to *self because it is borrowed #46917

ghost opened this issue Dec 21, 2017 · 1 comment
Labels
A-NLL Area: Non-lexical lifetimes (NLL) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@ghost
Copy link

ghost commented Dec 21, 2017

rustc version: de38f49 (after #46862)

This compiles just fine:

#![feature(match_default_bindings)]

struct Foo {
    state: Bar,
    deadline: i32,
}
struct Bar;

impl Foo {
    fn foo(&mut self) {
        match self {
            Foo { state, deadline } => {
                *self = Foo {
                    state: Bar,
                    deadline: *deadline,
                };
            }
        }
    }
}

fn main() {}

Now let's add #![feature(nll)] and try again:

error[E0506]: cannot assign to `*self` because it is borrowed                                             
  --> src/bin/main.rs:53:17                          
   |                      
52 |               Foo { state, deadline } => {      
   |                            -------- borrow of `*self` occurs here                                    
53 | /                 *self = Foo {                 
54 | |                     state: Bar,               
55 | |                     deadline: *deadline,      
56 | |                 }; 
   | |_________________^ assignment to borrowed `*self` occurs here                                       

error: aborting due to previous error    

There are two interesting workarounds that fix the compilation error, but I have absolutely no idea why they work. :)

The first workaround: reorder field assignment.

*self = Foo {
    deadline: *deadline,
    state: Bar,
};

The second workaround: make a dummy implementation of Drop for Bar.

impl Drop for Bar {
    fn drop(&mut self) {}
}

cc @nikomatsakis

@arielb1
Copy link
Contributor

arielb1 commented Dec 21, 2017

This looks like it is caused by #46875.

@pnkfelix pnkfelix added A-NLL Area: Non-lexical lifetimes (NLL) WG-compiler-nll T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 21, 2017
@bors bors closed this as completed in 17d4e9b Jan 3, 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) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

2 participants