rust-lang / rust-analyzer

A Rust compiler front-end for IDEs
https://rust-analyzer.github.io/
Apache License 2.0
14.02k stars 1.55k forks source link

Failed to infer type for await inside an impl block with specific trait bound with associated type #13705

Open xxchan opened 1 year ago

xxchan commented 1 year ago

rust-analyzer version: 0.4.1304-standalone (398a71aff 2022-11-29)

rustc version: rustc 1.66.0-nightly (b8c35ca26 2022-10-15)

relevant settings: (eg. client settings, or environment variables like CARGO, RUSTUP_HOME or CARGO_HOME)

struct T<S> {
    s: S,
}

trait TT: Super1 {
    type Local: Super1;
}

pub trait Super1 {
    type I: std::future::Future<Output = ()> ;
}

pub trait Super2 {
    type I: std::future::Future<Output = ()>;
}

impl<S: TT> T<S> {
    async fn foo() {
        let a = bar();    
        let a = bar().await;

    }
}

async fn bar() -> usize {
    1
}

The second one's type cannot be inferred.

image

Note: If we change one of the Super1 to Super2, it works. e.g.,

trait TT: Super1 {
    type Local: Super2;
}
xxchan commented 1 year ago

Another observation: If we change the output of Super1::I to the same type as bar, it works.

pub trait Super1 {
    type I: std::future::Future<Output = usize> ;
}

If we change it to another one, e.g., u32, it doesn't work again.

xxchan commented 1 year ago

More interestingly, await on any identifier that is not an async fn will get Super1::I::Output

image image
flodiebold commented 1 year ago

Yeah, pretty sure this is a chalk bug, we have a few similar ones, e.g. #10312; it might be a variation of https://github.com/rust-lang/chalk/issues/727.