'Is it possible to initialize a reference to ones self without needing to use an Option?

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?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source