Description
https://doc.rust-lang.org/std/ptr/struct.NonNull.html
If you're not sure if you should use
NonNull<T>
, just use*mut T
!
This is a cop out. I am unsure if I should use NonNull
, but mainly because the rest of the documentation is hard to digest.
The whole explanation of NonNull
doesn't use any terminology or examples that a C programmer can relate to. It feels written from perspective of a language designer, not a language user.
Unlike
*mut T
,NonNull<T>
is covariant overT
.
This property is explained entirely using type theory jargon, and advanced usage of PhantomData
. The documentation assumes that the reader understands the subtle but crucial difference between PhantomData<Cell<T>>
and PhantomData<T>
, which by itself requires understanding of covariance — a catch-22.
This documentation doesn't explain covariance, and unfortunately other sources aren't good either. The Wikipedia page requires a lot of mental effort to extract relevant information from (covariance is explained in terms of "that's how OCaml works" or "preserves the ordering of types (≤) [links deeper into jargon-filled type theory article]").
Usually this won't be necessary; covariance is correct for most safe abstractions, such as Box, Rc, Arc, Vec, and LinkedList.
The Wikipedia page has a whole section explaining that Arrays are only safe if they are invariant, and this note seems to be contradicting it, so this is further confusing (probably because the documentation refers to variance of lifetimes, not inheritance? But this is not documented)
Could usage of NonNull
be explained without relying on type variance terminology? (and subtle typesystem interactions of PhantomData
directly related to it?), e.g. what specific usage would violate the coveriance requirement? What would happen then?