Skip to content

Commit 5b0223e

Browse files
committed
Reword rustc_on_unimplemented errors for Iterator
- Detect one element array of `Range` type, which is potentially a typo: `for _ in [0..10] {}` where iterating between `0` and `10` was intended. (#23141) - Suggest `.bytes()` and `.chars()` for `String`. - Suggest borrowing or `.iter()` on arrays (#36391) - Suggest using range literal when iterating on integers (#34353) - Do not suggest `.iter()` by default (#50773, #46806)
1 parent cd7c818 commit 5b0223e

18 files changed

+64
-42
lines changed

src/libcore/iter/iterator.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,30 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item=()>) {}
3030
/// [impl]: index.html#implementing-iterator
3131
#[stable(feature = "rust1", since = "1.0.0")]
3232
#[rustc_on_unimplemented(
33+
on(
34+
_Self="[std::ops::Range<Idx>; 1]",
35+
label="if you meant to iterate between two values, remove the square brackets",
36+
note="`[start..end]` is an array of one `Range`, you might have meant to have a `Range`: `start..end`"
37+
),
3338
on(
3439
_Self="&str",
3540
label="`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
3641
),
37-
label="`{Self}` is not an iterator; maybe try calling `.iter()` or a similar method"
42+
on(
43+
_Self="std::string::String",
44+
label="`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
45+
),
46+
on(
47+
_Self="[]",
48+
label="borrow the array with `&` or call `.iter()` on it to iterate over it",
49+
note="arrays are not an iterators, but slices like the following are: `&[1, 2, 3]`"
50+
),
51+
on(
52+
_Self="{integral}",
53+
note="if you want to iterate between `0` until a value `end`, use the range syntax: `0..end`"
54+
),
55+
label="`{Self}` is not an iterator",
56+
message="`{Self}` is not an iterator"
3857
)]
3958
#[doc(spotlight)]
4059
pub trait Iterator {

src/test/ui/conservative_impl_trait.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// #39872, #39553
1212

1313
fn will_ice(something: &u32) -> impl Iterator<Item = &u32> {
14-
//~^ ERROR the trait bound `(): std::iter::Iterator` is not satisfied [E0277]
14+
//~^ ERROR `()` is not an iterator
1515
}
1616

1717
fn main() {}

src/test/ui/conservative_impl_trait.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0277]: the trait bound `(): std::iter::Iterator` is not satisfied
1+
error[E0277]: `()` is not an iterator
22
--> $DIR/conservative_impl_trait.rs:13:33
33
|
44
LL | fn will_ice(something: &u32) -> impl Iterator<Item = &u32> {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator; maybe try calling `.iter()` or a similar method
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
66
|
77
= help: the trait `std::iter::Iterator` is not implemented for `()`
88
= note: the return type of a function must have a statically known size

src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,16 @@ LL | | }
7575
= help: see issue #48214
7676
= help: add #![feature(trivial_bounds)] to the crate attributes to enable
7777

78-
error[E0277]: the trait bound `i32: std::iter::Iterator` is not satisfied
78+
error[E0277]: `i32` is not an iterator
7979
--> $DIR/feature-gate-trivial_bounds.rs:50:1
8080
|
8181
LL | / fn use_for() where i32: Iterator { //~ ERROR
8282
LL | | for _ in 2i32 {}
8383
LL | | }
84-
| |_^ `i32` is not an iterator; maybe try calling `.iter()` or a similar method
84+
| |_^ `i32` is not an iterator
8585
|
8686
= help: the trait `std::iter::Iterator` is not implemented for `i32`
87+
= note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end`
8788
= help: see issue #48214
8889
= help: add #![feature(trivial_bounds)] to the crate attributes to enable
8990

src/test/ui/for/for-c-in-str.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
fn main() {
1414
for c in "asdf" {
15-
//~^ ERROR the trait bound `&str: std::iter::Iterator` is not satisfied
15+
//~^ ERROR `&str` is not an iterator
1616
//~| NOTE `&str` is not an iterator
1717
//~| HELP the trait `std::iter::Iterator` is not implemented for `&str`
1818
//~| NOTE required by `std::iter::IntoIterator::into_iter`

src/test/ui/for/for-c-in-str.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0277]: the trait bound `&str: std::iter::Iterator` is not satisfied
1+
error[E0277]: `&str` is not an iterator
22
--> $DIR/for-c-in-str.rs:14:14
33
|
44
LL | for c in "asdf" {

src/test/ui/for/for-loop-bogosity.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ pub fn main() {
2424
x: 1,
2525
y: 2,
2626
};
27-
for x in bogus { //~ ERROR `MyStruct: std::iter::Iterator` is not satisfied
27+
for x in bogus {
28+
//~^ ERROR `MyStruct` is not an iterator
2829
drop(x);
2930
}
3031
}

src/test/ui/for/for-loop-bogosity.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0277]: the trait bound `MyStruct: std::iter::Iterator` is not satisfied
1+
error[E0277]: `MyStruct` is not an iterator
22
--> $DIR/for-loop-bogosity.rs:27:14
33
|
4-
LL | for x in bogus { //~ ERROR `MyStruct: std::iter::Iterator` is not satisfied
5-
| ^^^^^ `MyStruct` is not an iterator; maybe try calling `.iter()` or a similar method
4+
LL | for x in bogus {
5+
| ^^^^^ `MyStruct` is not an iterator
66
|
77
= help: the trait `std::iter::Iterator` is not implemented for `MyStruct`
88
= note: required by `std::iter::IntoIterator::into_iter`

src/test/ui/issues/issue-28098.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010

1111
fn main() {
1212
let _ = Iterator::next(&mut ());
13-
//~^ ERROR `(): std::iter::Iterator` is not satisfied
13+
//~^ ERROR `()` is not an iterator
1414

1515
for _ in false {}
16-
//~^ ERROR `bool: std::iter::Iterator` is not satisfied
16+
//~^ ERROR `bool` is not an iterator
1717

1818
let _ = Iterator::next(&mut ());
19-
//~^ ERROR `(): std::iter::Iterator` is not satisfied
19+
//~^ ERROR `()` is not an iterator
2020

2121
other()
2222
}
@@ -25,11 +25,11 @@ pub fn other() {
2525
// check errors are still reported globally
2626

2727
let _ = Iterator::next(&mut ());
28-
//~^ ERROR `(): std::iter::Iterator` is not satisfied
28+
//~^ ERROR `()` is not an iterator
2929

3030
let _ = Iterator::next(&mut ());
31-
//~^ ERROR `(): std::iter::Iterator` is not satisfied
31+
//~^ ERROR `()` is not an iterator
3232

3333
for _ in false {}
34-
//~^ ERROR `bool: std::iter::Iterator` is not satisfied
34+
//~^ ERROR `bool` is not an iterator
3535
}

src/test/ui/issues/issue-28098.stderr

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,53 @@
1-
error[E0277]: the trait bound `(): std::iter::Iterator` is not satisfied
1+
error[E0277]: `()` is not an iterator
22
--> $DIR/issue-28098.rs:12:13
33
|
44
LL | let _ = Iterator::next(&mut ());
5-
| ^^^^^^^^^^^^^^ `()` is not an iterator; maybe try calling `.iter()` or a similar method
5+
| ^^^^^^^^^^^^^^ `()` is not an iterator
66
|
77
= help: the trait `std::iter::Iterator` is not implemented for `()`
88
= note: required by `std::iter::Iterator::next`
99

10-
error[E0277]: the trait bound `bool: std::iter::Iterator` is not satisfied
10+
error[E0277]: `bool` is not an iterator
1111
--> $DIR/issue-28098.rs:15:14
1212
|
1313
LL | for _ in false {}
14-
| ^^^^^ `bool` is not an iterator; maybe try calling `.iter()` or a similar method
14+
| ^^^^^ `bool` is not an iterator
1515
|
1616
= help: the trait `std::iter::Iterator` is not implemented for `bool`
1717
= note: required by `std::iter::IntoIterator::into_iter`
1818

19-
error[E0277]: the trait bound `(): std::iter::Iterator` is not satisfied
19+
error[E0277]: `()` is not an iterator
2020
--> $DIR/issue-28098.rs:18:13
2121
|
2222
LL | let _ = Iterator::next(&mut ());
23-
| ^^^^^^^^^^^^^^ `()` is not an iterator; maybe try calling `.iter()` or a similar method
23+
| ^^^^^^^^^^^^^^ `()` is not an iterator
2424
|
2525
= help: the trait `std::iter::Iterator` is not implemented for `()`
2626
= note: required by `std::iter::Iterator::next`
2727

28-
error[E0277]: the trait bound `(): std::iter::Iterator` is not satisfied
28+
error[E0277]: `()` is not an iterator
2929
--> $DIR/issue-28098.rs:27:13
3030
|
3131
LL | let _ = Iterator::next(&mut ());
32-
| ^^^^^^^^^^^^^^ `()` is not an iterator; maybe try calling `.iter()` or a similar method
32+
| ^^^^^^^^^^^^^^ `()` is not an iterator
3333
|
3434
= help: the trait `std::iter::Iterator` is not implemented for `()`
3535
= note: required by `std::iter::Iterator::next`
3636

37-
error[E0277]: the trait bound `(): std::iter::Iterator` is not satisfied
37+
error[E0277]: `()` is not an iterator
3838
--> $DIR/issue-28098.rs:30:13
3939
|
4040
LL | let _ = Iterator::next(&mut ());
41-
| ^^^^^^^^^^^^^^ `()` is not an iterator; maybe try calling `.iter()` or a similar method
41+
| ^^^^^^^^^^^^^^ `()` is not an iterator
4242
|
4343
= help: the trait `std::iter::Iterator` is not implemented for `()`
4444
= note: required by `std::iter::Iterator::next`
4545

46-
error[E0277]: the trait bound `bool: std::iter::Iterator` is not satisfied
46+
error[E0277]: `bool` is not an iterator
4747
--> $DIR/issue-28098.rs:33:14
4848
|
4949
LL | for _ in false {}
50-
| ^^^^^ `bool` is not an iterator; maybe try calling `.iter()` or a similar method
50+
| ^^^^^ `bool` is not an iterator
5151
|
5252
= help: the trait `std::iter::Iterator` is not implemented for `bool`
5353
= note: required by `std::iter::IntoIterator::into_iter`

src/test/ui/issues/issue-50480.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@
1212
//~^ ERROR the trait `Copy` may not be implemented for this type
1313
struct Foo(NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
1414
//~^ ERROR cannot find type `NotDefined` in this scope
15-
//~| ERROR the trait bound `i32: std::iter::Iterator` is not satisfied
15+
//~| ERROR `i32` is not an iterator
1616

1717
fn main() {}

src/test/ui/issues/issue-50480.stderr

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ error[E0412]: cannot find type `NotDefined` in this scope
44
LL | struct Foo(NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
55
| ^^^^^^^^^^ not found in this scope
66

7-
error[E0277]: the trait bound `i32: std::iter::Iterator` is not satisfied
7+
error[E0277]: `i32` is not an iterator
88
--> $DIR/issue-50480.rs:13:24
99
|
1010
LL | struct Foo(NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
11-
| ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator; maybe try calling `.iter()` or a similar method
11+
| ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator
1212
|
1313
= help: the trait `std::iter::Iterator` is not implemented for `i32`
14+
= note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end`
1415

1516
error[E0204]: the trait `Copy` may not be implemented for this type
1617
--> $DIR/issue-50480.rs:11:17

src/test/ui/suggestions/suggest-remove-refs-1.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ fn main() {
1212
let v = vec![0, 1, 2, 3];
1313

1414
for (i, n) in &v.iter().enumerate() {
15-
//~^ ERROR the trait bound
15+
//~^ ERROR `&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
1616
println!("{}", i);
1717
}
1818
}

src/test/ui/suggestions/suggest-remove-refs-1.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error[E0277]: the trait bound `&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>: std::iter::Iterator` is not satisfied
1+
error[E0277]: `&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
22
--> $DIR/suggest-remove-refs-1.rs:14:19
33
|
44
LL | for (i, n) in &v.iter().enumerate() {
55
| -^^^^^^^^^^^^^^^^^^^^
66
| |
7-
| `&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator; maybe try calling `.iter()` or a similar method
7+
| `&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
88
| help: consider removing 1 leading `&`-references
99
|
1010
= help: the trait `std::iter::Iterator` is not implemented for `&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>`

src/test/ui/suggestions/suggest-remove-refs-2.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ fn main() {
1212
let v = vec![0, 1, 2, 3];
1313

1414
for (i, n) in & & & & &v.iter().enumerate() {
15-
//~^ ERROR the trait bound
15+
//~^ ERROR `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
1616
println!("{}", i);
1717
}
1818
}

src/test/ui/suggestions/suggest-remove-refs-2.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error[E0277]: the trait bound `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>: std::iter::Iterator` is not satisfied
1+
error[E0277]: `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
22
--> $DIR/suggest-remove-refs-2.rs:14:19
33
|
44
LL | for (i, n) in & & & & &v.iter().enumerate() {
55
| ---------^^^^^^^^^^^^^^^^^^^^
66
| |
7-
| `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator; maybe try calling `.iter()` or a similar method
7+
| `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
88
| help: consider removing 5 leading `&`-references
99
|
1010
= help: the trait `std::iter::Iterator` is not implemented for `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>`

src/test/ui/suggestions/suggest-remove-refs-3.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ fn main() {
1515
& &v
1616
.iter()
1717
.enumerate() {
18-
//~^^^^ ERROR the trait bound
18+
//~^^^^ ERROR `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an
1919
println!("{}", i);
2020
}
2121
}

src/test/ui/suggestions/suggest-remove-refs-3.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0277]: the trait bound `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>: std::iter::Iterator` is not satisfied
1+
error[E0277]: `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
22
--> $DIR/suggest-remove-refs-3.rs:14:19
33
|
44
LL | for (i, n) in & & &
@@ -9,7 +9,7 @@ LL | || & &v
99
| ||___________- help: consider removing 5 leading `&`-references
1010
LL | | .iter()
1111
LL | | .enumerate() {
12-
| |_____________________^ `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator; maybe try calling `.iter()` or a similar method
12+
| |_____________________^ `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
1313
|
1414
= help: the trait `std::iter::Iterator` is not implemented for `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>`
1515
= note: required by `std::iter::IntoIterator::into_iter`

0 commit comments

Comments
 (0)