matklad / once_cell

Rust library for single assignment cells and lazy statics without macros
Apache License 2.0
1.87k stars 109 forks source link

Use MaybeUninit #72

Closed pitdicker closed 4 years ago

pitdicker commented 5 years ago

Replace UnsafeCell<Option<T>> with UnsafeCell<MaybeUninit<T>>.

I included a terrible imitation of MaybeUninit based on Option, so there is no change in behavior right now. The real implementation that uses std::mem::MaybeUninit is behind a feature flag maybe_uninit and only usable with nightly.

I did find one complexity: OnceCell now has to implement Drop itself. Therefore it has to check is_initialized. into_inner now has to use the mem::replace trick to move the value field out of the OnceCell, and then free the cell without dropping (because initialized is not reset).

Conclusion: a bit messy. But I think it makes sense, as a preparation for the future. And it is a plus that is_initialized is now the single source of truth.

pitdicker commented 5 years ago

It probably works better to swap the types to MaybeUninit<UnsafeCell<T>>. Then the decision whether to get a mutable reference or not can be made later. This helps making a nicer abstraction for a consume operation, and the maybe_uninit feature wouldn't depend on nightly. Have to think it through a bit more.

pitdicker commented 5 years ago

Late night ideas don't always work :smile:. To initialize a MaybeUninit<UnsafeCell<T>> you either have to do:

The mention of UnsafeCell in the description of MaybeUninit::as_ptr threw me off.

matklad commented 4 years ago

Turns out we can't use MaybeUninit -- we'll need #[may_dangle] for dropcheck, and it only is avable in nightly.