Type inferencer probably could figure this case out (associated types)

092c3a6
Opened by Carl Lerche at 2023-04-05 17:36:41
trait Async {
    type Value;
    type Error;
}

enum Result<T, E> {
    Ok(T),
    Err(E),
}

impl<T, E> Result<T, E> {
    fn reduce<F, U>(self, init: U::Value, action: F) -> U::Value
            where F: Fn(U::Value, T) -> U,
                  U: Async<Error=E> {
        unimplemented!();
    }
}

impl Async for i32 {
    type Value = i32;
    type Error = ();
}

pub fn main() {
    let res: Result<&'static str, ()> = Result::Ok("hello");
    let val: i32 = 123;

    res.reduce(val, |val /* i32 */, curr| val);
    // Compiles if annotated ^^
}

cc @nikomatsakis

  1. This requires two features which have not been implemented yet: #19476 and #21939 - and I'm not certain on the interaction between the two.

    Eduard-Mihai Burtescu at 2015-03-26 06:53:11

  2. Carl, I think you could workaround this limitation by introducing another type parameter:

    impl<T, E> Result<T, E> {
        fn reduce<F, U, X>(self, init: X, action: F) -> U::Value
                where F: Fn(X, T) -> U,
                      U: Async<Error=E, Value=X> {
            unimplemented!();
        }
    }
    

    Indeed this works in play.

    I'm actually not sure why it's not working today. I think what should be happening is that when we try to normalize $U::Value, where $U is the variable we created for U, we wind up with a type variable $1 and the side-constraint that $U: Async<Value=$1>. Clearly $1 will get unified with i32 and then $U should (through the return value) be unified with $1. This seems like enough to figure out everything that is needed. But you do get an error, so presumably something goes wrong at an earlier point in the process, I'm not quite sure what.

    Niko Matsakis at 2015-03-26 17:14:18

  3. Oh, my bad, I didn't realize U::Value was being fed i32 from passing val into the call.

    Eduard-Mihai Burtescu at 2015-03-26 19:06:09

  4. Triage: this still reproduces today.

    Steve Klabnik at 2016-11-15 20:21:03

  5. Triage: no change

    Steve Klabnik at 2018-09-24 15:57:46

  6. Triage: no change

    Maayan Hanin at 2022-03-22 10:41:25