rust-lang / rust-analyzer

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

Hygiene not taken into account for name resolution (wrong type inference with `izip!`) #11681

Open flodiebold opened 2 years ago

flodiebold commented 2 years ago

In this line: https://github.com/rust-analyzer/rust-analyzer/blob/69e5bd5a2532cfe47e5517d720eb70cbf3f4a908/crates/ide_assists/src/handlers/inline_call.rs#L347 we infer the wrong type for expr, namely we infer Vec<PathExpr>. The reason for this seems to be our expansion of the izip!(params, param_use_nodes, arguments) macro call:

$crate::__std_iter::IntoIterator::into_iter(params).zip(param_use_nodes).zip(arguments).map(|((a,b),b)|(a,b,b))

note the .map(|((a,b),b)| (a,b,b)). This seems to be a hygiene issue, where the different bs come from different macro expansions and so we need to consider hygiene to correctly resolve them.

Part of #8961.

lnicola commented 1 week ago

Another example from #17448:

use itertools::izip;

fn main() {
    let mut yp_sn = vec![0;5];
    let yp = vec![0;5];
    let x = vec![0;5];
    for (x, yp_sn, _yp) in izip!(x, yp_sn.iter_mut(), yp) {
        *yp_sn = x;
    }
}

, which triggers a false positive cannot mutate immutable variable. Most likely will be fixed by adding hygiene, but it's still worth testing.