Skip to content

Borrow checker doesn't accept certain valid case when branch involves #57165

Open
@upsuper

Description

@upsuper

The compiler currently rejects the following code:

struct X {
    next: Option<Box<X>>,
}

fn main() {
    let mut b = Some(Box::new(X { next: None }));
    let mut p = &mut b;
    while let Some(now) = p {
        if true {
            p = &mut now.next;
        }
    }
}

It complains that now double mutably borrows p.0.

This explanation is not very convincing. If you rewrite it this way:

    while let Some(now) = p {
        p = &mut now.next;
    }

the compile would happily accept it, and compiler certainly also accepts

    while let Some(now) = p {
        // empty body
    }

so basically whatever the condition of if evaluates to, the original code should always be valid in terms of borrowing.

I'm not sure if I'm missing something, but it seems to me this is a bug of the borrow checker?

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-NLLArea: Non-lexical lifetimes (NLL)NLL-poloniusIssues related for using Polonius in the borrow checkerT-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