To create a cyclic structure, you can first construct it with a dummy value, get a Weak to your Rc, then use get_mut_unchecked to update the value to something using the Weak.
I think it's possible, but only with restrictions.
pub fn rc_new_cyclic<T: Default>(data_fn: impl FnOnce(&Weak<T>) -> T) -> Rc<T> {
let rc = Rc::new(T::default());
let data = data_fn(&Rc::downgrade(&rc));
assert_eq!(Rc::strong_count(&rc), 1);
// Workaround for not having `Rc::get_mut_unchecked` on stable.
let raw = Rc::into_raw(rc);
// SAFETY: We don't upgrade any of the `Weak`s that exist
// while we write the data to its slot.
*unsafe { &mut *(raw as *mut T) } = data;
unsafe { Rc::from_raw(raw) }
}
Miri doesn't complain about this code, so it does seem to be sound. There is one slight issue that if the destructor of a T::default() value panics this code will leak memory, but that can be easily fixed with a drop guard that recovers the Rc.
Oh, I didn't realize that get_mut_unchecked was unstable. Anyway, by using @Kestrer's workaround for that, you can still do what I suggested.
You can do something that is equivalent to new_cyclic, but I do not think that you could provide a safe API to it because the Weak is not "inaccessible" while constructing the value in the same way as it is with the real new_cyclic.
Luckily, the fix is easy: swap the two T instances first, and only drop the initial one after having done that
unsafe {
let prev: T = ::core::ptr::replace(raw as *mut T, data);
/* Bonus: we could `Rc::from_raw()` here to avoid the leak-on-panic */
drop(prev);
}
I wonder if the following would be sound (since it is less clear-cut, I wouldn't risk it):
unsafe {
let raw_mut: *mut T = raw as *mut T;
::core::ptr::drop_in_place(raw_mut);
// in between these two operations `raw_mut` may be aliased ≠ `*raw_mut = data;`
raw_mut.write(data);
}