@@ -11,36 +11,23 @@ use crate::{fmt, hash, intrinsics, mem, ptr};
1111
1212/// `*mut T` but non-zero and [covariant].
1313///
14- /// This is often the correct thing to use when building data structures using
15- /// raw pointers, but is ultimately more dangerous to use because of its additional
16- /// properties. If you're not sure if you should use `NonNull<T>`, just use `*mut T`!
14+ /// `NonNull<T>` is a non-null raw pointer, commonly used for building data structures with raw pointers.
15+ /// It is **covariant** over `T`, which is the correct choice for most safe abstractions (such as `Box`, `Rc`, `Arc`, `Vec`, etc).
1716///
18- /// Unlike `*mut T`, the pointer must always be non-null, even if the pointer
19- /// is never dereferenced. This is so that enums may use this forbidden value
20- /// as a discriminant -- `Option<NonNull<T>>` has the same size as `*mut T`.
21- /// However the pointer may still dangle if it isn't dereferenced.
17+ /// If you need **invariance** (for example, when implementing types like `Cell<T>`), you can add a marker field to your type:
2218///
23- /// Unlike `*mut T`, `NonNull<T>` was chosen to be covariant over `T`. This makes it
24- /// possible to use `NonNull<T>` when building covariant types, but introduces the
25- /// risk of unsoundness if used in a type that shouldn't actually be covariant.
26- /// (The opposite choice was made for `*mut T` even though technically the unsoundness
27- /// could only be caused by calling unsafe functions.)
28- ///
29- /// Covariance is correct for most safe abstractions, such as `Box`, `Rc`, `Arc`, `Vec`,
30- /// and `LinkedList`. This is the case because they provide a public API that follows the
31- /// normal shared XOR mutable rules of Rust.
19+ /// ```rust
20+ /// use std::marker::PhantomData;
21+ /// use std::cell::Cell;
22+ /// use std::ptr::NonNull;
3223///
33- /// If your type cannot safely be covariant, you must ensure it contains some
34- /// additional field to provide invariance. Often this field will be a [`PhantomData`]
35- /// type like `PhantomData<Cell<T>>` or `PhantomData<&'a mut T>`.
24+ /// struct MyCell<T> {
25+ /// ptr: NonNull<T>,
26+ /// _invariant: PhantomData<Cell<T>>,
27+ /// }
28+ /// ```
3629///
37- /// Notice that `NonNull<T>` has a `From` instance for `&T`. However, this does
38- /// not change the fact that mutating through a (pointer derived from a) shared
39- /// reference is undefined behavior unless the mutation happens inside an
40- /// [`UnsafeCell<T>`]. The same goes for creating a mutable reference from a shared
41- /// reference. When using this `From` instance without an `UnsafeCell<T>`,
42- /// it is your responsibility to ensure that `as_mut` is never called, and `as_ptr`
43- /// is never used for mutation.
30+ /// In most cases, you should use `NonNull<T>` when you want a non-null pointer. If you are unsure, using a raw pointer (`*mut T`) is also fine.
4431///
4532/// # Representation
4633///
0 commit comments