Description
check_if_reassignment_to_immutable_state
has the of handling assignments to immutable local variables. These are a bit tricky: you are allowed to assign to an immutable local variable, but only if it has never been assigned to before. Actually, the logic implemented in the NLL borrow checker is kind of wrong (or at least inconsistent with the AST checker). It's also just slow.
Here is an example of the sort of assignments that should be accepted (playground):
#![feature(nll)]
fn main() {
let x: (u32, u32);
if true {
x = (1, 2);
} else {
x = (3, 4);
}
drop(x);
}
This example is rightly rejected (but we should check to ensure we have a test) (playground):
#![feature(nll)]
fn main() {
let x: (u32, u32);
x = (1, 2);
x = (3, 4);
drop(x);
}
This example should be rejected but currently is not (playground):
#![feature(nll)]
fn main() {
let x: (u32, u32);
x.0 = 22;
}
In addition to being slightly wrong, the current implementation is also slow. It iterates over all initialized paths and checks that the path being assigned to (e.g., x.0
in the third example) is disjoint from all of them:
rust/src/librustc_mir/borrow_check/mod.rs
Lines 1612 to 1619 in 52c785b
I will write below how I think it should work.