Add alloc::rc::UniqueRc by eholk · Pull Request #111849 · rust-lang/rust (original) (raw)

Ah, I see what you mean. I misinterpreted the original suggestion.

UniqueRc didn't seem like the right name for what I've implemented. While I was writing the documentation, something like PlaceholderRc<T> felt like a better name.

So with UniqueRc, creating a cyclic structure would look more like this, right?

struct Cyclic { this: Weak, }

let mut cycle = UniqueRc::new(Cyclic { this: Weak::new() }; cycle.this = UniqueRc::weak(cycle);

// convert to a normal Rc let rc = UniqueRc::into_rc(cycle);

I'm curious why the Libs API team prefers this approach? I personally find something like PlaceholderRc or UninitializedRc more ergonomic, but I admit this is a matter of preference and I am likely overlooking other concerns around consistency with the rest of std, etc.

One nice property I see for PlaceholderRc is that it's pretty straightforward to implement Rc::new_cyclic in terms of PlaceholderRc. It's less obvious how to do this with UniqueRc, although @joboet's trick of using UniqueRc<MaybeUninit<T>> should work.

I appreciate the discussion here! One thing this has pointed out to me is that it's actually possible to implement this without depending on any internal details of Rc, so it could be done in an external crate (although it would require unsafe code, of course). In our usage of this, we had basically written our own RcBox and transmuted the contents of the Rc into that, which worked but was incredibly fragile. Given the realization we can do this without depending on internal details, I wonder if it makes more sense to try this as an external crate first in the interest of not growing std more than we need to?