Impl Trait on function in Trait


#1

Hey, I was wondering if there is any way to do something like this:

pub trait Bar {}

pub trait Foo {
    fn get_bar(&self) -> impl Bar where Self: Sized
}

I don’t think this is a supported design of impl Trait, but it would be very nice. At the moment I can do:

pub trait Bar {}

pub trait Foo {
    type ImplBar: bar;

    fn get_bar(&self) -> ImplBar
}

However in cases where the associated types can be very very complex I don’t really want to express the associated type myself, I’d rather let the compiler figure it out for me :slight_smile:


#2

No. Returning impl Trait is only for a single type from single functions. Using it in a traits function would give multiple types so you have to use Box<Bar> or as you write define the type with AT.


#3

Agreed, but I wonder whether this could be possible after adding the restriction where Self: Sized, similar to how generic methods on Iterator exist but do not participate in the trait objects thanks to that restriction.

With more digging I did find the original impl trait rfc briefly mentions that we don’t want to cross that bridge yet, but it doesn’t mention doing something like this there.


#4

I don’t think bare -> impl Trait in trait definitions will ever be allowed, but you will eventually be allowed to use impl Trait in the implementation of a trait with an associated type:

pub trait Bar {}

pub trait Foo {
    type BarType: Bar;
    fn get_bar(&self) -> Self::BarType
}

struct X;
impl Foo for X {
    type BarType = impl Bar;
    fn get_bar(&self) -> Self::BarType { ... }
}

If it’s exactly as https://github.com/rust-lang/rfcs/blob/8ee535b4fcc8bb22c121ad19a36414f1259397c0/text/2071-impl-trait-type-alias.md specifies, the syntax will be with “existential” instead:

struct X;
impl Foo for X {
    existential type BarType;
    fn get_bar(&self) -> Self::BarType { ... }
}

#5

Powerful, thanks very much. I’ll watch the RFC implementation issue closely :slight_smile: