Technically, foo.b
points at foo.a
.
struct Foo {
a: i32,
b: Option<&'static mut i32>,
}
let foo = Box::leak(Box::new(Foo { a: 42, b: None }));
let a = &mut foo.a;
let b = foo.b.get_or_insert(a);
(It is rather a joke)
Technically, foo.b
points at foo.a
.
struct Foo {
a: i32,
b: Option<&'static mut i32>,
}
let foo = Box::leak(Box::new(Foo { a: 42, b: None }));
let a = &mut foo.a;
let b = foo.b.get_or_insert(a);
(It is rather a joke)
You don't need to use Box::leak
for this:
struct Foo<'a> {
a: i32,
b: Option<&'a mut i32>,
}
// Foo can't implement Drop:
//impl Drop for Foo<'_> {fn drop(&mut self) {}}
let mut foo = Foo { a: 42, b: None };
// This will borrow `foo.a` for the lifetime of `foo`
foo.b = Some(&mut foo.a);
println!("{:?}", foo.b);
// Can't access `foo.a` again:
// println!("{:?}", foo.a);
Yep, they're possible, just sort of useless. This is a little less restrictive. I don't think I've seen a practical example of either though. The examples I have seen are handled just as well by keeping the structs separate, since the self-referential version gets pinned to the stack anyway.
Edit: Not really true, see next comment
impl<'a> Snek<'a> {
fn bite(&'a mut self) -> &'a Self {
self.borrowed = &self.owned;
self
}
}
Because it requires so many lifetime mechanics like borrow splitting for the assignment and shared reborrowing to be able to return &*self
.
The invariant case is pretty practical, because the example of typed-arena usage falls under this, and that's not uncommon - e. g. rustc
itself is full of this.
E. g.
Note that the lifetime is indeed invariant here (from the invariance of T
in TypedArena<T>
).
Yeah, true.
Ma beloved useless self-ref static statics.
#[derive(Debug)]
struct Foo(&'static Foo);
static FOO: Foo = Foo(&FOO);