Motivation: I have several different structures that can store several different kinds of data. I would like to be generic over structures that hold data using generalized associated traits. It's get tricky when one of the structures actually holds a reference to data, with a lifetime.
This minimal example compiles (playground), but what does it do? In the impl for Bar, am I constraining the output to have a lifetime as least as long as 'a? Is there a better way to express this without attaching extra generic parameters to the Swappable trait?
pub struct Foo<A> {
_foo: A
}
pub struct Bar<'a, A> {
_bar: &'a A
}
pub trait Swappable
{
type Output<B> where for<'b> B: 'b;
}
impl <A> Swappable for Foo<A> {
type Output<B> = Foo<B> where for<'b> B: 'b;
}
impl <'a, A> Swappable for Bar<'a, A> {
type Output<B> = Bar<'a, B> where for<'b> B: 'b;
}
pub fn main() {
let _foo: <Foo<i32> as Swappable>::Output<f64> = Foo::<f64> { _foo: 1. };
let x = 1.;
let _bar: <Bar<i32> as Swappable>::Output<f64> = Bar::<f64> { _bar: &x };
}
I’m not completely certain, but I think that it’s equivalent to a B:’static bound:
pub trait Swappable
{
type Output<B:'static>;
}
impl <A> Swappable for Foo<A> {
type Output<B:'static> = Foo<B>;
}
impl <'a, A> Swappable for Bar<'a, A> {
type Output<B:'static> = Bar<'a, B>;
}
Thank you for the clarification! From an ergonomics standpoint, is there any way to make the compiler infer the lifetime without making it a generic parameter to the trait like this? When writing generic functions it would be nice to be able to write T: Swappable instead of T: Swappable<'a>.
pub trait Swappable<'a>
{
type Output<B: 'a>;
}
impl <'a, A: 'a> Swappable<'a> for Foo<A> {
type Output<B: 'a> = Foo<B>;
}
impl <'a, A: 'a> Swappable<'a> for Bar<'a, A> {
type Output<B: 'a> = Bar<'a, B>;
}