Variance of lifetime arguments in GATs

The way I have incorporated explicit variance into a trait in the past is via requiring the implementor to provide an upcast implementation compatible with the variance that I need.

Zero unsafe code required:

#![feature(generic_associated_types)]
#![allow(incomplete_features)]

pub trait Trait {
    type GAT<'a>: Eq;

    fn upcast_gat<'short, 'long: 'short>(long: Self::GAT<'long>) -> Self::GAT<'short>;
}

impl Trait for () {
    type GAT<'a> = &'a str;

    fn upcast_gat<'short, 'long: 'short>(long: &'long str) -> &'short str { long }
}

pub fn eq<T: Trait>(left: T::GAT<'_>, right: T::GAT<'_>) -> bool {
    T::upcast_gat(left) == T::upcast_gat(right)
}
21 Likes