The difference between.*const T and *mut T is what API is made available, &mut T access are only allowed on *mut T, but &T access are possible on both, and that *mut T is invariant over (the lifetimes in) T whereas *const T is covariant over T.
The difference is essentially only a conventional lint, as they can be freely (and safely) cast between, and this only changes the API, not what is allowed to do through the pointer; that's the result of provenance (where the pointer came from) instead.
ptr::NonNull<T> is covariant and write-capable, as this is both the correct behavior owning pointers and the most permissive, able to be pared back in usage to match whatever is necessary for unowned cases as well.