Open jhpratt opened 8 months ago
If you're concerned about the types changing, what do you think about specifying the types in the from
call? Does that help? I realize though that this may not be an entirely satisfactory answer.
As in From::<&T>::from(r)
? That would rely on type inference for the return type, barring some way to do NonNull::from::<&T>(r)
or r.into::<NonNull>()
. While that would be wonderful, I don't see it happening any time soon. I'm looking at this API in the same light as the now-stabilized core::ptr::{from_ref, from_mut}
.
While not the motivating factor, having an API like this would also be const-compatible, unlike a From
-based approach.
As in
From::<&T>::from(r)
? That would rely on type inference for the return type, barring some way to doNonNull::from::<&T>(r)
orr.into::<NonNull>()
.
NonNull::<T>::from(r)
?
Yes, but that doesn't guarantee that the type it's being converted from doesn't change.
Another one I just ran across: NonNull::from_box
would be great, and that currently cannot be done without unsafe
.
NonNull::from_box
can be safely written as NonNull::from(Box::leak(b))
.
Thanks @cuviper. In any situation, the fact that I didn't recognize that should demonstrate some level of need (or at the least documentation).
@jhpratt you could write <NonNull<T> as From<&T>>::from(r)
to absolutely use no inference.
That is extremely verbose for something that (imo) should be quite simple.
That impl
is only possible within the crate that defines Bar
.
And when using NonNull::<_>::from
the only case you are going to accidentally invoke that impl
only if the type of r
is never explicitly specified or inferred to be &T
throughout the entire function.
I think these explicit constructors are fine but the motivation is rather weak.
That is the exact situation we found ourselves in when writing code. We didn't want adding an impl
within the crate to cause issues, which led to the unsafe
indirection. It is admittedly odd (and I brought that up), but I felt an appropriate change would be to be explicit about what is happening.
Proposal
Problem statement
The only way to construct a
NonNull
from a (mutable) reference is to either useNonNull::new_unchecked
orNonNull::from
. The former requiresunsafe
in addition tocore::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
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 usingnew_unchecked
, though this is naturally less than ideal. Internally, I will be introducing an extension trait identical to the below to avoid bothunsafe
and the drawbacks.Solution sketch
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