Skip to content

Commit 7635462

Browse files
Rollup merge of #79841 - fintelia:patch-6, r=kennytm
More clear documentation for NonNull<T> Rephrase and hopefully clarify the discussion of covariance in `NonNull<T>` documentation. I'm very much not an expert so someone should definitely double check the correctness of what I'm saying. At the same time, the new language makes more sense to me, so hopefully it also is more logical to others whose knowledge of covariance basically begins and ends with the [Rustonomicon chapter](https://doc.rust-lang.org/nomicon/subtyping.html). Related to #48929.
2 parents 4d0dd02 + 0392085 commit 7635462

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

library/core/src/ptr/non_null.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,19 @@ use crate::slice::{self, SliceIndex};
1919
/// as a discriminant -- `Option<NonNull<T>>` has the same size as `*mut T`.
2020
/// However the pointer may still dangle if it isn't dereferenced.
2121
///
22-
/// Unlike `*mut T`, `NonNull<T>` is covariant over `T`. If this is incorrect
23-
/// for your use case, you should include some [`PhantomData`] in your type to
24-
/// provide invariance, such as `PhantomData<Cell<T>>` or `PhantomData<&'a mut T>`.
25-
/// Usually this won't be necessary; covariance is correct for most safe abstractions,
26-
/// such as `Box`, `Rc`, `Arc`, `Vec`, and `LinkedList`. This is the case because they
27-
/// provide a public API that follows the normal shared XOR mutable rules of Rust.
22+
/// Unlike `*mut T`, `NonNull<T>` was chosen to be covariant over `T`. This makes it
23+
/// possible to use `NonNull<T>` when building covariant types, but introduces the
24+
/// risk of unsoundness if used in a type that shouldn't actually be covariant.
25+
/// (The opposite choice was made for `*mut T` even though technically the unsoundness
26+
/// could only be caused by calling unsafe functions.)
27+
///
28+
/// Covariance is correct for most safe abstractions, such as `Box`, `Rc`, `Arc`, `Vec`,
29+
/// and `LinkedList`. This is the case because they provide a public API that follows the
30+
/// normal shared XOR mutable rules of Rust.
31+
///
32+
/// If your type cannot safely be covariant, you must ensure it contains some
33+
/// additional field to provide invariance. Often this field will be a [`PhantomData`]
34+
/// type like `PhantomData<Cell<T>>` or `PhantomData<&'a mut T>`.
2835
///
2936
/// Notice that `NonNull<T>` has a `From` instance for `&T`. However, this does
3037
/// not change the fact that mutating through a (pointer derived from a) shared

0 commit comments

Comments
 (0)