Skip to content

Borrow checker extends borrow range in code with early return #54663

@CodeSandwich

Description

@CodeSandwich

Borrow checker seems to extend mutable borrow of variable to the end of the function in case of an early return of value dependent on the borrow:

fn foo(x: &mut u8) -> Option<&u8> {
    if let Some(y) = bar(x) {
        return Some(y) // comment this out to calm compiler
    }
    bar(x)
}

fn bar(x: &mut u8) -> Option<&u8> { Some(x) }

Gives:

error[E0499]: cannot borrow `*x` as mutable more than once at a time
 --> src/main.rs:7:9
  |
4 |     if let Some(y) = bar(x) {
  |                          - first mutable borrow occurs here
...
7 |     bar(x)
  |         ^ second mutable borrow occurs here
8 | }
  | - first borrow ends here

Compilation fails on stable, nightly and nightly with NLL, works on nightly with polonius.
Try it on Playground

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-NLLArea: Non-lexical lifetimes (NLL)A-borrow-checkerArea: The borrow checkerC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.fixed-by-poloniusCompiling with `-Zpolonius` fixes this issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions