diff --git a/CHANGELOG.md b/CHANGELOG.md index 137cf92a..53d60a0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- `&'static mut MaybeUninit` now implements `InPlaceWrite`. This enables users to use external + allocation mechanisms such as `static_cell`. + ### Changed - `#[pin_data]` now generates a `*Projection` struct similar to the `pin-project` crate. diff --git a/src/lib.rs b/src/lib.rs index dd553212..c24a8359 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1449,6 +1449,30 @@ pub trait InPlaceWrite { fn write_pin_init(self, init: impl PinInit) -> Result, E>; } +impl InPlaceWrite for &'static mut MaybeUninit { + type Initialized = &'static mut T; + + fn write_init(self, init: impl Init) -> Result { + let slot = self.as_mut_ptr(); + + // SAFETY: `slot` is a valid pointer to uninitialized memory. + unsafe { init.__init(slot)? }; + + // SAFETY: The above call initialized the memory. + unsafe { Ok(self.assume_init_mut()) } + } + + fn write_pin_init(self, init: impl PinInit) -> Result, E> { + let slot = self.as_mut_ptr(); + + // SAFETY: `slot` is a valid pointer to uninitialized memory. + unsafe { init.__pinned_init(slot)? }; + + // SAFETY: The above call initialized the memory. + unsafe { Ok(Pin::static_mut(self.assume_init_mut())) } + } +} + /// Trait facilitating pinned destruction. /// /// Use [`pinned_drop`] to implement this trait safely: