Skip to content

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

Closed
@ghost

Description

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-NLLArea: Non-lexical lifetimes (NLL)T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions