Skip to content

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

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

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
# for free to join this conversation on GitHub. Already have an account? # 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