Skip to content

MIR-borrowck: behavior around Box<T> is different from AST borrowck #45696

Description

@arielb1

MIR borrowck treats Box<T> differently from AST borrowck (not that AST borrowck is terribly consistent there), for example, in the (simplified) test for #17263:

struct Foo { a: isize, b: isize }

fn main() {
    let mut x: Box<_> = Box::new(Foo { a: 1, b: 2 });
    let (_a, _b) = (&mut x.a, &mut x.b);
    //~^ ERROR cannot borrow `x` (via `x.b`) as mutable more than once at a time
    //~| NOTE first mutable borrow occurs here (via `x.a`)
    //~| NOTE second mutable borrow occurs here (via `x.b`)

    let mut foo: Box<_> = Box::new(Foo { a: 1, b: 2 });
    let (_c, _d) = (&mut foo.a, &foo.b);
    //~^ ERROR cannot borrow `foo` (via `foo.b`) as immutable
    //~| NOTE mutable borrow occurs here (via `foo.a`)
    //~| NOTE immutable borrow occurs here (via `foo.b`)
}
//~^ NOTE first borrow ends here
//~^^ NOTE mutable borrow ends here

AST borrowck reports an error on both lines, but MIR borrowck lets the code pass:

error[E0499]: cannot borrow `x` (via `x.b`) as mutable more than once at a time (Ast)
  --> ../src/test/compile-fail/issue-17263.rs:15:36
   |
15 |     let (_a, _b) = (&mut x.a, &mut x.b);
   |                          ---       ^^^ second mutable borrow occurs here (via `x.b`)
   |                          |
   |                          first mutable borrow occurs here (via `x.a`)
...
25 | }
   | - first borrow ends here

error[E0502]: cannot borrow `foo` (via `foo.b`) as immutable because `foo` is also borrowed as mutable (via `foo.a`) (Ast)
  --> ../src/test/compile-fail/issue-17263.rs:21:34
   |
21 |     let (_c, _d) = (&mut foo.a, &foo.b);
   |                          -----   ^^^^^ immutable borrow occurs here (via `foo.b`)
   |                          |
   |                          mutable borrow occurs here (via `foo.a`)
...
25 | }
   | - mutable borrow ends here

error: aborting due to 2 previous errors

This should be investigated and solved

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-NLLArea: Non-lexical lifetimes (NLL)A-borrow-checkerArea: The borrow checkerNLL-completeWorking towards the "valid code works" goal

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions