rust-lang / rust-analyzer

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

Type inference for generators #4309

Open DustinByfuglien opened 4 years ago

DustinByfuglien commented 4 years ago
#![feature(generators)]

fn main() {
    let x = || { yield 3 };
}

When using VSCode with this code I notice that:

  1. It seems a yield with argument is reported by analyzer as error.
  2. Also helping hint about x type displays that x have closure type || -> i32 instead of generator trait type.
DustinByfuglien commented 4 years ago

I can illustrate by screenshot.

  1. Rust analyzer red underscored a error but no error is.
  2. Hint shows that x have closure type || -> i32 but really it have generator type

1

ExoticMatter commented 4 years ago

Interestingly, despite the bogus syntax error for no.1, rust-analyzer seems to typecheck yield arguments properly.

fn foo() {
    let bar = || {
        yield "baz";
        yield 0i32;     // E0308: expected `&str`, found `i32`
        yield;          // E0308: expected `&str`, found `()`
    };
}

Demonstration

flodiebold commented 4 years ago

Any such error is coming from cargo check, not rust-analyzer's analysis.

DustinByfuglien commented 4 years ago

Cargo check passed without errors. Program compiled and executed without errors.

flodiebold commented 4 years ago

Sorry, I meant the E308 type checker errors.

Veykril commented 3 years ago

Parsing has been implemented in #7209, type inference is yet to be implemented.

yuhr commented 2 years ago

Type inference for the parameter should also be covered:

fn wrapper(mut generator: impl Generator<i32, Yield = i32> + Unpin) {
    while let Yielded(x) = Pin::new(&mut generator).resume(42) {
        println!("{}", x);
    }
}

fn main() {
    wrapper(|i| { // i: {unknown}
        yield i + 1;
        yield i + 2;
        yield i + 3;
    });
}