diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 4ed4ddb5b656f..5b6d9e2033caa 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -30,11 +30,72 @@ 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` \ + without the brackets: `start..end`" + ), + on( + _Self="[std::ops::RangeFrom; 1]", + label="if you meant to iterate from a value onwards, remove the square brackets", + note="`[start..]` is an array of one `RangeFrom`; you might have meant to have a \ + `RangeFrom` without the brackets: `start..`, keeping in mind that iterating over an \ + unbounded iterator will run forever unless you `break` or `return` from within the \ + loop" + ), + on( + _Self="[std::ops::RangeTo; 1]", + label="if you meant to iterate until a value, remove the square brackets and add a \ + starting value", + note="`[..end]` is an array of one `RangeTo`; you might have meant to have a bounded \ + `Range` without the brackets: `0..end`" + ), + on( + _Self="[std::ops::RangeInclusive; 1]", + label="if you meant to iterate between two values, remove the square brackets", + note="`[start..=end]` is an array of one `RangeInclusive`; you might have meant to have a \ + `RangeInclusive` without the brackets: `start..=end`" + ), + on( + _Self="[std::ops::RangeToInclusive; 1]", + label="if you meant to iterate until a value (including it), remove the square brackets \ + and add a starting value", + note="`[..=end]` is an array of one `RangeToInclusive`; you might have meant to have a \ + bounded `RangeInclusive` without the brackets: `0..=end`" + ), + on( + _Self="std::ops::RangeTo", + label="if you meant to iterate until a value, add a starting value", + note="`..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a \ + bounded `Range`: `0..end`" + ), + on( + _Self="std::ops::RangeToInclusive", + label="if you meant to iterate until a value (including it), add a starting value", + note="`..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant \ + to have a bounded `RangeInclusive`: `0..=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 `start` until a value `end`, use the exclusive range \ + syntax `start..end` or the inclusive range syntax `start..=end`" + ), + label="`{Self}` is not an iterator", + message="`{Self}` is not an iterator" )] #[doc(spotlight)] pub trait Iterator { diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index da2173fead370..fc34a71f39221 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -349,9 +349,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn on_unimplemented_note( &self, trait_ref: ty::PolyTraitRef<'tcx>, - obligation: &PredicateObligation<'tcx>) -> - OnUnimplementedNote - { + obligation: &PredicateObligation<'tcx>, + ) -> OnUnimplementedNote { let def_id = self.impl_similar_to(trait_ref, obligation) .unwrap_or(trait_ref.def_id()); let trait_ref = *trait_ref.skip_binder(); @@ -410,6 +409,38 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { flags.push(("crate_local".to_owned(), None)); } + // Allow targetting all integers using `{integral}`, even if the exact type was resolved + if self_ty.is_integral() { + flags.push(("_Self".to_owned(), Some("{integral}".to_owned()))); + } + + if let ty::Array(aty, len) = self_ty.sty { + flags.push(("_Self".to_owned(), Some("[]".to_owned()))); + flags.push(("_Self".to_owned(), Some(format!("[{}]", aty)))); + if let Some(def) = aty.ty_adt_def() { + // We also want to be able to select the array's type's original + // signature with no type arguments resolved + flags.push(( + "_Self".to_owned(), + Some(format!("[{}]", self.tcx.type_of(def.did).to_string())), + )); + let tcx = self.tcx; + if let Some(len) = len.val.try_to_scalar().and_then(|scalar| { + scalar.to_usize(tcx).ok() + }) { + flags.push(( + "_Self".to_owned(), + Some(format!("[{}; {}]", self.tcx.type_of(def.did).to_string(), len)), + )); + } else { + flags.push(( + "_Self".to_owned(), + Some(format!("[{}; _]", self.tcx.type_of(def.did).to_string())), + )); + } + } + } + if let Ok(Some(command)) = OnUnimplementedDirective::of_item( self.tcx, trait_ref.def_id, def_id ) { diff --git a/src/test/ui/conservative_impl_trait.rs b/src/test/ui/conservative_impl_trait.rs index 30895bce357bb..8554b346beb28 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 6fcd384566cf8..cfa4618566ef1 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 f20c1ebb37aa9..14764b4e9f0f8 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 `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=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 011886e807346..83ec6c2db9b80 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 b249df3b4ef6a..d3db935166eb4 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 96ad184fd3558..b54d445ae37f0 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 0476ec06c705a..1aaf12c5da029 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-22872.rs b/src/test/ui/issues/issue-22872.rs new file mode 100644 index 0000000000000..7a83b098e78fe --- /dev/null +++ b/src/test/ui/issues/issue-22872.rs @@ -0,0 +1,23 @@ +trait Wrap<'b> { + fn foo(&'b mut self); +} + +struct Wrapper

