Skip to content

Error for for _ in HashMap::new().iter().cloned() { } doesn't provide enough context #33941

Closed

Description

@niconii

Playpen

use std::collections::HashMap;

fn main() {
    for _ in HashMap::new().iter().cloned() { }
}

.cloned() failing is normal since the iterator's items are (&K, &V) and .cloned() expects &T, but the number of errors is strange.

error: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as std::iter::Iterator>::Item == &_`:
 expected tuple,
    found &-ptr [--explain E0271]
 --> <anon>:4:36
4 |>     for _ in HashMap::new().iter().cloned() { }
  |>                                    ^^^^^^

error: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as std::iter::Iterator>::Item == &_`:
 expected tuple,
    found &-ptr [--explain E0271]
 --> <anon>:4:5
4 |>     for _ in HashMap::new().iter().cloned() { }
  |>     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required because of the requirements on the impl of `std::iter::Iterator` for `std::iter::Cloned<std::collections::hash_map::Iter<'_, _, _>>`

error: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as std::iter::Iterator>::Item == &_`:
 expected tuple,
    found &-ptr [--explain E0271]
 --> <anon>:4:5
4 |>     for _ in HashMap::new().iter().cloned() { }
  |>     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required because of the requirements on the impl of `std::iter::Iterator` for `std::iter::Cloned<std::collections::hash_map::Iter<'_, _, _>>`

error: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as std::iter::Iterator>::Item == &_`:
 expected tuple,
    found &-ptr [--explain E0271]
 --> <anon>:4:5
4 |>     for _ in HashMap::new().iter().cloned() { }
  |>     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required because of the requirements on the impl of `std::iter::Iterator` for `std::iter::Cloned<std::collections::hash_map::Iter<'_, _, _>>`
note: required by `std::iter::IntoIterator::into_iter`

error: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as std::iter::Iterator>::Item == &_`:
 expected tuple,
    found &-ptr [--explain E0271]
 --> <anon>:4:5
4 |>     for _ in HashMap::new().iter().cloned() { }
  |>     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required because of the requirements on the impl of `std::iter::Iterator` for `std::iter::Cloned<std::collections::hash_map::Iter<'_, _, _>>`
note: required by `std::iter::IntoIterator::into_iter`

error: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as std::iter::Iterator>::Item == &_`:
 expected tuple,
    found &-ptr [--explain E0271]
 --> <anon>:4:5
4 |>     for _ in HashMap::new().iter().cloned() { }
  |>     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required because of the requirements on the impl of `std::iter::Iterator` for `std::iter::Cloned<std::collections::hash_map::Iter<'_, _, _>>`
note: required because of the requirements on the impl of `std::iter::IntoIterator` for `std::iter::Cloned<std::collections::hash_map::Iter<'_, _, _>>`

error: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as std::iter::Iterator>::Item == &_`:
 expected tuple,
    found &-ptr [--explain E0271]
 --> <anon>:4:5
4 |>     for _ in HashMap::new().iter().cloned() { }
  |>     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required because of the requirements on the impl of `std::iter::Iterator` for `std::iter::Cloned<std::collections::hash_map::Iter<'_, _, _>>`

error: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as std::iter::Iterator>::Item == &_`:
 expected tuple,
    found &-ptr [--explain E0271]
 --> <anon>:4:5
4 |>     for _ in HashMap::new().iter().cloned() { }
  |>     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required because of the requirements on the impl of `std::iter::Iterator` for `std::iter::Cloned<std::collections::hash_map::Iter<'_, _, _>>`
note: required by `std::iter::Iterator::next`

error: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as std::iter::Iterator>::Item == &_`:
 expected tuple,
    found &-ptr [--explain E0271]
 --> <anon>:4:5
4 |>     for _ in HashMap::new().iter().cloned() { }
  |>     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required because of the requirements on the impl of `std::iter::Iterator` for `std::iter::Cloned<std::collections::hash_map::Iter<'_, _, _>>`

error: aborting due to 9 previous errors

Activity

  1. DoumanAsh commented on May 29, 2016

    @DoumanAsh

    I also think the error should be improved.
    Especially because you bluntly show user API that cannot be compiled.
    I'm ofc talking about HashMap's iter docs

  2. estebank commented on Sep 30, 2017

    @estebank
    Contributor

    Current output:

    error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as std::iter::Iterator>::Item == &_`
     --> src/main.rs:4:36
      |
    4 |     for _ in HashMap::new().iter().cloned() { }
      |                                    ^^^^^^ expected tuple, found reference
      |
      = note: expected type `(&_, &_)`
                 found type `&_`
    
    error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as std::iter::Iterator>::Item == &_`
     --> src/main.rs:4:14
      |
    4 |     for _ in HashMap::new().iter().cloned() { }
      |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected tuple, found reference
      |
      = note: expected type `(&_, &_)`
                 found type `&_`
      = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::iter::Cloned<std::collections::hash_map::Iter<'_, _, _>>`
    

    There are two problems here that can be tackled independently:

    1. The duplicated E0271 type mismatch errors can be fixed by modifying report_projection_error to not emit the diagnostic immediately, but rather to modify InferCtxt to keep a hashset of (expected_type, found_type, Span) so that the same error isn't emitted multiple times. All the duplicated errors (from the second onwards) seem to be caused by the implicit handling of iterators. Bonus points for collecting all the obligations and emitting them all together in the same diagnostic, instead of just losing the latter ones (requires either finding a method that gets called always at the end, or adding one). Done.

    2. The error itself is not very illuminating and should have extra information provided in order to be helpful. For the case in particular of hash_map::Iter, it would be great if we could suggest the following, as that would actually do what the user expects (other than a missing type definition for the HashMap, on real code the HashMap would have been created before so that it would have had a chance to be populated), but I don't know how we could accomplish that in a clean way:

     --> src/main.rs:4:5
      |
    4 |     for _ in HashMap::new().iter().cloned() { }
      |     ^^^^^^^^^^^^^^^^^^^^^^^-------^^^^^^^^^^^^^ expected tuple, found reference
      |                             |
      |                             help: did you mean to use `values()` here?
    

    In general, it would probably be nice to have something along the lines of the following output on cases where type errors are propagated down a method call chain, but it's non-trivial to do and would still add little help here, so it should be out of scope of this issue:

    error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as std::iter::Iterator>::Item == &_`
     --> src/main.rs:4:5
      |
    4 |     for _ in HashMap::new().iter().cloned() { }
      |     ^^^^^^^^^--------------^------^--------^^^^ expected tuple, found reference
      |              |              |      |
      |              |              |      found `&_` here
      |              |              found `std::collections::hash_map::Iter<'_, _, _>` here
      |              found `std::collections::HashMap<_, _>` here
      |
      = note: expected type `(&_, &_)`
                 found type `&_`
      = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::iter::Cloned<std::collections::hash_map::Iter<'_, _, _>>`
    
  3. added
    E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.
    on Sep 30, 2017
  4. added a commit that references this issue on Nov 13, 2017
  5. removed
    E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.
    on Feb 12, 2018
  6. changed the title [-]`for _ in HashMap::new().iter().cloned() { }` produces 9 (near-)duplicate errors[/-] [+]Error for `for _ in HashMap::new().iter().cloned() { }` doesn't provide enough context[/+] on May 22, 2019
  7. estebank commented on Jan 22, 2020

    @estebank
    Contributor

    Triage: no change.

  8. added
    D-confusingDiagnostics: Confusing error or lint that should be reworked.
    D-papercutDiagnostics: An error or lint that needs small tweaks.
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Jan 22, 2020
  9. yihuang commented on Jun 14, 2020

    @yihuang
    Contributor

    I wonder is there handy utils to convert (&K, &V) into (K, V) without writing a closure?

  10. added 4 commits that reference this issue on Dec 14, 2022
    567d887
    2a5d257
    ad8be3e
    622f560
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.D-confusingDiagnostics: Confusing error or lint that should be reworked.D-papercutDiagnostics: An error or lint that needs small tweaks.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.WG-diagnosticsWorking group: Diagnostics

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions