Skip to content

MIR borrowck: mutable use of immutable upvar causes duplicate errors #46559

Closed
@arielb1

Description

@arielb1

e.g. the test compile-fail/unboxed-closures-mutate-upvar, or this code:

fn main() {
    let x = 0;
    || { &mut x; };
}

Causes a double error with MIR borrowck

$ ./build/x86_64-unknown-linux-gnu/stage1/bin/rustc double-error.rs -Z borrowck=compare
error[E0595]: closure cannot assign to immutable local variable `x` (Ast)
 --> double-error.rs:3:5
  |
2 |     let x = 0;
  |         - consider changing this to `mut x`
3 |     || { &mut x; };
  |     ^^ cannot borrow mutably

error[E0596]: cannot borrow immutable item `x` as mutable (Mir)
 --> double-error.rs:3:5
  |
3 |     || { &mut x; };
  |     ^^^^^^^^^^^^^^ cannot borrow as mutable

error[E0596]: cannot borrow immutable item `x` as mutable (Mir)
 --> double-error.rs:3:10
  |
3 |     || { &mut x; };
  |          ^^^^^^ cannot borrow as mutable
  |
  = note: Value not mutable causing this error: `x`

error: aborting due to 3 previous errors

The reason is that the borrow of x is inferred as mutable, rather than unique, which means there's an error when creating the closure.

I think the best way to solve this would be to limit borrows of immutable upvars to unique - a mutable borrow can't succeed anyway, so this will only cause errors. We can't change the borrow to be unique, because otherwise AST borrowck will not report an error, but maybe we can do this in MIR construction?

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-NLLArea: Non-lexical lifetimes (NLL)C-bugCategory: This is a bug.NLL-diagnosticsWorking towards the "diagnostic parity" goalT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions