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

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

Closed
niconii opened this issue May 29, 2016 · 4 comments · Fixed by #105674
Closed
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. D-confusing Diagnostics: Confusing error or lint that should be reworked. D-papercut Diagnostics: An error or lint that needs small tweaks. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-diagnostics Working group: Diagnostics

Comments

@niconii
Copy link
Contributor

niconii commented May 29, 2016

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
@DoumanAsh
Copy link

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

@nagisa nagisa added the A-diagnostics Area: Messages for errors, warnings, and lints label May 29, 2016
@Mark-Simulacrum Mark-Simulacrum added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Jul 25, 2017
@estebank
Copy link
Contributor

estebank commented Sep 30, 2017

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<'_, _, _>>`

@estebank estebank added E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. WG-diagnostics Working group: Diagnostics labels Sep 30, 2017
zackmdavis added a commit to zackmdavis/rust that referenced this issue Nov 13, 2017
The `ErrorId` variant takes a u16 so that `DiagnosticMessageId` can retain
its `Copy` status (the present author's first choice having been the "EXXX"
code as a string).

The duplicated "type mismatch resolving `{}`" literal is unfortunate, but
the `struct_span_err!` macro (which we want to mark that error code as
used) is fussy about taking a literal, and the one-time-diagnostics set
needs an owned string.

This is concerning rust-lang#33941 and probably rust-lang#45805!
kennytm added a commit to kennytm/rust that referenced this issue Nov 13, 2017
…stebank

deduplicate projection error (E0271) messages

The `ErrorId` variant takes a u16 so that `DiagnosticMessageId` can retain
its `Copy` status (the present author's first choice having been the "EXXX"
code as a string).

The duplicated "type mismatch resolving `{}`" literal is unfortunate, but
the `struct_span_err!` macro (which we want to mark that error code as
used) is fussy about taking a literal, and the one-time-diagnostics set
needs an owned string.

This is concerning rust-lang#33941 and probably rust-lang#45805!

r? @estebank
@estebank estebank removed the E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. label Feb 12, 2018
@estebank estebank 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 May 22, 2019
@estebank
Copy link
Contributor

Triage: no change.

@estebank estebank added D-confusing Diagnostics: Confusing error or lint that should be reworked. D-papercut Diagnostics: An error or lint that needs small tweaks. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 22, 2020
@yihuang
Copy link

yihuang commented Jun 14, 2020

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

estebank added a commit to estebank/rust that referenced this issue May 10, 2022
```
error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as Iterator>::Item == &_`
  --> $DIR/issue-33941.rs:6:36
   |
LL |     for _ in HashMap::new().iter().cloned() {}
   |              ------------   ----   ^^^^^^ expected reference, found tuple
   |              |              |
   |              |              this call is of type `std::collections::hash_map::Iter<'_, _, _>`
   |              this call is of type `&HashMap<_, _>`
   |
   = note: expected reference `&_`
                  found tuple `(&_, &_)`
note: required by a bound in `cloned`
  --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
   |
LL |         Self: Sized + Iterator<Item = &'a T>,
   |                                ^^^^^^^^^^^^ required by this bound in `cloned`
```

Partially address rust-lang#33941.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Dec 14, 2022
Point at method chains on `E0271` errors

Follow up to rust-lang#105332. Fix rust-lang#33941. CC rust-lang#9082.

r? `@oli-obk`
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Dec 14, 2022
Point at method chains on `E0271` errors

Follow up to rust-lang#105332. Fix rust-lang#33941. CC rust-lang#9082.

r? ``@oli-obk``
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Dec 15, 2022
Point at method chains on `E0271` errors

Follow up to rust-lang#105332. Fix rust-lang#33941. CC rust-lang#9082.

r? ```@oli-obk```
@bors bors closed this as completed in 622f560 Dec 16, 2022
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-enhancement Category: An issue proposing an enhancement or a PR with one. D-confusing Diagnostics: Confusing error or lint that should be reworked. D-papercut Diagnostics: An error or lint that needs small tweaks. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-diagnostics Working group: Diagnostics
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants