Skip to content

Sender could be contravariant if desired #68

@orlp

Description

@orlp

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()
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions