Why Isn't There a Read-only Version of `NonNull`?

Why do we have *const T and *mut T, but we don't have NonNull and NonNullMut?

Honestly I don't know what the difference between *const T and *mut T are anyway, other than communicating the intent to the developer about how it is meant to be used. That communication of intent is why I'd wish there was a immutable NonNull pointer.

*const T is covariant in T and *mut T is invariant in T.

You can't do things like overwrite T with a *const T. You have to convert it to a *mut T first.

If you create a *const T directly from a &mut T, it's UB to overwrite the T or do other &mut _-like things through any pointer derived from *const T. If you need &mut-like abilities you need to enter the raw pointer world via *mut. After that you can round-trip through *const T if you want.

...at least in Miri today, not sure how normative that last paragraph is.

Breadcrumbs:

7 Likes

I believe this is not related to the raw pointer being const vs mut. Rather, this is an unfortunate artefact of this particular coercion introducing an intermediate &T reference.

1 Like

Wild guess: it seems pretty dubious to have a raw pointer that you can't write to but that isn't known to point to an initialized value, and therefore could be simply &T.