Warning
This post was published 47 days ago. The information described in this article may have changed.
An imaginary self-referential mode that would work in Rust might be
struct A<'a> {
ptr: Option<&'a A<'a>>,
}
fn main() {
let mut a = A { ptr: None };
a.ptr = Some(&a);
}
However, this code is not compiled. The error is
error[E0506]: cannot assign to `a.ptr` because it is borrowed
--> src/main.rs:6:5
|
6 | a.ptr = Some(&a);
| ^^^^^^^^^^^^^--^
| | |
| | `a.ptr` is borrowed here
| `a.ptr` is assigned to here but it was already borrowed
| borrow later used here
Does the borrowing checker forbid us from writing the self-referential structure in Rust?
NLL RFC seems to cover this case.
&a
is borrowed for lifetime 'a
, which keeps alive until a
deads. According to the RFC: An assignment statement LV = RV
is a shallow write to LV
;
So, the relevant borrowings for a.ptr
are determined by this rule:
For shallow accesses to the path
lvalue
, we consider borrows relevant if they meet one of the following criteria:
- [...]
- there is a loan for some prefix of the path
lvalue
;
So, &a
is that relevant borrowing, which is the in-scope loan at LV = RV
. The access to a.ptr
is Write, and the relevant borrowing exists. They conflict with each other. So, the borrowing checker reports the error.
Is this the reason why we cannot write out self-referential structures in Rust?
Is this the mechanism of how the borrowing checker forbids us from creating a self-referential structure?
9 posts - 3 participants
🏷️ rust_feed