Expressing &'a T versus T<'a> in a trait object function

Suppose I have a handler trait of sorts that handles types who implement some trait, like this:

trait Handler<T: Foo> {
    fn handle<'a>(&self, what: &'a T) -> Result<&'a T>;
}

(Where Result is some arbitrary type referencing the input.)
This is perferctly ok and works well.

However, I then figured that besides handling things by reference I'd also like to handle stuff like struct Something<'a>(&'a str), which is conceptually similar, but suddenly I don't know how to express this in the trait definition. I can't do this:

trait Handler<T: Foo> {
    fn handle(&self, what: T) -> Result<T>;
}

impl<'a> Handler<Something<'a>> for MyHandler { ... }

... because then the whole trait object is subject to the lifetime, ie. cannot outlive the types passed into the handle() method. But I also can't move the generic type from the trait to the method, because that breaks object safety.

Edit: what also can't be &dyn Foo because the handle() method needs the specific type.

Is it at all possible to solve this in current Rust? What are my options here?

Thanks!

Generic associated types (GAT, still unstable) will let you do something like this:

#![feature(generic_associated_types)]

pub trait Foo {}

pub trait Ref {
    type T<'a>: Foo;
}

pub trait Handler<R: Ref> {
    fn handle<'a>(&self, what: R::T<'a>) -> Result<R::T<'a>, ()>;
}

pub fn trait_object<R: Ref>(_: &dyn Handler<R>) {}

Playground

1 Like

Oh, that looks cool.

I suppose in the meantime a couple of specific traits (rather than a generic one) will do...

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.