Why does the assigment to a reference kill the loan that was previous assigned to the reference?
โ Rust ๐ 2025-07-30 ๐ค surdeus ๐๏ธ 10Consider this example:
fn main() {
let mut data = vec![1, 2, 3];
let mut x = &data[0];
println!("{}", x); // #0
data.push(4); // #1
x = &data[3]; // #2
println!("{}", x); // #3
}
If there were no #2, #1 would cause the borrowing checker error. This example is a bit like the example in 2094-nll - The Rust RFC Book
let mut foo: T = ...;
let mut bar: T = ...;
let mut p: &T;
p = &foo;
// (0)
if condition {
print(*p);
// (1)
p = &bar;
// (2)
}
// (3)
print(*p);
// (4)
The RFC comments on this example as:
The key point of this example is that the variable
fooshould only be considered borrowed at points 0 and 3, but not point 1.
However, it seems there is no wording that says why foo is not considered to be used at (1). If completing the example as the following like this:
fn main() {
let mut foo = 0;
let mut bar = 1;
let mut p: & /*'p*/ i32;
// --
p = &/*'foo*/ foo;
// ----
if false {
println!("{}",*p);
// (1)
foo = 2;
p = &/*'bar*/ bar;
// ----
}
//foo = 2;
println!("{}",*p);
}
foo = 2; won't cause the borrowing checker error. That implies, the loan ('foo,shared, foo) is not in the point (1) in the CFG, so, it's not considered as a relevant borrowing for the access foo = 2.
The rules for computing loans in the scope are:
For a statement at point P in the graph, we define the โtransfer functionโ โ that is, which loans it brings into or out of scope โ as follows:
- any loans whose region does not include P are killed;
- if this is a borrow statement, the corresponding loan is generated;
- if this is an assignment lv =
<rvalue>, then any loan for some path P of which lv is a prefix is killed.
I don't think the third bullet is saying about p = &/*'bar*/ bar, it intends to say the loan for some path P of which p is prefix. For the loan ('foo,shared, foo), it is not the case.
So, the relevant bullet should be the first one. However, NLL does not define why the region of the loan ('foo,shared, foo) does not include (1)? How to understand this point?
4 posts - 2 participants
๐ท๏ธ Rust_feed