Skip to content

Tuple parameters are {unknown} #12331

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

Closed
Barugon opened this issue May 20, 2022 · 5 comments
Closed

Tuple parameters are {unknown} #12331

Barugon opened this issue May 20, 2022 · 5 comments
Labels
A-ty type system / type inference / traits / method resolution C-bug Category: bug

Comments

@Barugon
Copy link

Barugon commented May 20, 2022

rust-analyzer version: rust-analyzer version: 7e95c14 2022-05-17 stable

rustc version: rustc 1.61.0 (fe5b13d68 2022-05-18)

relevant settings: none

Rust Analyzer gets confused about the tuple parameters in the following code (the logic here is dumb but it's simply to illustrate):

fn main() {
    let mut item = None;
    loop {
        if let Some((id, _, _)) = item {
            if id == 1 {
                break;
            }
        }

        item = Some((1, 2.5, String::new()));
    }
}

The result is this:

Screenshot from 2022-05-20 09-19-29

@flodiebold flodiebold added A-ty type system / type inference / traits / method resolution C-bug Category: bug labels May 20, 2022
@ruabmbua
Copy link
Contributor

I started reducing the example to find out what is happening.

I arrived at this, and I think I have found a clue what is going on:

fn main() {
    enum Option<T> {Some(T), None}
    use Option::*;

    let mut item = None;
   // Infers to Option<(i32, {unknown})>

    if let Some((_a, _)) = item {
    }

    item = Some((1, 2));
}

// Other example:
fn main() {
    enum Option<T> {Some(T), None}
    use Option::*;

    let mut item = None;
   // Infers to Option<({unknown}, i32)>

    if let Some((_, _a)) = item {
    }

    item = Some((1, 2));
}

So it has nothing to do with the loop, its just about a pattern match appearing before the first (fully type-resolvable) assignment. It only happens, when tuples are involved (according to my few tests), and when the pattern matching uses the _ placeholder anywhere. If the pattern matching actually binds the value to an identifier like _a there is no problem.

@ruabmbua
Copy link
Contributor

So somehow the _ in a pattern matching stops the inference from working on that particular part of the type.

@Barugon
Copy link
Author

Barugon commented May 22, 2022

So it has nothing to do with the loop, its just about a pattern match appearing before the first (fully type-resolvable) assignment. It only happens, when tuples are involved (according to my few tests), and when the pattern matching uses the _ placeholder anywhere. If the pattern matching actually binds the value to an identifier like _a there is no problem.

Right. If I do this then it works.

fn main() {
    let mut item = None;
    loop {
        item = Some((1, 2.5, String::new()));

        if let Some((id, _, _)) = item {
            if id == 1 {
                break;
            }
        }
    }
}

@flodiebold
Copy link
Member

Good catch. I suspect changing

expectations.iter().map(|a| a.assert_ty_ref(Interner)).chain(repeat(&err_ty));

to use repeat_with(|| self.table.new_type_var()) might be the fix, but I don't have time to test it right now.

bors added a commit that referenced this issue May 23, 2022
…odiebold

Fix inference when pattern matching a tuple field with a wildcard

This should fix the following issue:  #12331

* Replaced the `err_ty` in `infer_pat()` with a new type variable.
* Had to change the iterator code a bit, to get around multiple mutable borrows of `self` in `infer_pat()`.
Also added a test
* Also added a test
@ruabmbua
Copy link
Contributor

Tested again the original mentioned code, fixed by #12355

@lnicola lnicola closed this as completed May 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ty type system / type inference / traits / method resolution C-bug Category: bug
Projects
None yet
Development

No branches or pull requests

4 participants