I'm trying to do something with Rust that I think should be possible, but which I am unclear on how to do.
I have a struct
struct X<'a> {
...
}
There are several structs that will implement the From trait using this trait like so:
struct A {
...
}
impl <'a> From <&'a X<'a>> for A {
...
}
Now, I want my own trait, Y, that guarantees that structs implementing it will also implement trait X. The problem is I don't know what to do with the lifetime parameter. How do I declare Y so that it doesn't itself have a lifetime parameter and so that it ensures implementation of From as demonstrated above?
Unfortunately this is impossible, if a Trait has forced implementation of another trait, then it's logical that the first trait uses everything that the trait it's forcing the implementation of provides. Here is a playground which demonstrates this. Now, then again, trait Y in the example doesn't have to use 'a, it only has to pass it on to XFrom to then be used there. In a sense Y can be oblivious about the lifetime
//dummy from trait
trait X<'a> { }
trait Y: for<'z> X<'z> { }
struct Foo;
struct Bar<'a, 'b: 'a>(&'a &'b ());
impl<'a> X<'a> for Foo {}
impl<'a> Y for Foo {}
impl<'a, 'b: 'a> X<'b> for Bar<'a, 'b> {}
// This won't work because X is not implemented for Bar for *all* lifetimes,
// only those that outlive `'a`
impl<'a, 'b: 'a> Y for Bar<'a, 'b> {}
The change is in the bounds for trait Y, you can see for<'a> X<'a>, this reads as for all lifetimes ('a), Self must implement X<'a>. The catch is that it must be implemented for all lifetimes. As you can see in the example, it is fine to implement Y for Foo because Foo implements X<'a> for all lifetimes 'a, but it is not fine to implemnt Y for Bar because Bar<'a, 'b> only implements X<'b> for all lifetimes 'b that outlive lifetime 'a.
If you have more complex lifetimes requirements, then you will need to propagate lifetimes through your traits.