I'm trying to implement a tiny language interpreter, things works fine until I tried to create a Scope
struct.
In my head, a Scope
definition is as simple as this:
struct Scope<'outer> {
outer_scope: Option<&'outer mut Scope<'outer>>,
// ...other fields
}
impl<'o> Scope<'o> {
fn inner(&mut self) -> Scope<'_> {
Scope {
outer_scope: Some(self),
}
}
}
Unfortunately, this doesn't really work since 'outer
is invariant. So I changed the code to something like this:
struct Scope<'me, 'outer> {
outer_scope: Option<&'me mut Scope<'outer, 'outer>>,
// ...other fields
}
impl<'i: 'o, 'o> Scope<'i, 'o> {
fn inner(&mut self) -> Scope<'_, 'o> {
Scope {
outer_scope: Some(self),
}
}
}
At least the code compiles for now, but it breaks when I calls scope.inner().inner()
.
Playground
A workaround can be made with GAT, but this creates types like Scope<'_, Scope<'_, Scope<'_ ....
My question: Is there a simpler way to express recursive type with mutable borrow?
P.S. Yes I know in this specific case I can alloc all scope in an arena and then all reference to the arena somehow. I'm just wondering if this linked-list-like structure is possible in rust.