Skip to content

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

Closed
@arielb1

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

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