`impl Trait` for trait methods?

I'm experimenting with traits, and I've noticed that while impl Trait is allowed on nightly for inherent methods and functions, it's not allowed to do something like this:

#![feature(conservative_impl_trait)]

trait Foo {}

trait Bar {
    fn fooify(&self) -> impl Foo; // compile error: error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
}

Why is this? Is it simply a matter of the implementation not supporting that yet?
Or are there coherence rules that would be broken by allowing something like this?

3 Likes

Do go through the rfc

1 Like

It only works in hiding the single internal data type returned. You would need to know that single type used in the case of trait members.
e.g. this fails

fn foo(f:bool) -> impl ::std::fmt::Display {
    if f {  1.0  } else {  0  }
}

Alternatively, you can use the Box of the trait as a return type and when implementing the function, you can return the boxed concrete type.

I thought about this, but the usual issues of unnecessary allocation and awkward API apply.
On top of that, I'm implementing a tree-like structure, the types of which all use Arc behind the screens.
So in terms of ownership it doesn't seem to make much sense.
That's why I started looking at impl Trait.

But upon reflecting further I realize now that a proper trait-based abstraction would likely require higher kinded types, especially since ideally the entire thing should be agnostic in terms of using Rc, Arc or some other owning pointer type.

1 Like

I think your original post is better served by an associated type (bound to be a Foo) as the output type. But it’s possible you considered that and rejected it on some grounds.