Need help extending a trait

Hi everyone,

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?

Thanks in advance!

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

Thanks! Very helpful. Your explanation makes sense.

Actually it is possible, but there is a catch

This is an editted version of @OptimisticPeach’s example
playground link

//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.

Oh, that’s interesting! I wasn’t aware that there were lifetime parameters available in for, where is it mentioned in the docs?

The Rust nomicon has it, you can also search for it under Higher Rank Type Bounds (HRTB)

https://doc.rust-lang.org/nomicon/hrtb.html


please note that this has nothing to do with for loops. Even though they share some syntax

1 Like