1

Here's the code I would like to compile:

struct Error {}

trait Foo {
    type FooError;
    fn fallible_function() -> Result<(), Self::FooError>;
}

trait SubFoo: Foo
where
    Error: From<<Self as Foo>::FooError>,
{
}

fn some_function<T: SubFoo>(object: T) {}

Unfortunately, it won't compile without repeating the From trait bound under some_function, like this:

fn some_function<T: SubFoo>(object: T)
where
    Error: From<<T as Foo>::FooError>,
{
}

That defeats the point though, as the point of SubFoo is to reduce the boilerplate on the many points where its fully described supertraits would be used (you can imagine this is a lot more bulky in my real code than in this simplified snippet). I'm aware the reason why this doesn't work is this issue, which appears to be a little bit stuck in limbo (with the possible implication that nothing you could ever express here is inexpressible with normal trait bounds, outside a where clause?)

Since the above is a no-go until that issue gets closed, I'm looking for alternative solutions to my problem. Pulling the associated_type_bounds unstable feature, at least I'm able to express a similar constraint:

#![feature(associated_type_bounds)]

struct Error {}

trait Foo {
    type FooError;
    fn fallible_function() -> Result<(), Self::FooError>;
}

trait SubFoo: Foo<FooError: Into<Error>> {}

This is almost fine (and to be fair, looks a lot more elegant than the where clause before). However, it won't cut it for two reasons:

  • Where From<A> for B implies Into<B> from A, the reverse is not true.
  • The ? operator requires From<FooError> for Error

I can't think of a way to encode the From<FooError> for Error requirement in the supertrait bound without using a where clause. Am I missing a key bit of syntax here, or am I out of luck?

I can't do this:

trait Foo
where
    Error: From<Self::FooError>,
{
    type FooError;
    fn fallible_function() -> Result<(), Self::FooError>;
}

In my real code, this would break encapsulation (the module where Foo lives has no reason to see the top level Error struct).

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Cuervo
  • 31
  • 2
  • 1
    Welcome to StackOverflow! This is a very well-researched question. I got a few ideas what to try while reading this, but you already tried all of them yourself. – Sven Marnach Aug 03 '20 at 20:23

0 Answers0