(P); + +impl<'b, P> Wrap<'b> for Wrapper

+where P: Process<'b>, +

>::Item: Iterator { + fn foo(&mut self) {} +} + + +pub trait Process<'a> { + type Item; + fn bar(&'a self); +} + +fn push_process

(process: P) where P: Process<'static> { + let _: Box Wrap<'b>> = Box::new(Wrapper(process)); +} + +fn main() {} diff --git a/src/test/ui/issues/issue-22872.stderr b/src/test/ui/issues/issue-22872.stderr new file mode 100644 index 0000000000000..231080add9bd0 --- /dev/null +++ b/src/test/ui/issues/issue-22872.stderr @@ -0,0 +1,23 @@ +error[E0277]: the trait bound `for<'b> P: Process<'b>` is not satisfied + --> $DIR/issue-22872.rs:20:36 + | +LL | let _: Box Wrap<'b>> = Box::new(Wrapper(process)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'b> Process<'b>` is not implemented for `P` + | + = help: consider adding a `where for<'b> P: Process<'b>` bound + = note: required because of the requirements on the impl of `for<'b> Wrap<'b>` for `Wrapper

` + = note: required for the cast to the object type `dyn for<'b> Wrap<'b>` + +error[E0277]: `

>::Item` is not an iterator + --> $DIR/issue-22872.rs:20:36 + | +LL | let _: Box Wrap<'b>> = Box::new(Wrapper(process)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `

>::Item` is not an iterator + | + = help: the trait `for<'b> std::iter::Iterator` is not implemented for `

>::Item` + = note: required because of the requirements on the impl of `for<'b> Wrap<'b>` for `Wrapper

` + = note: required for the cast to the object type `dyn for<'b> Wrap<'b>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/issues/issue-28098.rs b/src/test/ui/issues/issue-28098.rs index 5dded2b1e1697..11990c34fbae4 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 3a6e1aea28834..c7537065b32b6 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 3427cf6bf9ca2..565ba8dd4de45 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 f5281fec4d1ea..cbff927ac74d4 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 `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=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/iterators/array-of-ranges.rs b/src/test/ui/iterators/array-of-ranges.rs new file mode 100644 index 0000000000000..a7d6e80bae5f7 --- /dev/null +++ b/src/test/ui/iterators/array-of-ranges.rs @@ -0,0 +1,14 @@ +fn main() { + for _ in [0..1] {} + for _ in [0..=1] {} + for _ in [0..] {} + for _ in [..1] {} + for _ in [..=1] {} + let start = 0; + let end = 0; + for _ in [start..end] {} + let array_of_range = [start..end]; + for _ in array_of_range {} + for _ in [0..1, 2..3] {} + for _ in [0..=1] {} +} diff --git a/src/test/ui/iterators/array-of-ranges.stderr b/src/test/ui/iterators/array-of-ranges.stderr new file mode 100644 index 0000000000000..fbe7e0ee74889 --- /dev/null +++ b/src/test/ui/iterators/array-of-ranges.stderr @@ -0,0 +1,93 @@ +error[E0277]: `[std::ops::Range<{integer}>; 1]` is not an iterator + --> $DIR/array-of-ranges.rs:2:14 + | +LL | for _ in [0..1] {} + | ^^^^^^ if you meant to iterate between two values, remove the square brackets + | + = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::Range<{integer}>; 1]` + = note: `[start..end]` is an array of one `Range`; you might have meant to have a `Range` without the brackets: `start..end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `[std::ops::RangeInclusive<{integer}>; 1]` is not an iterator + --> $DIR/array-of-ranges.rs:3:14 + | +LL | for _ in [0..=1] {} + | ^^^^^^^ if you meant to iterate between two values, remove the square brackets + | + = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::RangeInclusive<{integer}>; 1]` + = note: `[start..=end]` is an array of one `RangeInclusive`; you might have meant to have a `RangeInclusive` without the brackets: `start..=end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `[std::ops::RangeFrom<{integer}>; 1]` is not an iterator + --> $DIR/array-of-ranges.rs:4:14 + | +LL | for _ in [0..] {} + | ^^^^^ if you meant to iterate from a value onwards, remove the square brackets + | + = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::RangeFrom<{integer}>; 1]` + = note: `[start..]` is an array of one `RangeFrom`; you might have meant to have a `RangeFrom` without the brackets: `start..`, keeping in mind that iterating over an unbounded iterator will run forever unless you `break` or `return` from within the loop + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `[std::ops::RangeTo<{integer}>; 1]` is not an iterator + --> $DIR/array-of-ranges.rs:5:14 + | +LL | for _ in [..1] {} + | ^^^^^ if you meant to iterate until a value, remove the square brackets and add a starting value + | + = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::RangeTo<{integer}>; 1]` + = note: `[..end]` is an array of one `RangeTo`; you might have meant to have a bounded `Range` without the brackets: `0..end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `[std::ops::RangeToInclusive<{integer}>; 1]` is not an iterator + --> $DIR/array-of-ranges.rs:6:14 + | +LL | for _ in [..=1] {} + | ^^^^^^ if you meant to iterate until a value (including it), remove the square brackets and add a starting value + | + = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::RangeToInclusive<{integer}>; 1]` + = note: `[..=end]` is an array of one `RangeToInclusive`; you might have meant to have a bounded `RangeInclusive` without the brackets: `0..=end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `[std::ops::Range<{integer}>; 1]` is not an iterator + --> $DIR/array-of-ranges.rs:9:14 + | +LL | for _ in [start..end] {} + | ^^^^^^^^^^^^ if you meant to iterate between two values, remove the square brackets + | + = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::Range<{integer}>; 1]` + = note: `[start..end]` is an array of one `Range`; you might have meant to have a `Range` without the brackets: `start..end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `[std::ops::Range<{integer}>; 1]` is not an iterator + --> $DIR/array-of-ranges.rs:11:14 + | +LL | for _ in array_of_range {} + | ^^^^^^^^^^^^^^ if you meant to iterate between two values, remove the square brackets + | + = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::Range<{integer}>; 1]` + = note: `[start..end]` is an array of one `Range`; you might have meant to have a `Range` without the brackets: `start..end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `[std::ops::Range<{integer}>; 2]` is not an iterator + --> $DIR/array-of-ranges.rs:12:14 + | +LL | for _ in [0..1, 2..3] {} + | ^^^^^^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it + | + = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::Range<{integer}>; 2]` + = note: arrays are not an iterators, but slices like the following are: `&[1, 2, 3]` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `[std::ops::RangeInclusive<{integer}>; 1]` is not an iterator + --> $DIR/array-of-ranges.rs:13:14 + | +LL | for _ in [0..=1] {} + | ^^^^^^^ if you meant to iterate between two values, remove the square brackets + | + = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::RangeInclusive<{integer}>; 1]` + = note: `[start..=end]` is an array of one `RangeInclusive`; you might have meant to have a `RangeInclusive` without the brackets: `start..=end` + = note: required by `std::iter::IntoIterator::into_iter` + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/iterators/array.rs b/src/test/ui/iterators/array.rs new file mode 100644 index 0000000000000..f54bb81274362 --- /dev/null +++ b/src/test/ui/iterators/array.rs @@ -0,0 +1,6 @@ +fn main() { + for _ in [1, 2] {} + let x = [1, 2]; + for _ in x {} + for _ in [1.0, 2.0] {} +} diff --git a/src/test/ui/iterators/array.stderr b/src/test/ui/iterators/array.stderr new file mode 100644 index 0000000000000..fd74cd7a727e2 --- /dev/null +++ b/src/test/ui/iterators/array.stderr @@ -0,0 +1,33 @@ +error[E0277]: `[{integer}; 2]` is not an iterator + --> $DIR/array.rs:2:14 + | +LL | for _ in [1, 2] {} + | ^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it + | + = help: the trait `std::iter::Iterator` is not implemented for `[{integer}; 2]` + = note: arrays are not an iterators, but slices like the following are: `&[1, 2, 3]` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `[{integer}; 2]` is not an iterator + --> $DIR/array.rs:4:14 + | +LL | for _ in x {} + | ^ borrow the array with `&` or call `.iter()` on it to iterate over it + | + = help: the trait `std::iter::Iterator` is not implemented for `[{integer}; 2]` + = note: arrays are not an iterators, but slices like the following are: `&[1, 2, 3]` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `[{float}; 2]` is not an iterator + --> $DIR/array.rs:5:14 + | +LL | for _ in [1.0, 2.0] {} + | ^^^^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it + | + = help: the trait `std::iter::Iterator` is not implemented for `[{float}; 2]` + = note: arrays are not an iterators, but slices like the following are: `&[1, 2, 3]` + = note: required by `std::iter::IntoIterator::into_iter` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/iterators/bound.rs b/src/test/ui/iterators/bound.rs new file mode 100644 index 0000000000000..78285b8161c38 --- /dev/null +++ b/src/test/ui/iterators/bound.rs @@ -0,0 +1,3 @@ +struct S(I); +struct T(S); +fn main() {} diff --git a/src/test/ui/iterators/bound.stderr b/src/test/ui/iterators/bound.stderr new file mode 100644 index 0000000000000..14057387c4f40 --- /dev/null +++ b/src/test/ui/iterators/bound.stderr @@ -0,0 +1,17 @@ +error[E0277]: `u8` is not an iterator + --> $DIR/bound.rs:2:10 + | +LL | struct T(S); + | ^^^^^ `u8` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `u8` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` +note: required by `S` + --> $DIR/bound.rs:1:1 + | +LL | struct S(I); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/iterators/integral.rs b/src/test/ui/iterators/integral.rs new file mode 100644 index 0000000000000..7537c7904c0bf --- /dev/null +++ b/src/test/ui/iterators/integral.rs @@ -0,0 +1,26 @@ +fn main() { + for _ in 42 {} + //~^ ERROR `{integer}` is not an iterator + for _ in 42 as u8 {} + //~^ ERROR `u8` is not an iterator + for _ in 42 as i8 {} + //~^ ERROR `i8` is not an iterator + for _ in 42 as u16 {} + //~^ ERROR `u16` is not an iterator + for _ in 42 as i16 {} + //~^ ERROR `i16` is not an iterator + for _ in 42 as u32 {} + //~^ ERROR `u32` is not an iterator + for _ in 42 as i32 {} + //~^ ERROR `i32` is not an iterator + for _ in 42 as u64 {} + //~^ ERROR `u64` is not an iterator + for _ in 42 as i64 {} + //~^ ERROR `i64` is not an iterator + for _ in 42 as usize {} + //~^ ERROR `usize` is not an iterator + for _ in 42 as isize {} + //~^ ERROR `isize` is not an iterator + for _ in 42.0 {} + //~^ ERROR `{float}` is not an iterator +} diff --git a/src/test/ui/iterators/integral.stderr b/src/test/ui/iterators/integral.stderr new file mode 100644 index 0000000000000..71e1e81e5afec --- /dev/null +++ b/src/test/ui/iterators/integral.stderr @@ -0,0 +1,122 @@ +error[E0277]: `{integer}` is not an iterator + --> $DIR/integral.rs:2:14 + | +LL | for _ in 42 {} + | ^^ `{integer}` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `{integer}` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `u8` is not an iterator + --> $DIR/integral.rs:4:14 + | +LL | for _ in 42 as u8 {} + | ^^^^^^^^ `u8` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `u8` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `i8` is not an iterator + --> $DIR/integral.rs:6:14 + | +LL | for _ in 42 as i8 {} + | ^^^^^^^^ `i8` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `i8` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `u16` is not an iterator + --> $DIR/integral.rs:8:14 + | +LL | for _ in 42 as u16 {} + | ^^^^^^^^^ `u16` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `u16` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `i16` is not an iterator + --> $DIR/integral.rs:10:14 + | +LL | for _ in 42 as i16 {} + | ^^^^^^^^^ `i16` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `i16` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `u32` is not an iterator + --> $DIR/integral.rs:12:14 + | +LL | for _ in 42 as u32 {} + | ^^^^^^^^^ `u32` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `u32` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `i32` is not an iterator + --> $DIR/integral.rs:14:14 + | +LL | for _ in 42 as i32 {} + | ^^^^^^^^^ `i32` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `i32` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `u64` is not an iterator + --> $DIR/integral.rs:16:14 + | +LL | for _ in 42 as u64 {} + | ^^^^^^^^^ `u64` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `u64` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `i64` is not an iterator + --> $DIR/integral.rs:18:14 + | +LL | for _ in 42 as i64 {} + | ^^^^^^^^^ `i64` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `i64` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `usize` is not an iterator + --> $DIR/integral.rs:20:14 + | +LL | for _ in 42 as usize {} + | ^^^^^^^^^^^ `usize` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `usize` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `isize` is not an iterator + --> $DIR/integral.rs:22:14 + | +LL | for _ in 42 as isize {} + | ^^^^^^^^^^^ `isize` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `isize` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `{float}` is not an iterator + --> $DIR/integral.rs:24:14 + | +LL | for _ in 42.0 {} + | ^^^^ `{float}` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `{float}` + = note: required by `std::iter::IntoIterator::into_iter` + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/iterators/ranges.rs b/src/test/ui/iterators/ranges.rs new file mode 100644 index 0000000000000..925d2d61a1247 --- /dev/null +++ b/src/test/ui/iterators/ranges.rs @@ -0,0 +1,9 @@ +fn main() { + for _ in ..10 {} + //~^ ERROR E0277 + for _ in ..=10 {} + //~^ ERROR E0277 + for _ in 0..10 {} + for _ in 0..=10 {} + for _ in 0.. {} +} diff --git a/src/test/ui/iterators/ranges.stderr b/src/test/ui/iterators/ranges.stderr new file mode 100644 index 0000000000000..e5e2d87879d23 --- /dev/null +++ b/src/test/ui/iterators/ranges.stderr @@ -0,0 +1,23 @@ +error[E0277]: `std::ops::RangeTo<{integer}>` is not an iterator + --> $DIR/ranges.rs:2:14 + | +LL | for _ in ..10 {} + | ^^^^ if you meant to iterate until a value, add a starting value + | + = help: the trait `std::iter::Iterator` is not implemented for `std::ops::RangeTo<{integer}>` + = note: `..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a bounded `Range`: `0..end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `std::ops::RangeToInclusive<{integer}>` is not an iterator + --> $DIR/ranges.rs:4:14 + | +LL | for _ in ..=10 {} + | ^^^^^ if you meant to iterate until a value (including it), add a starting value + | + = help: the trait `std::iter::Iterator` is not implemented for `std::ops::RangeToInclusive<{integer}>` + = note: `..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant to have a bounded `RangeInclusive`: `0..=end` + = note: required by `std::iter::IntoIterator::into_iter` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/iterators/string.rs b/src/test/ui/iterators/string.rs new file mode 100644 index 0000000000000..4373dcaabe57b --- /dev/null +++ b/src/test/ui/iterators/string.rs @@ -0,0 +1,6 @@ +fn main() { + for _ in "".to_owned() {} + //~^ ERROR `std::string::String` is not an iterator + for _ in "" {} + //~^ ERROR `&str` is not an iterator +} diff --git a/src/test/ui/iterators/string.stderr b/src/test/ui/iterators/string.stderr new file mode 100644 index 0000000000000..927de952cc827 --- /dev/null +++ b/src/test/ui/iterators/string.stderr @@ -0,0 +1,21 @@ +error[E0277]: `std::string::String` is not an iterator + --> $DIR/string.rs:2:14 + | +LL | for _ in "".to_owned() {} + | ^^^^^^^^^^^^^ `std::string::String` is not an iterator; try calling `.chars()` or `.bytes()` + | + = help: the trait `std::iter::Iterator` is not implemented for `std::string::String` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `&str` is not an iterator + --> $DIR/string.rs:4:14 + | +LL | for _ in "" {} + | ^^ `&str` is not an iterator; try calling `.chars()` or `.bytes()` + | + = help: the trait `std::iter::Iterator` is not implemented for `&str` + = note: required by `std::iter::IntoIterator::into_iter` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/suggest-remove-refs-1.rs b/src/test/ui/suggestions/suggest-remove-refs-1.rs index 0f19c48337b1e..d7c80a677a5e1 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 c47b4d283d7cd..1fc661efd91f4 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 c427f697ae1ef..37af97323d598 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 fdd654ea3923f..96c6c92d59baa 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 f54ae30caebca..c9dff35f92c0b 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 b0920a0fa523e..4311c432b41d3 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`