::maybe-dangling
MaybeDangling<T> in stable Rust, as per https://github.com/rust-lang/rfcs/pull/3336
For context, MaybeDangling<T>, is like ManuallyDrop<T>, insofar it does not carry
aliasing/dereferenceable-ity properties w.r.t. the
T it contains. Notably, it means it is allowed to:
- have some expired value inside of them, such as
T = &'expired …, - be fed to a function that does not inspect its value (such as
::core::mem::forget()), - exhibit well-defined behavior (no UB!).
Moreover, contrary to ManuallyDrop<T>, MaybeDangling<T> does not forgo T's drop glue.
Another way to look at it is to say that:
-
there is
MaybeDangling<T>, which is a core primitive type, equivalent toTin almost every aspect (notably, it carries its very same drop glue), except in its lack ofT's default implicitdereferenceable-ity-and-lack-of-aliasing semantics (whereinT's validity invariants mandates that these semantics be active, and remain true, upon every time the type is so much as "looked at" (this includes "inert" assignments or calling functions to it, even a no-op one such asmem::forget())).MaybeDangling<T>forgos and loosens this requirement, excepting "only" as a safety invariant that the safety (and thus, validity) invariants of its innerTbe upheld upon actual use ofT's API, e.g., uponDeref{,Mut}of this wrapper.Notably, this includes, in a wildly dangerous, maybe even footgunny way, its drop, at least whenever
mem::needs_drop::<T>(). -
In order to fix this last remark, another type is offered by the stdlib,
ManuallyDrop<T>, which not only features the very same loose lack-of-dereferenceable-ity-and-lack-of-aliasing semantics ofMaybeDangling<T>, but it also fully disables the inherent/built-in (implicit) drop glue of the overall type. If drop of its innerTis desired, it can be achieved by doing so explicitly, throughManuallyDrop::into_inner()orManuallyDrop::drop()(_in_place).
See the docs of ::core::mem::MaybeDangling for more info about all this.
Currently, whilst MaybeDangling<T> is indeed offered by the stdlib, it is gated behind an unstable feature. This crate offers a polyfill of this, achieved by:
- wrapping
ManuallyDrop<T> - manually implementing
Dropon it to callManuallyDrop::drop().
This does come with one small potential ergonomic issue compared to the stdlib's, related to dropck.
Read the docs of this crate's MaybeDangling<T> for more info about this.
References
-
The RFC that shall eventually and ultimately supersede this very crate: https://github.com/rust-lang/rfcs/pull/3336
-
The
miriPR implementing the check against this: https://github.com/rust-lang/miri/pull/2985 -
The soundness problem of
::ouroborosstemming from not using this: https://github.com/joshua-maros/ouroboros/issues/88 -
The soundness problem of
::yokestemming from not using this: https://github.com/unicode-org/icu4x/issues/3696 -
An URLO thread on the topic, and a post exposing the intention to write this very crate