3

I defined a number of TryFrom instances and want to write a function that can use all of these types.

use std::convert::TryFrom;

// several structs like this that are TryFrom<i32>
struct SuperiorThanZero(i32);

impl TryFrom<i32> for SuperiorThanZero {
    type Error = String;

    fn try_from(value: i32) -> Result<Self, Self::Error> {
        unimplemented!()
    }
}

fn from_three<T>() -> Result<T, String>
where
    T: TryFrom<i32>,
{
    T::try_from(3)
}

This does not compile:

error[E0308]: mismatched types
  --> src/lib.rs:16:9
   |
12 |     fn from_three<T>() -> Result<T, String>
   |                           ----------------- expected `std::result::Result<T, std::string::String>` because of return type
...
16 |         T::try_from(3)
   |         ^^^^^^^^^^^^^^ expected struct `std::string::String`, found associated type
   |
   = note: expected type `std::result::Result<_, std::string::String>`
              found type `std::result::Result<_, <T as std::convert::TryFrom<i32>>::Error>`

If I define the error type to be &'static str, the message changes to Expected reference, found associated type.

There are multiple questions about the error Expected associated type, found struct [...], i.e. with associated type and the concrete type swapped, but they don't seem relevant.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
nnnmmm
  • 7,964
  • 4
  • 22
  • 41

1 Answers1

6

The culprit is the trait bound T: TryFrom<i32>. It doesn't specify that the error is String.

To do that, you can write where T: TryFrom<i32, Error = String>.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
nnnmmm
  • 7,964
  • 4
  • 22
  • 41