Skip to content

two-phase borrows are causing #[feature(nll)] to reject a mutable borrow incorrectly #48070

Closed
@nikomatsakis

Description

@nikomatsakis

In this example, the NLL checker incorrectly judges foo to be borrowed more than once:

#![feature(nll)]

struct Foo {
    x: u32
}

impl Foo {
    fn twiddle(&mut self) -> &mut Self { self }
    fn twaddle(&mut self) -> &mut Self { self }
    fn emit(&mut self) {
        self.x += 1;
    }
}

fn main() {
    let mut foo = Foo { x: 0 };
    match 22 {
        22 => &mut foo,
        44 => foo.twiddle(),
        _ => foo.twaddle(),
    }.emit();
}

I get this error:

error[E0499]: cannot borrow `foo` as mutable more than once at a time
  --> src/main.rs:17:5
   |
17 | /     match 22 {
18 | |         22 => &mut foo,
19 | |         44 => foo.twiddle(),
   | |               --- first mutable borrow occurs here
20 | |         _ => foo.twaddle(),
21 | |     }.emit();
   | |_____^ second mutable borrow occurs here

This works without NLL. This was found while trying to bootstrap rustc with NLL enabled, where it manifests as:

error[E0499]: cannot borrow `diag_builder` as mutable more than once at a time
   --> src/librustc/lint/levels.rs:304:13
    |
304 | /             match forbid_src {
305 | |                 LintSource::Default => &mut diag_builder,
306 | |                 LintSource::Node(_, forbid_source_span) => {
307 | |                     diag_builder.span_label(forbid_source_span,
...   |
311 | |                     diag_builder.note("`forbid` lint level was set on command line")
    | |                     ------------ first mutable borrow occurs here
312 | |                 }
313 | |             }.emit();
    | |_____________^ second mutable borrow occurs here

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-NLLArea: Non-lexical lifetimes (NLL)NLL-completeWorking towards the "valid code works" goalT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions