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

Confusing/incorrect "&mut &mut [T] is not an iterator" #84837

Closed
Soveu opened this issue May 2, 2021 · 5 comments · Fixed by #106360
Closed

Confusing/incorrect "&mut &mut [T] is not an iterator" #84837

Soveu opened this issue May 2, 2021 · 5 comments · Fixed by #106360
Labels
A-diagnostics Area: Messages for errors, warnings, and lints D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Soveu
Copy link
Contributor

Soveu commented May 2, 2021

Given the following code:

let mut v: Vec<u8> = Vec::new();
for _ in &mut &mut v {}
let mut v: &mut [u8] = &mut [];
for _ in &mut v {}

The current output is:

error[E0277]: `Vec<u8>` is not an iterator
 --> src/main.rs:4:14
  |
4 |     for _ in &mut &mut v {}
  |              ^^^^^^^^^^^ `Vec<u8>` is not an iterator
  |
  = help: the trait `Iterator` is not implemented for `Vec<u8>`
  = note: required because of the requirements on the impl of `Iterator` for `&mut Vec<u8>`
  = note: 1 redundant requirements hidden
  = note: required because of the requirements on the impl of `Iterator` for `&mut &mut Vec<u8>`
  = note: required because of the requirements on the impl of `IntoIterator` for `&mut &mut Vec<u8>`
  = note: required by `into_iter`
error[E0277]: `[u8]` is not an iterator
 --> src/main.rs:3:14
  |
3 |     for _ in &mut v {}
  |              ^^^^^^ `[u8]` is not an iterator
  |
  = help: the trait `Iterator` is not implemented for `[u8]`
  = note: required because of the requirements on the impl of `Iterator` for `&mut [u8]`
  = note: 1 redundant requirements hidden
  = note: required because of the requirements on the impl of `Iterator` for `&mut &mut [u8]`
  = note: required because of the requirements on the impl of `IntoIterator` for `&mut &mut [u8]`
  = note: required by `into_iter`

Ideally it would say that &mut &mut T is not an iterator and maybe suggest removing &mut.
On the other hand, for _ in &mut &mut (0usize..) just derefs and works fine.

@rustbot label: A-diagnostics D-incorrect D-confusing

@Soveu Soveu added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels May 2, 2021
@rustbot rustbot added 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 2, 2021
@tjallingt
Copy link

tjallingt commented Jul 13, 2022

This can happen "naturally" when trying to mutate nested arrays:

let mut inner = [1usize, 2, 3, 4, 5];
let mut outer = [&mut inner];

for items in &mut outer {
    for item in items {
        *item += 1
    }
}
error[E0277]: `[usize; 5]` is not an iterator
 --> src/main.rs:7:21
  |
7 |         for item in items {
  |                     ^^^^^ `[usize; 5]` is not an iterator; try calling `.into_iter()` or `.iter()`
  |
  = help: the trait `Iterator` is not implemented for `[usize; 5]`
  = help: the following other types implement trait `IntoIterator`:
            &'a [T; N]
            &'a [T]
            &'a mut [T; N]
            &'a mut [T]
            [T; N]
  = note: required because of the requirements on the impl of `Iterator` for `&mut [usize; 5]`
  = note: 1 redundant requirement hidden
  = note: required because of the requirements on the impl of `~const Iterator` for `&mut &mut [usize; 5]`
  = note: required because of the requirements on the impl of `IntoIterator` for `&mut &mut [usize; 5]`

Not sure if there is a more idiomatic way to write that code that avoids this but it feels like this should just work.

The message

[usize; 5] is not an iterator;

Also seems confusing when I think/know that it should definitely be an Iterator (or IntoIterator).
At least it helpfully suggest to call .into_iter() or .iter(), although it would probably be better if it suggested .iter_mut().

The same code using Vec will not have this suggestion (@estebank ?):

let mut inner = vec![1, 2, 3, 4, 5];
let mut outer = vec![&mut inner];

for items in &mut outer {
    for item in items {
        *item += 1
    }
}
error[E0277]: `Vec<{integer}>` is not an iterator
 --> src/main.rs:7:21
  |
7 |         for item in items {
  |                     ^^^^^ `Vec<{integer}>` is not an iterator
  |
  = help: the trait `Iterator` is not implemented for `Vec<{integer}>`
  = help: the following other types implement trait `IntoIterator`:
            &'a Vec<T, A>
            &'a mut Vec<T, A>
            Vec<T, A>
  = note: required because of the requirements on the impl of `Iterator` for `&mut Vec<{integer}>`
  = note: 1 redundant requirement hidden
  = note: required because of the requirements on the impl of `~const Iterator` for `&mut &mut Vec<{integer}>`
  = note: required because of the requirements on the impl of `IntoIterator` for `&mut &mut Vec<{integer}>`

@estebank
Copy link
Contributor

Also seems confusing when I think/know that it should definitely be an Iterator (or IntoIterator).
At least it helpfully suggest to call .into_iter() or .iter(), although it would probably be better if it suggested .iter_mut().

The same code using Vec will not have this suggestion (@estebank ?):

These labels are given with rustc_on_unimplemented annotations on the Iterator trait, so adding more conditions to them is relatively straightforward.

@tjallingt
Copy link

tjallingt commented Jul 14, 2022

Ah someone already added a variant for Vec and it works on nightly: #97871
Sorry for the confusion.

I'm still curious why the code doesn't "just work"tm but at least the errors are helpful.

@estebank
Copy link
Contributor

estebank commented Jan 8, 2023

Triage: we now provide enough context to figure out what the problem might be, but it is not newcomer friendly.

Current output:

error[[E0277]](https://doc.rust-lang.org/nightly/error-index.html#E0277): `Vec<u8>` is not an iterator
 --> src/main.rs:3:14
  |
3 |     for _ in &mut &mut v {}
  |              ^^^^^^^^^^^ `Vec<u8>` is not an iterator; try calling `.into_iter()` or `.iter()`
  |
  = help: the trait `Iterator` is not implemented for `Vec<u8>`
  = help: the following other types implement trait `IntoIterator`:
            &'a Vec<T, A>
            &'a mut Vec<T, A>
            Vec<T, A>
  = note: required for `&mut Vec<u8>` to implement `Iterator`
  = note: 1 redundant requirement hidden
  = note: required for `&mut &mut Vec<u8>` to implement `Iterator`
  = note: required for `&mut &mut Vec<u8>` to implement `IntoIterator`

error[[E0277]](https://doc.rust-lang.org/nightly/error-index.html#E0277): `[u8]` is not an iterator
 --> src/main.rs:6:14
  |
6 |     for _ in &mut v {}
  |              ^^^^^^ `[u8]` is not an iterator; try calling `.into_iter()` or `.iter()`
  |
  = help: the trait `Iterator` is not implemented for `[u8]`
  = help: the following other types implement trait `IntoIterator`:
            &'a [T; N]
            &'a [T]
            &'a mut [T; N]
            &'a mut [T]
            [T; N]
  = note: required for `&mut [u8]` to implement `Iterator`
  = note: 1 redundant requirement hidden
  = note: required for `&mut &mut [u8]` to implement `Iterator`
  = note: required for `&mut &mut [u8]` to implement `IntoIterator`

@estebank estebank added D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. and removed D-confusing Diagnostics: Confusing error or lint that should be reworked. D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information. labels Jan 8, 2023
@estebank
Copy link
Contributor

estebank commented Jan 8, 2023

I need to check why the logic being modified at #106360 doesn't trigger for these cases.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jan 12, 2023
… r=compiler-errors

Tweak E0277 `&`-removal suggestions

Fix rust-lang#64068, fix rust-lang#84837.
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Jan 12, 2023
… r=compiler-errors

Tweak E0277 `&`-removal suggestions

Fix rust-lang#64068, fix rust-lang#84837.
compiler-errors added a commit to compiler-errors/rust that referenced this issue Jan 12, 2023
… r=compiler-errors

Tweak E0277 `&`-removal suggestions

Fix rust-lang#64068, fix rust-lang#84837.
@bors bors closed this as completed in 8b8cce1 Jan 12, 2023
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 D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants