Search code examples
error-handlingrustassociated-types

How can I bound an associated type to work with the `?` operator?


Given the following Rust:

struct E;

trait Fallible {
    type Error: Into<E>;
    fn e(&self) -> Result<(), Self::Error>;
}

fn test(f: &impl Fallible) -> Result<(), E> {
    Ok(f.e()?)
}

I am trying to express that the Fallible::Error type can be converted to an E and therefore should be usable with the ? operator. But, for some reason the ? is based on the From trait, which I'm not sure that it is possible to bound.

This currently fails with:

error[E0277]: `?` couldn't convert the error to `E`
 --> src/lib.rs:9:13
  |
9 |     Ok(f.e()?)
  |             ^ the trait `std::convert::From<<impl Fallible as Fallible>::Error>` is not implemented for `E`
  |
  = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
  = note: required by `std::convert::From::from`

Solution

  • While you cannot bind at the trait level yet, you can do so on the function:

    struct E;
    
    trait Fallible {
        type Error: Into<E>;
        fn e(&self) -> Result<(), Self::Error>;
    }
    
    fn test<T>(f: &T) -> Result<(), E>
    where
        T: Faillible,
        E: From<T::Error>,
    {
        Ok(f.e()?)
    }