Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple Iterator generic parameters confuse the type inference #15145

Closed
TDplai opened this issue Jun 27, 2023 · 2 comments
Closed

Multiple Iterator generic parameters confuse the type inference #15145

TDplai opened this issue Jun 27, 2023 · 2 comments
Labels
C-bug Category: bug

Comments

@TDplai
Copy link

TDplai commented Jun 27, 2023

rust-analyzer gets confused about IntoIterator::Item types when multiple generic parameters implement IntoIterator.

Example:

pub fn item_type_confusion<'a, I: IntoIterator<Item = &'a mut usize>, I2: IntoIterator>(it: I) {
    for a in it {
        // rust-analyzer reports error: cannot mutate immutable variable `a`
        *a += 1;
    }
}

This error is only reported in rust-analyzer. The function compiles without errors. Furthermore, neither cargo check nor cargo clippy report any errors.

The hover-text on a is a: {unknown}, which shows that rust-analyzer was unable to infer the type of a.

This occurs even when I and I2 have the same Item type:

pub fn analyzer_confusion<
    'a,
    I: IntoIterator<Item = &'a mut usize>,
    I2: IntoIterator<Item = &'a mut usize>,
>(
    i1: I,
) {
    for a in i1 {
        // rust-analyzer reports error: cannot mutate immutable variable `a`
        *a += 1;
    }
}

If I coerce a into an &mut usize, the error goes away:

pub fn item_type_confusion<'a, I: IntoIterator<Item = &'a mut usize>, I2: IntoIterator>(it: I) {
    for a in it {
        let _: &mut usize = a;
        // no error reported
        *a += 1;
    }
}

rust-analyzer does recognise that a is an &mut usize when printing a type error, but still claims that *a is immutable:

pub fn item_type_confusion<'a, I: IntoIterator<Item = &'a mut usize>, I2: IntoIterator>(it: I) {
    for a in it {
        // rust-analyzer reports the expected error: expected `u64`, found `&mut usize`
        let _: u64 = a;
        // rust-analyzer reports error: cannot mutate immutable variable `a`
        *a += 1;
    }
}

Furthermore, if I2: IntoIterator is removed, the error goes away:

pub fn item_type_confusion<'a, I: IntoIterator<Item = &'a mut usize>, I2>(it: I) {
    for a in it {
        // no error reported
        *a += 1;
    }
}

rust-analyzer version: rust-analyzer 1.72.0-nightly (8084f39 2023-06-25)

rustc version: rustc 1.72.0-nightly (8084f397c 2023-06-25)

relevant settings:
CARGO_HOME is set to $HOME/.local/share/cargo
RUSTUP_HOME is set to $HOME/.local/share/rustup
RUSTC_WRAPPER is set to sccache
rust-analyzer settings are:

["rust-analyzer"] = {
	cargo = {
		features = "all",
	},
	checkOnSave = {
		command = "clippy",
		allFeatures = true,
		extraArgs = { "--", "-W", "clippy::pedantic" },
	},
},

(this is copied verbatim from my Neovim configuration)

@TDplai TDplai added the C-bug Category: bug label Jun 27, 2023
@TDplai
Copy link
Author

TDplai commented Jun 27, 2023

In further testing, if I coerce a into &mut _, rust-analyzer is able to infer the usize part.

pub fn analyzer_confusion<'a, I: IntoIterator<Item = &'a mut usize>, I2: IntoIterator>(i1: I) {
    for a in i1 {
        let _: &mut _ = a;
        // no error reported
        *a += 1;
    }
}

@lowr
Copy link
Contributor

lowr commented Jun 27, 2023

Thanks for the report -- this is a known issue that needs to be solved in an upstream library: rust-lang/chalk#750. Closing as a duplicate of #10653.

@lowr lowr closed this as not planned Won't fix, can't repro, duplicate, stale Jun 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: bug
Projects
None yet
Development

No branches or pull requests

2 participants