From 5b0223e8c6bfe89ab3697343d5314c72c806504e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 9 Oct 2018 18:53:53 -0700 Subject: [PATCH] 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) --- src/libcore/iter/iterator.rs | 21 +++++++++++++++- src/test/ui/conservative_impl_trait.rs | 2 +- src/test/ui/conservative_impl_trait.stderr | 4 ++-- .../feature-gate-trivial_bounds.stderr | 5 ++-- src/test/ui/for/for-c-in-str.rs | 2 +- src/test/ui/for/for-c-in-str.stderr | 2 +- src/test/ui/for/for-loop-bogosity.rs | 3 ++- src/test/ui/for/for-loop-bogosity.stderr | 6 ++--- src/test/ui/issues/issue-28098.rs | 12 +++++----- src/test/ui/issues/issue-28098.stderr | 24 +++++++++---------- src/test/ui/issues/issue-50480.rs | 2 +- src/test/ui/issues/issue-50480.stderr | 5 ++-- .../ui/suggestions/suggest-remove-refs-1.rs | 2 +- .../suggestions/suggest-remove-refs-1.stderr | 4 ++-- .../ui/suggestions/suggest-remove-refs-2.rs | 2 +- .../suggestions/suggest-remove-refs-2.stderr | 4 ++-- .../ui/suggestions/suggest-remove-refs-3.rs | 2 +- .../suggestions/suggest-remove-refs-3.stderr | 4 ++-- 18 files changed, 64 insertions(+), 42 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 4ed4ddb5b656..b3fa5abd1c4e 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -30,11 +30,30 @@ fn _assert_is_object_safe(_: &dyn Iterator) {} /// [impl]: index.html#implementing-iterator #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented( + on( + _Self="[std::ops::Range; 1]", + label="if you meant to iterate between two values, remove the square brackets", + note="`[start..end]` is an array of one `Range`, you might have meant to have a `Range`: `start..end`" + ), on( _Self="&str", label="`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`" ), - label="`{Self}` is not an iterator; maybe try calling `.iter()` or a similar method" + on( + _Self="std::string::String", + label="`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`" + ), + on( + _Self="[]", + label="borrow the array with `&` or call `.iter()` on it to iterate over it", + note="arrays are not an iterators, but slices like the following are: `&[1, 2, 3]`" + ), + on( + _Self="{integral}", + note="if you want to iterate between `0` until a value `end`, use the range syntax: `0..end`" + ), + label="`{Self}` is not an iterator", + message="`{Self}` is not an iterator" )] #[doc(spotlight)] pub trait Iterator { diff --git a/src/test/ui/conservative_impl_trait.rs b/src/test/ui/conservative_impl_trait.rs index 30895bce357b..8554b346beb2 100644 --- a/src/test/ui/conservative_impl_trait.rs +++ b/src/test/ui/conservative_impl_trait.rs @@ -11,7 +11,7 @@ // #39872, #39553 fn will_ice(something: &u32) -> impl Iterator { - //~^ ERROR the trait bound `(): std::iter::Iterator` is not satisfied [E0277] + //~^ ERROR `()` is not an iterator } fn main() {} diff --git a/src/test/ui/conservative_impl_trait.stderr b/src/test/ui/conservative_impl_trait.stderr index 6fcd384566cf..cfa4618566ef 100644 --- a/src/test/ui/conservative_impl_trait.stderr +++ b/src/test/ui/conservative_impl_trait.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `(): std::iter::Iterator` is not satisfied +error[E0277]: `()` is not an iterator --> $DIR/conservative_impl_trait.rs:13:33 | LL | fn will_ice(something: &u32) -> impl Iterator { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `()` = note: the return type of a function must have a statically known size diff --git a/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr b/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr index f20c1ebb37aa..a37980d0d512 100644 --- a/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr +++ b/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr @@ -75,15 +75,16 @@ LL | | } = help: see issue #48214 = help: add #![feature(trivial_bounds)] to the crate attributes to enable -error[E0277]: the trait bound `i32: std::iter::Iterator` is not satisfied +error[E0277]: `i32` is not an iterator --> $DIR/feature-gate-trivial_bounds.rs:50:1 | LL | / fn use_for() where i32: Iterator { //~ ERROR LL | | for _ in 2i32 {} LL | | } - | |_^ `i32` is not an iterator; maybe try calling `.iter()` or a similar method + | |_^ `i32` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `i32` + = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` = help: see issue #48214 = help: add #![feature(trivial_bounds)] to the crate attributes to enable diff --git a/src/test/ui/for/for-c-in-str.rs b/src/test/ui/for/for-c-in-str.rs index 011886e80734..83ec6c2db9b8 100644 --- a/src/test/ui/for/for-c-in-str.rs +++ b/src/test/ui/for/for-c-in-str.rs @@ -12,7 +12,7 @@ fn main() { for c in "asdf" { - //~^ ERROR the trait bound `&str: std::iter::Iterator` is not satisfied + //~^ ERROR `&str` is not an iterator //~| NOTE `&str` is not an iterator //~| HELP the trait `std::iter::Iterator` is not implemented for `&str` //~| NOTE required by `std::iter::IntoIterator::into_iter` diff --git a/src/test/ui/for/for-c-in-str.stderr b/src/test/ui/for/for-c-in-str.stderr index b249df3b4ef6..d3db935166eb 100644 --- a/src/test/ui/for/for-c-in-str.stderr +++ b/src/test/ui/for/for-c-in-str.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `&str: std::iter::Iterator` is not satisfied +error[E0277]: `&str` is not an iterator --> $DIR/for-c-in-str.rs:14:14 | LL | for c in "asdf" { diff --git a/src/test/ui/for/for-loop-bogosity.rs b/src/test/ui/for/for-loop-bogosity.rs index 96ad184fd355..b54d445ae37f 100644 --- a/src/test/ui/for/for-loop-bogosity.rs +++ b/src/test/ui/for/for-loop-bogosity.rs @@ -24,7 +24,8 @@ pub fn main() { x: 1, y: 2, }; - for x in bogus { //~ ERROR `MyStruct: std::iter::Iterator` is not satisfied + for x in bogus { + //~^ ERROR `MyStruct` is not an iterator drop(x); } } diff --git a/src/test/ui/for/for-loop-bogosity.stderr b/src/test/ui/for/for-loop-bogosity.stderr index 0476ec06c705..1aaf12c5da02 100644 --- a/src/test/ui/for/for-loop-bogosity.stderr +++ b/src/test/ui/for/for-loop-bogosity.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `MyStruct: std::iter::Iterator` is not satisfied +error[E0277]: `MyStruct` is not an iterator --> $DIR/for-loop-bogosity.rs:27:14 | -LL | for x in bogus { //~ ERROR `MyStruct: std::iter::Iterator` is not satisfied - | ^^^^^ `MyStruct` is not an iterator; maybe try calling `.iter()` or a similar method +LL | for x in bogus { + | ^^^^^ `MyStruct` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `MyStruct` = note: required by `std::iter::IntoIterator::into_iter` diff --git a/src/test/ui/issues/issue-28098.rs b/src/test/ui/issues/issue-28098.rs index 5dded2b1e169..11990c34fbae 100644 --- a/src/test/ui/issues/issue-28098.rs +++ b/src/test/ui/issues/issue-28098.rs @@ -10,13 +10,13 @@ fn main() { let _ = Iterator::next(&mut ()); - //~^ ERROR `(): std::iter::Iterator` is not satisfied + //~^ ERROR `()` is not an iterator for _ in false {} - //~^ ERROR `bool: std::iter::Iterator` is not satisfied + //~^ ERROR `bool` is not an iterator let _ = Iterator::next(&mut ()); - //~^ ERROR `(): std::iter::Iterator` is not satisfied + //~^ ERROR `()` is not an iterator other() } @@ -25,11 +25,11 @@ pub fn other() { // check errors are still reported globally let _ = Iterator::next(&mut ()); - //~^ ERROR `(): std::iter::Iterator` is not satisfied + //~^ ERROR `()` is not an iterator let _ = Iterator::next(&mut ()); - //~^ ERROR `(): std::iter::Iterator` is not satisfied + //~^ ERROR `()` is not an iterator for _ in false {} - //~^ ERROR `bool: std::iter::Iterator` is not satisfied + //~^ ERROR `bool` is not an iterator } diff --git a/src/test/ui/issues/issue-28098.stderr b/src/test/ui/issues/issue-28098.stderr index 3a6e1aea2883..c7537065b32b 100644 --- a/src/test/ui/issues/issue-28098.stderr +++ b/src/test/ui/issues/issue-28098.stderr @@ -1,53 +1,53 @@ -error[E0277]: the trait bound `(): std::iter::Iterator` is not satisfied +error[E0277]: `()` is not an iterator --> $DIR/issue-28098.rs:12:13 | LL | let _ = Iterator::next(&mut ()); - | ^^^^^^^^^^^^^^ `()` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^^^^^^^^^^ `()` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `()` = note: required by `std::iter::Iterator::next` -error[E0277]: the trait bound `bool: std::iter::Iterator` is not satisfied +error[E0277]: `bool` is not an iterator --> $DIR/issue-28098.rs:15:14 | LL | for _ in false {} - | ^^^^^ `bool` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^ `bool` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `bool` = note: required by `std::iter::IntoIterator::into_iter` -error[E0277]: the trait bound `(): std::iter::Iterator` is not satisfied +error[E0277]: `()` is not an iterator --> $DIR/issue-28098.rs:18:13 | LL | let _ = Iterator::next(&mut ()); - | ^^^^^^^^^^^^^^ `()` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^^^^^^^^^^ `()` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `()` = note: required by `std::iter::Iterator::next` -error[E0277]: the trait bound `(): std::iter::Iterator` is not satisfied +error[E0277]: `()` is not an iterator --> $DIR/issue-28098.rs:27:13 | LL | let _ = Iterator::next(&mut ()); - | ^^^^^^^^^^^^^^ `()` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^^^^^^^^^^ `()` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `()` = note: required by `std::iter::Iterator::next` -error[E0277]: the trait bound `(): std::iter::Iterator` is not satisfied +error[E0277]: `()` is not an iterator --> $DIR/issue-28098.rs:30:13 | LL | let _ = Iterator::next(&mut ()); - | ^^^^^^^^^^^^^^ `()` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^^^^^^^^^^ `()` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `()` = note: required by `std::iter::Iterator::next` -error[E0277]: the trait bound `bool: std::iter::Iterator` is not satisfied +error[E0277]: `bool` is not an iterator --> $DIR/issue-28098.rs:33:14 | LL | for _ in false {} - | ^^^^^ `bool` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^ `bool` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `bool` = note: required by `std::iter::IntoIterator::into_iter` diff --git a/src/test/ui/issues/issue-50480.rs b/src/test/ui/issues/issue-50480.rs index 3427cf6bf9ca..565ba8dd4de4 100644 --- a/src/test/ui/issues/issue-50480.rs +++ b/src/test/ui/issues/issue-50480.rs @@ -12,6 +12,6 @@ //~^ ERROR the trait `Copy` may not be implemented for this type struct Foo(NotDefined, ::Item, Vec, String); //~^ ERROR cannot find type `NotDefined` in this scope -//~| ERROR the trait bound `i32: std::iter::Iterator` is not satisfied +//~| ERROR `i32` is not an iterator fn main() {} diff --git a/src/test/ui/issues/issue-50480.stderr b/src/test/ui/issues/issue-50480.stderr index f5281fec4d1e..672484f401a2 100644 --- a/src/test/ui/issues/issue-50480.stderr +++ b/src/test/ui/issues/issue-50480.stderr @@ -4,13 +4,14 @@ error[E0412]: cannot find type `NotDefined` in this scope LL | struct Foo(NotDefined, ::Item, Vec, String); | ^^^^^^^^^^ not found in this scope -error[E0277]: the trait bound `i32: std::iter::Iterator` is not satisfied +error[E0277]: `i32` is not an iterator --> $DIR/issue-50480.rs:13:24 | LL | struct Foo(NotDefined, ::Item, Vec, String); - | ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `i32` + = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` error[E0204]: the trait `Copy` may not be implemented for this type --> $DIR/issue-50480.rs:11:17 diff --git a/src/test/ui/suggestions/suggest-remove-refs-1.rs b/src/test/ui/suggestions/suggest-remove-refs-1.rs index 0f19c48337b1..d7c80a677a5e 100644 --- a/src/test/ui/suggestions/suggest-remove-refs-1.rs +++ b/src/test/ui/suggestions/suggest-remove-refs-1.rs @@ -12,7 +12,7 @@ fn main() { let v = vec![0, 1, 2, 3]; for (i, n) in &v.iter().enumerate() { - //~^ ERROR the trait bound + //~^ ERROR `&std::iter::Enumerate>` is not an iterator println!("{}", i); } } diff --git a/src/test/ui/suggestions/suggest-remove-refs-1.stderr b/src/test/ui/suggestions/suggest-remove-refs-1.stderr index c47b4d283d7c..1fc661efd91f 100644 --- a/src/test/ui/suggestions/suggest-remove-refs-1.stderr +++ b/src/test/ui/suggestions/suggest-remove-refs-1.stderr @@ -1,10 +1,10 @@ -error[E0277]: the trait bound `&std::iter::Enumerate>: std::iter::Iterator` is not satisfied +error[E0277]: `&std::iter::Enumerate>` is not an iterator --> $DIR/suggest-remove-refs-1.rs:14:19 | LL | for (i, n) in &v.iter().enumerate() { | -^^^^^^^^^^^^^^^^^^^^ | | - | `&std::iter::Enumerate>` is not an iterator; maybe try calling `.iter()` or a similar method + | `&std::iter::Enumerate>` is not an iterator | help: consider removing 1 leading `&`-references | = help: the trait `std::iter::Iterator` is not implemented for `&std::iter::Enumerate>` diff --git a/src/test/ui/suggestions/suggest-remove-refs-2.rs b/src/test/ui/suggestions/suggest-remove-refs-2.rs index c427f697ae1e..37af97323d59 100644 --- a/src/test/ui/suggestions/suggest-remove-refs-2.rs +++ b/src/test/ui/suggestions/suggest-remove-refs-2.rs @@ -12,7 +12,7 @@ fn main() { let v = vec![0, 1, 2, 3]; for (i, n) in & & & & &v.iter().enumerate() { - //~^ ERROR the trait bound + //~^ ERROR `&&&&&std::iter::Enumerate>` is not an iterator println!("{}", i); } } diff --git a/src/test/ui/suggestions/suggest-remove-refs-2.stderr b/src/test/ui/suggestions/suggest-remove-refs-2.stderr index fdd654ea3923..96c6c92d59ba 100644 --- a/src/test/ui/suggestions/suggest-remove-refs-2.stderr +++ b/src/test/ui/suggestions/suggest-remove-refs-2.stderr @@ -1,10 +1,10 @@ -error[E0277]: the trait bound `&&&&&std::iter::Enumerate>: std::iter::Iterator` is not satisfied +error[E0277]: `&&&&&std::iter::Enumerate>` is not an iterator --> $DIR/suggest-remove-refs-2.rs:14:19 | LL | for (i, n) in & & & & &v.iter().enumerate() { | ---------^^^^^^^^^^^^^^^^^^^^ | | - | `&&&&&std::iter::Enumerate>` is not an iterator; maybe try calling `.iter()` or a similar method + | `&&&&&std::iter::Enumerate>` is not an iterator | help: consider removing 5 leading `&`-references | = help: the trait `std::iter::Iterator` is not implemented for `&&&&&std::iter::Enumerate>` diff --git a/src/test/ui/suggestions/suggest-remove-refs-3.rs b/src/test/ui/suggestions/suggest-remove-refs-3.rs index f54ae30caebc..c9dff35f92c0 100644 --- a/src/test/ui/suggestions/suggest-remove-refs-3.rs +++ b/src/test/ui/suggestions/suggest-remove-refs-3.rs @@ -15,7 +15,7 @@ fn main() { & &v .iter() .enumerate() { - //~^^^^ ERROR the trait bound + //~^^^^ ERROR `&&&&&std::iter::Enumerate>` is not an println!("{}", i); } } diff --git a/src/test/ui/suggestions/suggest-remove-refs-3.stderr b/src/test/ui/suggestions/suggest-remove-refs-3.stderr index b0920a0fa523..4311c432b41d 100644 --- a/src/test/ui/suggestions/suggest-remove-refs-3.stderr +++ b/src/test/ui/suggestions/suggest-remove-refs-3.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `&&&&&std::iter::Enumerate>: std::iter::Iterator` is not satisfied +error[E0277]: `&&&&&std::iter::Enumerate>` is not an iterator --> $DIR/suggest-remove-refs-3.rs:14:19 | LL | for (i, n) in & & & @@ -9,7 +9,7 @@ LL | || & &v | ||___________- help: consider removing 5 leading `&`-references LL | | .iter() LL | | .enumerate() { - | |_____________________^ `&&&&&std::iter::Enumerate>` is not an iterator; maybe try calling `.iter()` or a similar method + | |_____________________^ `&&&&&std::iter::Enumerate>` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `&&&&&std::iter::Enumerate>` = note: required by `std::iter::IntoIterator::into_iter`