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

mislead type ascribed to collection in a for loop diagnostic error #97163

Closed
pnkfelix opened this issue May 19, 2022 · 1 comment · Fixed by #97531
Closed

mislead type ascribed to collection in a for loop diagnostic error #97163

pnkfelix opened this issue May 19, 2022 · 1 comment · Fixed by #97531
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. D-confusing Diagnostics: Confusing error or lint that should be reworked. D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information.

Comments

@pnkfelix
Copy link
Member

I tried this code (playground):

use std::collections::HashMap;

fn main() {
    let mut map = HashMap::new();
    map.insert(('a', 'b'), ('c', 'd'));
    
    for ((_, _), (&mut c, _)) in &mut map {
        if c == 'e' { }
    }
}

I expected to see this happen: I expect an error, but I expect the diagnostic to report types that corespond to all the expressions involved.

Instead, this happened: Part of the error diagostic claims that &mut map has type Option<(&(char, char), &mut (char, char))>

This is very confusing. In a simple case this I am certain that &mut map does not have that type, and it just ends up distracting me from the rest of the message (which does try to indicate what is wrong. But in a more complex case, where its not obvious that the compiler is misleading me, I end up wasting my time trying to figure out why map is getting a value of the wrong type here.

Herei is the specific diagnostic output I am seeing:

error[[E0308]](https://doc.rust-lang.org/nightly/error-index.html#E0308): mismatched types
 --> src/main.rs:7:19
  |
7 |     for ((_, _), (&mut c, _)) in &mut map {
  |                   ^^^^^^         -------- this expression has type `Option<(&(char, char), &mut (char, char))>`
  |                   |
  |                   expected `char`, found `&mut _`
  |                   help: you can probably remove the explicit borrow: `c`
  |
  = note:           expected type `char`
          found mutable reference `&mut _`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to previous error
@pnkfelix pnkfelix added the C-bug Category: This is a bug. label May 19, 2022
@compiler-errors compiler-errors added A-diagnostics Area: Messages for errors, warnings, and lints D-confusing Diagnostics: Confusing error or lint that should be reworked. D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information. labels May 19, 2022
@compiler-errors
Copy link
Member

This is due to for-loop desugaring -- specifically, the same span is used for the IntoIterator value as the temporary variable of iterator.next(), so this is really reporting that the iterator's element has the wrong type.

Preferably we report something like "this expression is an iterator with elements of type Option<...>". I think I have somewhere in my git-stash a fix for this, I'll try to salvage it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. D-confusing Diagnostics: Confusing error or lint that should be reworked. D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants