I'm building a circular linked list using an arena for the nodes.
If I use a struct like the following it works fine:
struct Node<'a> {
next: Cell<Option<&'a Edge<'a>>>
}
let f = Node { next: Cell::new(None) };
f.next.set(&f);
Having to use an Option<&'a Edge>
is a pain because having the next pointer be None is not a state that I want to have representable in the data structure.
Ideally, I could just use &'a Edge
but creating an initial one node list is difficult.
One option is the following:
struct Edge<'a> {
next: Cell<&'a Edge<'a>>
}
let u: MaybeUninit<Edge> = MaybeUninit::uninit();
let next = unsafe { &(*u.as_ptr()) };
let s = Edge { next: Cell::new(next)};
s.next.set(&s);
That does the job and miri
with -Zmiri-track-raw-pointers
doesn't complain about any undefined behaviour. However,
https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.as_ptr suggests that creating a reference to uninitialized memory is undefined behaviour.
Is there an alternative method of initializing that Edge that I can be more certain isn't undefined behaviour?