`impl Trait` for trait methods?


#1

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?


#2

Do go through the rfc


#3

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  }
}

#4

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.


#5

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.


#6

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.