Description
Proposal
Problem statement
The only way to construct a NonNull
from a (mutable) reference is to either use NonNull::new_unchecked
or NonNull::from
. The former requires unsafe
in addition to core::ptr::from_ref
or casts for shared references, while the latter does not necessarily guarantee that there is no type conversion taking place.
Motivating examples or use cases
use std::ptr::NonNull;
struct Foo;
struct Bar;
impl From<&Foo> for NonNull<Bar> {
fn from(_: &Foo) -> Self {
unimplemented!()
}
}
We are trying to avoid a situation where adding an implementation like this in conjunction with refactoring would result in a silent change to NonNull::from
. For this reason we are currently using new_unchecked
, though this is naturally less than ideal. Internally, I will be introducing an extension trait identical to the below to avoid both unsafe
and the drawbacks.
Solution sketch
impl<T: ?Sized> NonNull<T> {
#[unstable(feature = "nonnull_from_ref", issue = "TODO")]
#[rustc_const_unstable(feature = "nonnull_from_ref", issue = "TODO")]
pub const fn from_ref(r: &T) -> Self {
// Safety: `r` is a reference that is guaranteed to be non-null.
unsafe { NonNull::new_unchecked(core::ptr::from_ref(r).cast_mut()) }
}
#[unstable(feature = "nonnull_from_ref", issue = "TODO")]
#[rustc_const_unstable(feature = "nonnull_from_ref", issue = "TODO")]
pub const fn from_mut(r: &mut T) -> Self {
// Safety: `r` is a reference that is guaranteed to be non-null.
unsafe { NonNull::new_unchecked(core::ptr::from_mut(r)) }
}
}
Alternatives
As with most library changes, the only alternatives are to not doing this and to leave it to the ecosystem.
Links and related work
N/A