Problem with lifetime on Trait in impl


#1

Hello,
I have a problem that I have been struggling with for some days. I have a trait that has an associated type and a lifetime bound:

trait MyTrait<'a> {
    type Output;
    fn process(s: &'a [u8]) -> Self::Output;
}

The associated type is used to make the output of process generic. The lifetime bound is there so that the lifetime of the input to the process method can be used in the Output type.

I then define a struct that wraps objects that implement this trait:

struct Wrapper<T>
    where T: for<'a> MyTrait<'a>
{
    inner: T,
}

My thinking is that the lifetime applies to the method on the Trait and is not on the Wrapper. If I put the lifetime on the wrapper, I get an “unused lifetime” error. Because of this I added some syntax that I don’t understand. I am unsure of where I picked up the where for syntax from. I cannot find it in the documentation.

I would like the wrapper to also implement the trait. I would also like the wrapper to use the lifetime on the trait in its Output. Here is a stupid example:

impl<'a, T> MyTrait<'a> for Wrapper<T>
    where T: MyTrait<'a>
{
    type Output = &'a [u8];
    fn process(s: &'a [u8]) -> Self::Output {
        s
    }
}

This is where I get bitten for using syntax that I don’t understand:

error[E0277]: the trait bound `for<'a> T: MyTrait<'a>` is not satisfied

Link to Playground: https://play.rust-lang.org/?gist=425054ace8d46390a349209877a82561&version=stable&backtrace=0

Is there a way of simply fixing this with a bit of syntax, or am I trying to do something doomed to failure?

Thanks in advance for any help.


#2

This looks like a job for PhantomData which lets you mark a type parameter as ‘used’ if you don’t need it on a field. Here’s an updated playground.

To be fair, higher rank trait bounds are really only useful for closures right now, because there isn’t really anything else that can satisfy that for<'a> bound (as that error suggests without hinting at why). In a glorious future version of Rust with associated type constructors you’d be able to do something like this instead:

trait MyTrait {
    type Output<'a>;
    fn process<'a>(s: &'a [u8]) -> Self::Output<'a>;
}

So you don’t need to carry that concrete 'a lifetime around with the definition of MyTrait.

I think I’ve thrown a lot of jargon around in this explanation, if you want some better clarification on anything please ask :slight_smile: