oneshot
oneshot copied to clipboard
Sender could be contravariant if desired
The Sender struct has the following comment:
pub struct Sender<T> {
channel_ptr: NonNull<Channel<T>>,
// In reality we want contravariance, however we can't obtain that.
//
// Consider the following scenario:
// ```
// let (mut tx, rx) = channel::<&'short u8>();
// let (tx2, rx2) = channel::<&'long u8>();
//
// tx = tx2;
//
// // Pretend short_ref is some &'short u8
// tx.send(short_ref).unwrap();
// let long_ref = rx2.recv().unwrap();
// ```
//
// If this type were covariant then we could safely extend lifetimes, which is not okay.
// Hence, we enforce invariance.
_invariant: PhantomData<fn(T) -> T>,
}
However it's actually possible to make a contravariant NonNull pointer:
struct ContravariantNonNull<T> {
ptr: NonNull<()>,
_marker: PhantomData<fn(T) -> ()>,
}
impl ContravariantNonNull<T> {
#[inline(always)]
fn as_ptr(&self) -> *mut T {
self.ptr.as_ptr().cast()
}
}
Interesting. I'll look into this when I have the time. Do you know if this actually unlocks any use case or improves the ergonomic in any practical way?
No, nothing comes to mind.