summaryrefslogtreecommitdiffstats
path: root/tests/ui/iterators
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/iterators')
-rw-r--r--tests/ui/iterators/array-of-ranges.rs16
-rw-r--r--tests/ui/iterators/array.rs8
-rw-r--r--tests/ui/iterators/bound.rs4
-rw-r--r--tests/ui/iterators/bound.stderr17
-rw-r--r--tests/ui/iterators/collect-into-array.rs6
-rw-r--r--tests/ui/iterators/collect-into-array.stderr13
-rw-r--r--tests/ui/iterators/collect-into-slice.rs17
-rw-r--r--tests/ui/iterators/collect-into-slice.stderr33
-rw-r--r--tests/ui/iterators/float_iterator_hint.rs15
-rw-r--r--tests/ui/iterators/float_iterator_hint.stderr13
-rw-r--r--tests/ui/iterators/integral.rs26
-rw-r--r--tests/ui/iterators/integral.stderr123
-rw-r--r--tests/ui/iterators/into-iter-on-arrays-2018.rs46
-rw-r--r--tests/ui/iterators/into-iter-on-arrays-2018.stderr65
-rw-r--r--tests/ui/iterators/into-iter-on-arrays-2021.rs32
-rw-r--r--tests/ui/iterators/into-iter-on-arrays-lint.fixed63
-rw-r--r--tests/ui/iterators/into-iter-on-arrays-lint.rs63
-rw-r--r--tests/ui/iterators/into-iter-on-arrays-lint.stderr143
-rw-r--r--tests/ui/iterators/into-iterator-type-inference-shift.rs36
-rw-r--r--tests/ui/iterators/invalid-iterator-chain-with-int-infer.rs4
-rw-r--r--tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr24
-rw-r--r--tests/ui/iterators/invalid-iterator-chain.rs53
-rw-r--r--tests/ui/iterators/invalid-iterator-chain.stderr176
-rw-r--r--tests/ui/iterators/issue-28098.rs31
-rw-r--r--tests/ui/iterators/issue-28098.stderr109
-rw-r--r--tests/ui/iterators/issue-58952-filter-type-length.rs32
-rw-r--r--tests/ui/iterators/iter-cloned-type-inference.rs16
-rw-r--r--tests/ui/iterators/iter-count-overflow-debug.rs15
-rw-r--r--tests/ui/iterators/iter-count-overflow-ndebug.rs8
-rw-r--r--tests/ui/iterators/iter-map-fold-type-length.rs38
-rw-r--r--tests/ui/iterators/iter-position-overflow-debug.rs21
-rw-r--r--tests/ui/iterators/iter-position-overflow-ndebug.rs10
-rw-r--r--tests/ui/iterators/iter-range.rs14
-rw-r--r--tests/ui/iterators/iter-step-overflow-debug.rs21
-rw-r--r--tests/ui/iterators/iter-step-overflow-ndebug.rs12
-rw-r--r--tests/ui/iterators/iter-sum-overflow-debug.rs27
-rw-r--r--tests/ui/iterators/iter-sum-overflow-ndebug.rs14
-rw-r--r--tests/ui/iterators/iter-sum-overflow-overflow-checks.rs27
-rw-r--r--tests/ui/iterators/ranges.rs9
-rw-r--r--tests/ui/iterators/ranges.stderr23
-rw-r--r--tests/ui/iterators/rsplit-clone.rs11
-rw-r--r--tests/ui/iterators/skip-count-overflow.rs8
-rw-r--r--tests/ui/iterators/string.rs6
-rw-r--r--tests/ui/iterators/string.stderr21
-rw-r--r--tests/ui/iterators/vec-on-unimplemented.rs4
-rw-r--r--tests/ui/iterators/vec-on-unimplemented.stderr18
46 files changed, 1491 insertions, 0 deletions
diff --git a/tests/ui/iterators/array-of-ranges.rs b/tests/ui/iterators/array-of-ranges.rs
new file mode 100644
index 000000000..037540a3e
--- /dev/null
+++ b/tests/ui/iterators/array-of-ranges.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+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/tests/ui/iterators/array.rs b/tests/ui/iterators/array.rs
new file mode 100644
index 000000000..5985c74e1
--- /dev/null
+++ b/tests/ui/iterators/array.rs
@@ -0,0 +1,8 @@
+// check-pass
+
+fn main() {
+ for _ in [1, 2] {}
+ let x = [1, 2];
+ for _ in x {}
+ for _ in [1.0, 2.0] {}
+}
diff --git a/tests/ui/iterators/bound.rs b/tests/ui/iterators/bound.rs
new file mode 100644
index 000000000..bdd99ef8d
--- /dev/null
+++ b/tests/ui/iterators/bound.rs
@@ -0,0 +1,4 @@
+struct S<I: Iterator>(I);
+struct T(S<u8>);
+//~^ ERROR is not an iterator
+fn main() {}
diff --git a/tests/ui/iterators/bound.stderr b/tests/ui/iterators/bound.stderr
new file mode 100644
index 000000000..cc7ded498
--- /dev/null
+++ b/tests/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>);
+ | ^^^^^ `u8` is not an iterator
+ |
+ = help: the trait `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 a bound in `S`
+ --> $DIR/bound.rs:1:13
+ |
+LL | struct S<I: Iterator>(I);
+ | ^^^^^^^^ required by this bound in `S`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/iterators/collect-into-array.rs b/tests/ui/iterators/collect-into-array.rs
new file mode 100644
index 000000000..99d0d9bd7
--- /dev/null
+++ b/tests/ui/iterators/collect-into-array.rs
@@ -0,0 +1,6 @@
+fn main() {
+ let whatever: [u32; 10] = (0..10).collect();
+ //~^ ERROR an array of type `[u32; 10]` cannot be built directly from an iterator
+ //~| NOTE try collecting into a `Vec<{integer}>`, then using `.try_into()`
+ //~| NOTE required by a bound in `collect`
+}
diff --git a/tests/ui/iterators/collect-into-array.stderr b/tests/ui/iterators/collect-into-array.stderr
new file mode 100644
index 000000000..e38745cc1
--- /dev/null
+++ b/tests/ui/iterators/collect-into-array.stderr
@@ -0,0 +1,13 @@
+error[E0277]: an array of type `[u32; 10]` cannot be built directly from an iterator
+ --> $DIR/collect-into-array.rs:2:39
+ |
+LL | let whatever: [u32; 10] = (0..10).collect();
+ | ^^^^^^^ try collecting into a `Vec<{integer}>`, then using `.try_into()`
+ |
+ = help: the trait `FromIterator<{integer}>` is not implemented for `[u32; 10]`
+note: required by a bound in `collect`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/iterators/collect-into-slice.rs b/tests/ui/iterators/collect-into-slice.rs
new file mode 100644
index 000000000..5a8aacb1a
--- /dev/null
+++ b/tests/ui/iterators/collect-into-slice.rs
@@ -0,0 +1,17 @@
+fn process_slice(data: &[i32]) {
+ todo!()
+}
+
+fn main() {
+ let some_generated_vec = (0..10).collect();
+ //~^ ERROR the size for values of type `[i32]` cannot be known at compilation time
+ //~| ERROR the size for values of type `[i32]` cannot be known at compilation time
+ //~| ERROR a slice of type `[i32]` cannot be built since `[i32]` has no definite size
+ //~| NOTE try explicitly collecting into a `Vec<{integer}>`
+ //~| NOTE required by a bound in `collect`
+ //~| NOTE required by a bound in `collect`
+ //~| NOTE all local variables must have a statically known size
+ //~| NOTE doesn't have a size known at compile-time
+ //~| NOTE doesn't have a size known at compile-time
+ process_slice(&some_generated_vec);
+}
diff --git a/tests/ui/iterators/collect-into-slice.stderr b/tests/ui/iterators/collect-into-slice.stderr
new file mode 100644
index 000000000..29fff8c51
--- /dev/null
+++ b/tests/ui/iterators/collect-into-slice.stderr
@@ -0,0 +1,33 @@
+error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
+ --> $DIR/collect-into-slice.rs:6:9
+ |
+LL | let some_generated_vec = (0..10).collect();
+ | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[i32]`
+ = note: all local variables must have a statically known size
+ = help: unsized locals are gated as an unstable feature
+
+error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
+ --> $DIR/collect-into-slice.rs:6:38
+ |
+LL | let some_generated_vec = (0..10).collect();
+ | ^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[i32]`
+note: required by a bound in `collect`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error[E0277]: a slice of type `[i32]` cannot be built since `[i32]` has no definite size
+ --> $DIR/collect-into-slice.rs:6:38
+ |
+LL | let some_generated_vec = (0..10).collect();
+ | ^^^^^^^ try explicitly collecting into a `Vec<{integer}>`
+ |
+ = help: the trait `FromIterator<{integer}>` is not implemented for `[i32]`
+note: required by a bound in `collect`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/iterators/float_iterator_hint.rs b/tests/ui/iterators/float_iterator_hint.rs
new file mode 100644
index 000000000..a3335ca41
--- /dev/null
+++ b/tests/ui/iterators/float_iterator_hint.rs
@@ -0,0 +1,15 @@
+// #106728
+
+fn main() {
+ for i in 0.2 {
+ //~^ ERROR `{float}` is not an iterator
+ //~| `{float}` is not an iterator
+ //~| NOTE in this expansion of desugaring of `for` loop
+ //~| NOTE in this expansion of desugaring of `for` loop
+ //~| NOTE in this expansion of desugaring of `for` loop
+ //~| NOTE in this expansion of desugaring of `for` loop
+ //~| 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 for `{float}` to implement `IntoIterator`
+ println!();
+ }
+}
diff --git a/tests/ui/iterators/float_iterator_hint.stderr b/tests/ui/iterators/float_iterator_hint.stderr
new file mode 100644
index 000000000..bae23a1f8
--- /dev/null
+++ b/tests/ui/iterators/float_iterator_hint.stderr
@@ -0,0 +1,13 @@
+error[E0277]: `{float}` is not an iterator
+ --> $DIR/float_iterator_hint.rs:4:14
+ |
+LL | for i in 0.2 {
+ | ^^^ `{float}` is not an iterator
+ |
+ = help: the trait `Iterator` is not implemented for `{float}`
+ = 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 for `{float}` to implement `IntoIterator`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/iterators/integral.rs b/tests/ui/iterators/integral.rs
new file mode 100644
index 000000000..7537c7904
--- /dev/null
+++ b/tests/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/tests/ui/iterators/integral.stderr b/tests/ui/iterators/integral.stderr
new file mode 100644
index 000000000..c142fec8d
--- /dev/null
+++ b/tests/ui/iterators/integral.stderr
@@ -0,0 +1,123 @@
+error[E0277]: `{integer}` is not an iterator
+ --> $DIR/integral.rs:2:14
+ |
+LL | for _ in 42 {}
+ | ^^ `{integer}` is not an iterator
+ |
+ = help: the trait `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 for `{integer}` to implement `IntoIterator`
+
+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 `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 for `u8` to implement `IntoIterator`
+
+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 `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 for `i8` to implement `IntoIterator`
+
+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 `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 for `u16` to implement `IntoIterator`
+
+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 `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 for `i16` to implement `IntoIterator`
+
+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 `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 for `u32` to implement `IntoIterator`
+
+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 `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 for `i32` to implement `IntoIterator`
+
+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 `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 for `u64` to implement `IntoIterator`
+
+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 `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 for `i64` to implement `IntoIterator`
+
+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 `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 for `usize` to implement `IntoIterator`
+
+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 `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 for `isize` to implement `IntoIterator`
+
+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 `Iterator` is not implemented for `{float}`
+ = 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 for `{float}` to implement `IntoIterator`
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/iterators/into-iter-on-arrays-2018.rs b/tests/ui/iterators/into-iter-on-arrays-2018.rs
new file mode 100644
index 000000000..60995170a
--- /dev/null
+++ b/tests/ui/iterators/into-iter-on-arrays-2018.rs
@@ -0,0 +1,46 @@
+// check-pass
+// edition:2018
+
+use std::array::IntoIter;
+use std::ops::Deref;
+use std::rc::Rc;
+use std::slice::Iter;
+
+fn main() {
+ let array = [0; 10];
+
+ // Before 2021, the method dispatched to `IntoIterator for &[T; N]`,
+ // which we continue to support for compatibility.
+ let _: Iter<'_, i32> = array.into_iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+
+ let _: Iter<'_, i32> = Box::new(array).into_iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+
+ let _: Iter<'_, i32> = Rc::new(array).into_iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+ let _: Iter<'_, i32> = Array(array).into_iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+
+ // But you can always use the trait method explicitly as an array.
+ let _: IntoIter<i32, 10> = IntoIterator::into_iter(array);
+
+ for _ in [1, 2, 3].into_iter() {}
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+}
+
+/// User type that dereferences to an array.
+struct Array([i32; 10]);
+
+impl Deref for Array {
+ type Target = [i32; 10];
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
diff --git a/tests/ui/iterators/into-iter-on-arrays-2018.stderr b/tests/ui/iterators/into-iter-on-arrays-2018.stderr
new file mode 100644
index 000000000..2378476e5
--- /dev/null
+++ b/tests/ui/iterators/into-iter-on-arrays-2018.stderr
@@ -0,0 +1,65 @@
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021
+ --> $DIR/into-iter-on-arrays-2018.rs:14:34
+ |
+LL | let _: Iter<'_, i32> = array.into_iter();
+ | ^^^^^^^^^
+ |
+ = warning: this changes meaning in Rust 2021
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: `#[warn(array_into_iter)]` on by default
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
+ |
+LL | let _: Iter<'_, i32> = array.iter();
+ | ~~~~
+help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
+ |
+LL | let _: Iter<'_, i32> = IntoIterator::into_iter(array);
+ | ++++++++++++++++++++++++ ~
+
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021
+ --> $DIR/into-iter-on-arrays-2018.rs:18:44
+ |
+LL | let _: Iter<'_, i32> = Box::new(array).into_iter();
+ | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+ |
+ = warning: this changes meaning in Rust 2021
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021
+ --> $DIR/into-iter-on-arrays-2018.rs:22:43
+ |
+LL | let _: Iter<'_, i32> = Rc::new(array).into_iter();
+ | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+ |
+ = warning: this changes meaning in Rust 2021
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021
+ --> $DIR/into-iter-on-arrays-2018.rs:25:41
+ |
+LL | let _: Iter<'_, i32> = Array(array).into_iter();
+ | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+ |
+ = warning: this changes meaning in Rust 2021
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021
+ --> $DIR/into-iter-on-arrays-2018.rs:32:24
+ |
+LL | for _ in [1, 2, 3].into_iter() {}
+ | ^^^^^^^^^
+ |
+ = warning: this changes meaning in Rust 2021
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
+ |
+LL | for _ in [1, 2, 3].iter() {}
+ | ~~~~
+help: or remove `.into_iter()` to iterate by value
+ |
+LL - for _ in [1, 2, 3].into_iter() {}
+LL + for _ in [1, 2, 3] {}
+ |
+
+warning: 5 warnings emitted
+
diff --git a/tests/ui/iterators/into-iter-on-arrays-2021.rs b/tests/ui/iterators/into-iter-on-arrays-2021.rs
new file mode 100644
index 000000000..158317efe
--- /dev/null
+++ b/tests/ui/iterators/into-iter-on-arrays-2021.rs
@@ -0,0 +1,32 @@
+// check-pass
+// edition:2021
+
+use std::array::IntoIter;
+use std::ops::Deref;
+use std::rc::Rc;
+
+fn main() {
+ let array = [0; 10];
+
+ // In 2021, the method dispatches to `IntoIterator for [T; N]`.
+ let _: IntoIter<i32, 10> = array.into_iter();
+ let _: IntoIter<i32, 10> = Box::new(array).into_iter();
+
+ // The `array_into_iter` lint doesn't cover other wrappers that deref to an array.
+ let _: IntoIter<i32, 10> = Rc::new(array).into_iter();
+ let _: IntoIter<i32, 10> = Array(array).into_iter();
+
+ // You can always use the trait method explicitly as an array.
+ let _: IntoIter<i32, 10> = IntoIterator::into_iter(array);
+}
+
+/// User type that dereferences to an array.
+struct Array([i32; 10]);
+
+impl Deref for Array {
+ type Target = [i32; 10];
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
diff --git a/tests/ui/iterators/into-iter-on-arrays-lint.fixed b/tests/ui/iterators/into-iter-on-arrays-lint.fixed
new file mode 100644
index 000000000..6e02a7024
--- /dev/null
+++ b/tests/ui/iterators/into-iter-on-arrays-lint.fixed
@@ -0,0 +1,63 @@
+// run-pass
+// run-rustfix
+// rustfix-only-machine-applicable
+
+#[allow(unused_must_use)]
+fn main() {
+ let small = [1, 2];
+ let big = [0u8; 33];
+
+ // Expressions that should trigger the lint
+ small.iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+ [1, 2].iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+ big.iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+ [0u8; 33].iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+
+ Box::new(small).iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+ Box::new([1, 2]).iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+ Box::new(big).iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+ Box::new([0u8; 33]).iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+
+ Box::new(Box::new(small)).iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+ Box::new(Box::new([1, 2])).iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+ Box::new(Box::new(big)).iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+ Box::new(Box::new([0u8; 33])).iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+
+ // Expressions that should not
+ (&[1, 2]).into_iter();
+ (&small).into_iter();
+ (&[0u8; 33]).into_iter();
+ (&big).into_iter();
+
+ for _ in &[1, 2] {}
+ (&small as &[_]).into_iter();
+ small[..].into_iter();
+ std::iter::IntoIterator::into_iter(&[1, 2]);
+
+ #[allow(array_into_iter)]
+ [0, 1].into_iter();
+}
diff --git a/tests/ui/iterators/into-iter-on-arrays-lint.rs b/tests/ui/iterators/into-iter-on-arrays-lint.rs
new file mode 100644
index 000000000..582d5cadd
--- /dev/null
+++ b/tests/ui/iterators/into-iter-on-arrays-lint.rs
@@ -0,0 +1,63 @@
+// run-pass
+// run-rustfix
+// rustfix-only-machine-applicable
+
+#[allow(unused_must_use)]
+fn main() {
+ let small = [1, 2];
+ let big = [0u8; 33];
+
+ // Expressions that should trigger the lint
+ small.into_iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+ [1, 2].into_iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+ big.into_iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+ [0u8; 33].into_iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+
+ Box::new(small).into_iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+ Box::new([1, 2]).into_iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+ Box::new(big).into_iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+ Box::new([0u8; 33]).into_iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+
+ Box::new(Box::new(small)).into_iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+ Box::new(Box::new([1, 2])).into_iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+ Box::new(Box::new(big)).into_iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+ Box::new(Box::new([0u8; 33])).into_iter();
+ //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+ //~| WARNING this changes meaning
+
+ // Expressions that should not
+ (&[1, 2]).into_iter();
+ (&small).into_iter();
+ (&[0u8; 33]).into_iter();
+ (&big).into_iter();
+
+ for _ in &[1, 2] {}
+ (&small as &[_]).into_iter();
+ small[..].into_iter();
+ std::iter::IntoIterator::into_iter(&[1, 2]);
+
+ #[allow(array_into_iter)]
+ [0, 1].into_iter();
+}
diff --git a/tests/ui/iterators/into-iter-on-arrays-lint.stderr b/tests/ui/iterators/into-iter-on-arrays-lint.stderr
new file mode 100644
index 000000000..2fde276fa
--- /dev/null
+++ b/tests/ui/iterators/into-iter-on-arrays-lint.stderr
@@ -0,0 +1,143 @@
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021
+ --> $DIR/into-iter-on-arrays-lint.rs:11:11
+ |
+LL | small.into_iter();
+ | ^^^^^^^^^
+ |
+ = warning: this changes meaning in Rust 2021
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: `#[warn(array_into_iter)]` on by default
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
+ |
+LL | small.iter();
+ | ~~~~
+help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
+ |
+LL | IntoIterator::into_iter(small);
+ | ++++++++++++++++++++++++ ~
+
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021
+ --> $DIR/into-iter-on-arrays-lint.rs:14:12
+ |
+LL | [1, 2].into_iter();
+ | ^^^^^^^^^
+ |
+ = warning: this changes meaning in Rust 2021
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
+ |
+LL | [1, 2].iter();
+ | ~~~~
+help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
+ |
+LL | IntoIterator::into_iter([1, 2]);
+ | ++++++++++++++++++++++++ ~
+
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021
+ --> $DIR/into-iter-on-arrays-lint.rs:17:9
+ |
+LL | big.into_iter();
+ | ^^^^^^^^^
+ |
+ = warning: this changes meaning in Rust 2021
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
+ |
+LL | big.iter();
+ | ~~~~
+help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
+ |
+LL | IntoIterator::into_iter(big);
+ | ++++++++++++++++++++++++ ~
+
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021
+ --> $DIR/into-iter-on-arrays-lint.rs:20:15
+ |
+LL | [0u8; 33].into_iter();
+ | ^^^^^^^^^
+ |
+ = warning: this changes meaning in Rust 2021
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
+ |
+LL | [0u8; 33].iter();
+ | ~~~~
+help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
+ |
+LL | IntoIterator::into_iter([0u8; 33]);
+ | ++++++++++++++++++++++++ ~
+
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021
+ --> $DIR/into-iter-on-arrays-lint.rs:24:21
+ |
+LL | Box::new(small).into_iter();
+ | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+ |
+ = warning: this changes meaning in Rust 2021
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021
+ --> $DIR/into-iter-on-arrays-lint.rs:27:22
+ |
+LL | Box::new([1, 2]).into_iter();
+ | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+ |
+ = warning: this changes meaning in Rust 2021
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021
+ --> $DIR/into-iter-on-arrays-lint.rs:30:19
+ |
+LL | Box::new(big).into_iter();
+ | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+ |
+ = warning: this changes meaning in Rust 2021
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021
+ --> $DIR/into-iter-on-arrays-lint.rs:33:25
+ |
+LL | Box::new([0u8; 33]).into_iter();
+ | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+ |
+ = warning: this changes meaning in Rust 2021
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021
+ --> $DIR/into-iter-on-arrays-lint.rs:37:31
+ |
+LL | Box::new(Box::new(small)).into_iter();
+ | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+ |
+ = warning: this changes meaning in Rust 2021
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021
+ --> $DIR/into-iter-on-arrays-lint.rs:40:32
+ |
+LL | Box::new(Box::new([1, 2])).into_iter();
+ | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+ |
+ = warning: this changes meaning in Rust 2021
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021
+ --> $DIR/into-iter-on-arrays-lint.rs:43:29
+ |
+LL | Box::new(Box::new(big)).into_iter();
+ | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+ |
+ = warning: this changes meaning in Rust 2021
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021
+ --> $DIR/into-iter-on-arrays-lint.rs:46:35
+ |
+LL | Box::new(Box::new([0u8; 33])).into_iter();
+ | ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+ |
+ = warning: this changes meaning in Rust 2021
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+
+warning: 12 warnings emitted
+
diff --git a/tests/ui/iterators/into-iterator-type-inference-shift.rs b/tests/ui/iterators/into-iterator-type-inference-shift.rs
new file mode 100644
index 000000000..9151172fd
--- /dev/null
+++ b/tests/ui/iterators/into-iterator-type-inference-shift.rs
@@ -0,0 +1,36 @@
+// run-pass
+#![allow(unused_must_use)]
+#![allow(dead_code)]
+#![allow(unused_mut)]
+#![allow(unused_variables)]
+// Regression test for type inference failure around shifting. In this
+// case, the iteration yields an isize, but we hadn't run the full type
+// propagation yet, and so we just saw a type variable, yielding an
+// error.
+
+// pretty-expanded FIXME #23616
+
+trait IntoIterator {
+ type Iter: Iterator;
+
+ fn into_iter(self) -> Self::Iter;
+}
+
+impl<I> IntoIterator for I where I: Iterator {
+ type Iter = I;
+
+ fn into_iter(self) -> I {
+ self
+ }
+}
+
+fn desugared_for_loop_bad(byte: u8) -> u8 {
+ let mut result = 0;
+ let mut x = IntoIterator::into_iter(0..8);
+ let mut y = Iterator::next(&mut x);
+ let mut z = y.unwrap();
+ byte >> z;
+ 1
+}
+
+fn main() {}
diff --git a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.rs b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.rs
new file mode 100644
index 000000000..882a1d139
--- /dev/null
+++ b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let x = Some(()).iter().map(|()| 1).sum::<f32>();
+ //~^ ERROR a value of type `f32` cannot be made by summing an iterator over elements of type `{integer}`
+}
diff --git a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr
new file mode 100644
index 000000000..3cb5e44c7
--- /dev/null
+++ b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr
@@ -0,0 +1,24 @@
+error[E0277]: a value of type `f32` cannot be made by summing an iterator over elements of type `{integer}`
+ --> $DIR/invalid-iterator-chain-with-int-infer.rs:2:41
+ |
+LL | let x = Some(()).iter().map(|()| 1).sum::<f32>();
+ | ^^^ value of type `f32` cannot be made by summing a `std::iter::Iterator<Item={integer}>`
+ |
+ = help: the trait `Sum<{integer}>` is not implemented for `f32`
+ = help: the following other types implement trait `Sum<A>`:
+ <f32 as Sum<&'a f32>>
+ <f32 as Sum>
+note: the method call chain might not have had the expected associated types
+ --> $DIR/invalid-iterator-chain-with-int-infer.rs:2:29
+ |
+LL | let x = Some(()).iter().map(|()| 1).sum::<f32>();
+ | -------- ------ ^^^^^^^^^^^ `Iterator::Item` changed to `{integer}` here
+ | | |
+ | | `Iterator::Item` is `&()` here
+ | this expression has type `Option<()>`
+note: required by a bound in `std::iter::Iterator::sum`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/iterators/invalid-iterator-chain.rs b/tests/ui/iterators/invalid-iterator-chain.rs
new file mode 100644
index 000000000..ebdf33303
--- /dev/null
+++ b/tests/ui/iterators/invalid-iterator-chain.rs
@@ -0,0 +1,53 @@
+use std::collections::hash_set::Iter;
+use std::collections::HashSet;
+
+fn iter_to_vec<'b, X>(i: Iter<'b, X>) -> Vec<X> {
+ let i = i.map(|x| x.clone());
+ i.collect() //~ ERROR E0277
+}
+
+fn main() {
+ let scores = vec![(0, 0)]
+ .iter()
+ .map(|(a, b)| {
+ a + b;
+ });
+ println!("{}", scores.sum::<i32>()); //~ ERROR E0277
+ println!(
+ "{}",
+ vec![0, 1]
+ .iter()
+ .map(|x| x * 2)
+ .map(|x| x as f64)
+ .map(|x| x as i64)
+ .filter(|x| *x > 0)
+ .map(|x| { x + 1 })
+ .map(|x| { x; })
+ .sum::<i32>(), //~ ERROR E0277
+ );
+ println!(
+ "{}",
+ vec![0, 1]
+ .iter()
+ .map(|x| x * 2)
+ .map(|x| x as f64)
+ .filter(|x| *x > 0.0)
+ .map(|x| { x + 1.0 })
+ .sum::<i32>(), //~ ERROR E0277
+ );
+ println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>()); //~ ERROR E0277
+ println!("{}", vec![(), ()].iter().sum::<i32>()); //~ ERROR E0277
+ let a = vec![0];
+ let b = a.into_iter();
+ let c = b.map(|x| x + 1);
+ let d = c.filter(|x| *x > 10 );
+ let e = d.map(|x| {
+ x + 1;
+ });
+ let f = e.filter(|_| false);
+ let g: Vec<i32> = f.collect(); //~ ERROR E0277
+
+ let mut s = HashSet::new();
+ s.insert(1u8);
+ println!("{:?}", iter_to_vec(s.iter()));
+}
diff --git a/tests/ui/iterators/invalid-iterator-chain.stderr b/tests/ui/iterators/invalid-iterator-chain.stderr
new file mode 100644
index 000000000..f3dceca7e
--- /dev/null
+++ b/tests/ui/iterators/invalid-iterator-chain.stderr
@@ -0,0 +1,176 @@
+error[E0277]: a value of type `Vec<X>` cannot be built from an iterator over elements of type `&X`
+ --> $DIR/invalid-iterator-chain.rs:6:7
+ |
+LL | i.collect()
+ | ^^^^^^^ value of type `Vec<X>` cannot be built from `std::iter::Iterator<Item=&X>`
+ |
+ = help: the trait `FromIterator<&X>` is not implemented for `Vec<X>`
+ = help: the trait `FromIterator<T>` is implemented for `Vec<T>`
+note: the method call chain might not have had the expected associated types
+ --> $DIR/invalid-iterator-chain.rs:4:26
+ |
+LL | fn iter_to_vec<'b, X>(i: Iter<'b, X>) -> Vec<X> {
+ | ^^^^^^^^^^^ `Iterator::Item` is `&X` here
+LL | let i = i.map(|x| x.clone());
+ | ------------------ `Iterator::Item` remains `&X` here
+note: required by a bound in `collect`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `()`
+ --> $DIR/invalid-iterator-chain.rs:15:27
+ |
+LL | println!("{}", scores.sum::<i32>());
+ | ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=()>`
+ |
+ = help: the trait `Sum<()>` is not implemented for `i32`
+ = help: the following other types implement trait `Sum<A>`:
+ <i32 as Sum<&'a i32>>
+ <i32 as Sum>
+note: the method call chain might not have had the expected associated types
+ --> $DIR/invalid-iterator-chain.rs:12:10
+ |
+LL | let scores = vec![(0, 0)]
+ | ------------ this expression has type `Vec<({integer}, {integer})>`
+LL | .iter()
+ | ------ `Iterator::Item` is `&({integer}, {integer})` here
+LL | .map(|(a, b)| {
+ | __________^
+LL | | a + b;
+LL | | });
+ | |__________^ `Iterator::Item` changed to `()` here
+note: required by a bound in `std::iter::Iterator::sum`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `()`
+ --> $DIR/invalid-iterator-chain.rs:26:14
+ |
+LL | .sum::<i32>(),
+ | ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=()>`
+ |
+ = help: the trait `Sum<()>` is not implemented for `i32`
+ = help: the following other types implement trait `Sum<A>`:
+ <i32 as Sum<&'a i32>>
+ <i32 as Sum>
+note: the method call chain might not have had the expected associated types
+ --> $DIR/invalid-iterator-chain.rs:25:14
+ |
+LL | vec![0, 1]
+ | ---------- this expression has type `Vec<{integer}>`
+LL | .iter()
+ | ------ `Iterator::Item` is `&{integer}` here
+LL | .map(|x| x * 2)
+ | -------------- `Iterator::Item` changed to `{integer}` here
+LL | .map(|x| x as f64)
+ | ----------------- `Iterator::Item` changed to `f64` here
+LL | .map(|x| x as i64)
+ | ----------------- `Iterator::Item` changed to `i64` here
+LL | .filter(|x| *x > 0)
+ | ------------------ `Iterator::Item` remains `i64` here
+LL | .map(|x| { x + 1 })
+ | ------------------ `Iterator::Item` remains `i64` here
+LL | .map(|x| { x; })
+ | ^^^^^^^^^^^^^^^ `Iterator::Item` changed to `()` here
+note: required by a bound in `std::iter::Iterator::sum`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `f64`
+ --> $DIR/invalid-iterator-chain.rs:36:14
+ |
+LL | .sum::<i32>(),
+ | ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=f64>`
+ |
+ = help: the trait `Sum<f64>` is not implemented for `i32`
+ = help: the following other types implement trait `Sum<A>`:
+ <i32 as Sum<&'a i32>>
+ <i32 as Sum>
+note: the method call chain might not have had the expected associated types
+ --> $DIR/invalid-iterator-chain.rs:33:14
+ |
+LL | vec![0, 1]
+ | ---------- this expression has type `Vec<{integer}>`
+LL | .iter()
+ | ------ `Iterator::Item` is `&{integer}` here
+LL | .map(|x| x * 2)
+ | -------------- `Iterator::Item` changed to `{integer}` here
+LL | .map(|x| x as f64)
+ | ^^^^^^^^^^^^^^^^^ `Iterator::Item` changed to `f64` here
+LL | .filter(|x| *x > 0.0)
+ | -------------------- `Iterator::Item` remains `f64` here
+LL | .map(|x| { x + 1.0 })
+ | -------------------- `Iterator::Item` remains `f64` here
+note: required by a bound in `std::iter::Iterator::sum`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `()`
+ --> $DIR/invalid-iterator-chain.rs:38:54
+ |
+LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>());
+ | ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=()>`
+ |
+ = help: the trait `Sum<()>` is not implemented for `i32`
+ = help: the following other types implement trait `Sum<A>`:
+ <i32 as Sum<&'a i32>>
+ <i32 as Sum>
+note: the method call chain might not have had the expected associated types
+ --> $DIR/invalid-iterator-chain.rs:38:38
+ |
+LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>());
+ | ---------- ------ ^^^^^^^^^^^^^^^ `Iterator::Item` changed to `()` here
+ | | |
+ | | `Iterator::Item` is `&{integer}` here
+ | this expression has type `Vec<{integer}>`
+note: required by a bound in `std::iter::Iterator::sum`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `&()`
+ --> $DIR/invalid-iterator-chain.rs:39:40
+ |
+LL | println!("{}", vec![(), ()].iter().sum::<i32>());
+ | ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=&()>`
+ |
+ = help: the trait `Sum<&()>` is not implemented for `i32`
+ = help: the following other types implement trait `Sum<A>`:
+ <i32 as Sum<&'a i32>>
+ <i32 as Sum>
+note: the method call chain might not have had the expected associated types
+ --> $DIR/invalid-iterator-chain.rs:39:33
+ |
+LL | println!("{}", vec![(), ()].iter().sum::<i32>());
+ | ------------ ^^^^^^ `Iterator::Item` is `&()` here
+ | |
+ | this expression has type `Vec<()>`
+note: required by a bound in `std::iter::Iterator::sum`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error[E0277]: a value of type `Vec<i32>` cannot be built from an iterator over elements of type `()`
+ --> $DIR/invalid-iterator-chain.rs:48:25
+ |
+LL | let g: Vec<i32> = f.collect();
+ | ^^^^^^^ value of type `Vec<i32>` cannot be built from `std::iter::Iterator<Item=()>`
+ |
+ = help: the trait `FromIterator<()>` is not implemented for `Vec<i32>`
+ = help: the trait `FromIterator<T>` is implemented for `Vec<T>`
+note: the method call chain might not have had the expected associated types
+ --> $DIR/invalid-iterator-chain.rs:44:15
+ |
+LL | let a = vec![0];
+ | ------- this expression has type `Vec<{integer}>`
+LL | let b = a.into_iter();
+ | ----------- `Iterator::Item` is `{integer}` here
+LL | let c = b.map(|x| x + 1);
+ | -------------- `Iterator::Item` remains `{integer}` here
+LL | let d = c.filter(|x| *x > 10 );
+ | -------------------- `Iterator::Item` remains `{integer}` here
+LL | let e = d.map(|x| {
+ | _______________^
+LL | | x + 1;
+LL | | });
+ | |______^ `Iterator::Item` changed to `()` here
+LL | let f = e.filter(|_| false);
+ | ----------------- `Iterator::Item` remains `()` here
+note: required by a bound in `collect`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/iterators/issue-28098.rs b/tests/ui/iterators/issue-28098.rs
new file mode 100644
index 000000000..80c77edae
--- /dev/null
+++ b/tests/ui/iterators/issue-28098.rs
@@ -0,0 +1,31 @@
+fn main() {
+ let _ = Iterator::next(&mut ());
+ //~^ ERROR `()` is not an iterator
+ //~| ERROR `()` is not an iterator
+ //~| ERROR `()` is not an iterator
+
+ for _ in false {}
+ //~^ ERROR `bool` is not an iterator
+
+ let _ = Iterator::next(&mut ());
+ //~^ ERROR `()` is not an iterator
+ //~| ERROR `()` is not an iterator
+
+ other()
+}
+
+pub fn other() {
+ // check errors are still reported globally
+
+ let _ = Iterator::next(&mut ());
+ //~^ ERROR `()` is not an iterator
+ //~| ERROR `()` is not an iterator
+ //~| ERROR `()` is not an iterator
+
+ let _ = Iterator::next(&mut ());
+ //~^ ERROR `()` is not an iterator
+ //~| ERROR `()` is not an iterator
+
+ for _ in false {}
+ //~^ ERROR `bool` is not an iterator
+}
diff --git a/tests/ui/iterators/issue-28098.stderr b/tests/ui/iterators/issue-28098.stderr
new file mode 100644
index 000000000..3256e57d4
--- /dev/null
+++ b/tests/ui/iterators/issue-28098.stderr
@@ -0,0 +1,109 @@
+error[E0277]: `()` is not an iterator
+ --> $DIR/issue-28098.rs:2:28
+ |
+LL | let _ = Iterator::next(&mut ());
+ | -------------- ^^^^^^^ `()` is not an iterator
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `Iterator` is not implemented for `()`
+
+error[E0277]: `()` is not an iterator
+ --> $DIR/issue-28098.rs:2:13
+ |
+LL | let _ = Iterator::next(&mut ());
+ | ^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
+ |
+ = help: the trait `Iterator` is not implemented for `()`
+
+error[E0277]: `bool` is not an iterator
+ --> $DIR/issue-28098.rs:7:14
+ |
+LL | for _ in false {}
+ | ^^^^^ `bool` is not an iterator
+ |
+ = help: the trait `Iterator` is not implemented for `bool`
+ = note: required for `bool` to implement `IntoIterator`
+
+error[E0277]: `()` is not an iterator
+ --> $DIR/issue-28098.rs:10:28
+ |
+LL | let _ = Iterator::next(&mut ());
+ | -------------- ^^^^^^^ `()` is not an iterator
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `Iterator` is not implemented for `()`
+
+error[E0277]: `()` is not an iterator
+ --> $DIR/issue-28098.rs:10:13
+ |
+LL | let _ = Iterator::next(&mut ());
+ | ^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
+ |
+ = help: the trait `Iterator` is not implemented for `()`
+
+error[E0277]: `()` is not an iterator
+ --> $DIR/issue-28098.rs:2:13
+ |
+LL | let _ = Iterator::next(&mut ());
+ | ^^^^^^^^^^^^^^ `()` is not an iterator
+ |
+ = help: the trait `Iterator` is not implemented for `()`
+
+error[E0277]: `()` is not an iterator
+ --> $DIR/issue-28098.rs:20:28
+ |
+LL | let _ = Iterator::next(&mut ());
+ | -------------- ^^^^^^^ `()` is not an iterator
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `Iterator` is not implemented for `()`
+
+error[E0277]: `()` is not an iterator
+ --> $DIR/issue-28098.rs:20:13
+ |
+LL | let _ = Iterator::next(&mut ());
+ | ^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
+ |
+ = help: the trait `Iterator` is not implemented for `()`
+
+error[E0277]: `()` is not an iterator
+ --> $DIR/issue-28098.rs:25:28
+ |
+LL | let _ = Iterator::next(&mut ());
+ | -------------- ^^^^^^^ `()` is not an iterator
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `Iterator` is not implemented for `()`
+
+error[E0277]: `()` is not an iterator
+ --> $DIR/issue-28098.rs:25:13
+ |
+LL | let _ = Iterator::next(&mut ());
+ | ^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
+ |
+ = help: the trait `Iterator` is not implemented for `()`
+
+error[E0277]: `bool` is not an iterator
+ --> $DIR/issue-28098.rs:29:14
+ |
+LL | for _ in false {}
+ | ^^^^^ `bool` is not an iterator
+ |
+ = help: the trait `Iterator` is not implemented for `bool`
+ = note: required for `bool` to implement `IntoIterator`
+
+error[E0277]: `()` is not an iterator
+ --> $DIR/issue-28098.rs:20:13
+ |
+LL | let _ = Iterator::next(&mut ());
+ | ^^^^^^^^^^^^^^ `()` is not an iterator
+ |
+ = help: the trait `Iterator` is not implemented for `()`
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/iterators/issue-58952-filter-type-length.rs b/tests/ui/iterators/issue-58952-filter-type-length.rs
new file mode 100644
index 000000000..6d12db8d1
--- /dev/null
+++ b/tests/ui/iterators/issue-58952-filter-type-length.rs
@@ -0,0 +1,32 @@
+// run-pass
+//! This snippet causes the type length to blowup exponentially,
+//! so check that we don't accidentally exceed the type length limit.
+// FIXME: Once the size of iterator adaptors is further reduced,
+// increase the complexity of this test.
+use std::collections::VecDeque;
+
+fn main() {
+ let c = 2;
+ let bv = vec![2];
+ let b = bv
+ .iter()
+ .filter(|a| **a == c);
+
+ let _a = vec![1, 2, 3]
+ .into_iter()
+ .filter(|a| b.clone().any(|b| *b == *a))
+ .filter(|a| b.clone().any(|b| *b == *a))
+ .filter(|a| b.clone().any(|b| *b == *a))
+ .filter(|a| b.clone().any(|b| *b == *a))
+ .filter(|a| b.clone().any(|b| *b == *a))
+ .filter(|a| b.clone().any(|b| *b == *a))
+ .filter(|a| b.clone().any(|b| *b == *a))
+ .filter(|a| b.clone().any(|b| *b == *a))
+ .filter(|a| b.clone().any(|b| *b == *a))
+ .filter(|a| b.clone().any(|b| *b == *a))
+ .filter(|a| b.clone().any(|b| *b == *a))
+ .filter(|a| b.clone().any(|b| *b == *a))
+ .filter(|a| b.clone().any(|b| *b == *a))
+ .filter(|a| b.clone().any(|b| *b == *a))
+ .collect::<VecDeque<_>>();
+}
diff --git a/tests/ui/iterators/iter-cloned-type-inference.rs b/tests/ui/iterators/iter-cloned-type-inference.rs
new file mode 100644
index 000000000..898e33719
--- /dev/null
+++ b/tests/ui/iterators/iter-cloned-type-inference.rs
@@ -0,0 +1,16 @@
+// run-pass
+#![allow(stable_features)]
+
+// Test to see that the element type of .cloned() can be inferred
+// properly. Previously this would fail to deduce the type of `sum`.
+
+#![feature(iter_arith)]
+
+fn square_sum(v: &[i64]) -> i64 {
+ let sum: i64 = v.iter().cloned().sum();
+ sum * sum
+}
+
+fn main() {
+ assert_eq!(36, square_sum(&[1,2,3]));
+}
diff --git a/tests/ui/iterators/iter-count-overflow-debug.rs b/tests/ui/iterators/iter-count-overflow-debug.rs
new file mode 100644
index 000000000..8e59c11e9
--- /dev/null
+++ b/tests/ui/iterators/iter-count-overflow-debug.rs
@@ -0,0 +1,15 @@
+// run-pass
+// only-32bit too impatient for 2⁶⁴ items
+// needs-unwind
+// compile-flags: -C debug_assertions=yes -C opt-level=3
+
+use std::panic;
+
+fn main() {
+ assert_eq!((0..usize::MAX).by_ref().count(), usize::MAX);
+
+ let r = panic::catch_unwind(|| {
+ (0..=usize::MAX).by_ref().count()
+ });
+ assert!(r.is_err());
+}
diff --git a/tests/ui/iterators/iter-count-overflow-ndebug.rs b/tests/ui/iterators/iter-count-overflow-ndebug.rs
new file mode 100644
index 000000000..dcaaff671
--- /dev/null
+++ b/tests/ui/iterators/iter-count-overflow-ndebug.rs
@@ -0,0 +1,8 @@
+// run-pass
+// only-32bit too impatient for 2⁶⁴ items
+// compile-flags: -C debug_assertions=no -C opt-level=3
+
+fn main() {
+ assert_eq!((0..usize::MAX).by_ref().count(), usize::MAX);
+ assert_eq!((0..=usize::MAX).by_ref().count(), 0);
+}
diff --git a/tests/ui/iterators/iter-map-fold-type-length.rs b/tests/ui/iterators/iter-map-fold-type-length.rs
new file mode 100644
index 000000000..8ce4fcd87
--- /dev/null
+++ b/tests/ui/iterators/iter-map-fold-type-length.rs
@@ -0,0 +1,38 @@
+// run-pass
+//! Check that type lengths don't explode with `Map` folds.
+//!
+//! The normal limit is a million, and this test used to exceed 1.5 million, but
+//! now we can survive an even tighter limit. Still seems excessive though...
+#![type_length_limit = "256000"]
+
+// Custom wrapper so Iterator methods aren't specialized.
+struct Iter<I>(I);
+
+impl<I> Iterator for Iter<I>
+where
+ I: Iterator
+{
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.0.next()
+ }
+}
+
+fn main() {
+ let c = Iter(0i32..10)
+ .map(|x| x)
+ .map(|x| x)
+ .map(|x| x)
+ .map(|x| x)
+ .map(|x| x)
+ .map(|x| x)
+ .map(|x| x)
+ .map(|x| x)
+ .map(|x| x)
+ .map(|x| x)
+ .map(|x| x)
+ .map(|x| x)
+ .count();
+ assert_eq!(c, 10);
+}
diff --git a/tests/ui/iterators/iter-position-overflow-debug.rs b/tests/ui/iterators/iter-position-overflow-debug.rs
new file mode 100644
index 000000000..7a871e744
--- /dev/null
+++ b/tests/ui/iterators/iter-position-overflow-debug.rs
@@ -0,0 +1,21 @@
+// run-pass
+// only-32bit too impatient for 2⁶⁴ items
+// needs-unwind
+// compile-flags: -C debug_assertions=yes -C opt-level=3
+
+use std::panic;
+
+fn main() {
+ let n = usize::MAX as u64;
+ assert_eq!((0..).by_ref().position(|i| i >= n), Some(usize::MAX));
+
+ let r = panic::catch_unwind(|| {
+ (0..).by_ref().position(|i| i > n)
+ });
+ assert!(r.is_err());
+
+ let r = panic::catch_unwind(|| {
+ (0..=n + 1).by_ref().position(|_| false)
+ });
+ assert!(r.is_err());
+}
diff --git a/tests/ui/iterators/iter-position-overflow-ndebug.rs b/tests/ui/iterators/iter-position-overflow-ndebug.rs
new file mode 100644
index 000000000..e610c3559
--- /dev/null
+++ b/tests/ui/iterators/iter-position-overflow-ndebug.rs
@@ -0,0 +1,10 @@
+// run-pass
+// only-32bit too impatient for 2⁶⁴ items
+// compile-flags: -C debug_assertions=no -C opt-level=3
+
+fn main() {
+ let n = usize::MAX as u64;
+ assert_eq!((0..).by_ref().position(|i| i >= n), Some(usize::MAX));
+ assert_eq!((0..).by_ref().position(|i| i > n), Some(0));
+ assert_eq!((0..=n + 1).by_ref().position(|_| false), None);
+}
diff --git a/tests/ui/iterators/iter-range.rs b/tests/ui/iterators/iter-range.rs
new file mode 100644
index 000000000..993d93790
--- /dev/null
+++ b/tests/ui/iterators/iter-range.rs
@@ -0,0 +1,14 @@
+// run-pass
+
+
+fn range_<F>(a: isize, b: isize, mut it: F) where F: FnMut(isize) {
+ assert!((a < b));
+ let mut i: isize = a;
+ while i < b { it(i); i += 1; }
+}
+
+pub fn main() {
+ let mut sum: isize = 0;
+ range_(0, 100, |x| sum += x );
+ println!("{}", sum);
+}
diff --git a/tests/ui/iterators/iter-step-overflow-debug.rs b/tests/ui/iterators/iter-step-overflow-debug.rs
new file mode 100644
index 000000000..6aa349ebe
--- /dev/null
+++ b/tests/ui/iterators/iter-step-overflow-debug.rs
@@ -0,0 +1,21 @@
+// run-pass
+// needs-unwind
+// compile-flags: -C debug_assertions=yes
+
+use std::panic;
+
+fn main() {
+ let r = panic::catch_unwind(|| {
+ let mut it = u8::MAX..;
+ it.next().unwrap(); // 255
+ it.next().unwrap();
+ });
+ assert!(r.is_err());
+
+ let r = panic::catch_unwind(|| {
+ let mut it = i8::MAX..;
+ it.next().unwrap(); // 127
+ it.next().unwrap();
+ });
+ assert!(r.is_err());
+}
diff --git a/tests/ui/iterators/iter-step-overflow-ndebug.rs b/tests/ui/iterators/iter-step-overflow-ndebug.rs
new file mode 100644
index 000000000..33e708769
--- /dev/null
+++ b/tests/ui/iterators/iter-step-overflow-ndebug.rs
@@ -0,0 +1,12 @@
+// run-pass
+// compile-flags: -C debug_assertions=no
+
+fn main() {
+ let mut it = u8::MAX..;
+ assert_eq!(it.next().unwrap(), 255);
+ assert_eq!(it.next().unwrap(), u8::MIN);
+
+ let mut it = i8::MAX..;
+ assert_eq!(it.next().unwrap(), 127);
+ assert_eq!(it.next().unwrap(), i8::MIN);
+}
diff --git a/tests/ui/iterators/iter-sum-overflow-debug.rs b/tests/ui/iterators/iter-sum-overflow-debug.rs
new file mode 100644
index 000000000..24c764ff9
--- /dev/null
+++ b/tests/ui/iterators/iter-sum-overflow-debug.rs
@@ -0,0 +1,27 @@
+// run-pass
+// needs-unwind
+// compile-flags: -C debug_assertions=yes
+
+use std::panic;
+
+fn main() {
+ let r = panic::catch_unwind(|| {
+ [1, i32::MAX].iter().sum::<i32>();
+ });
+ assert!(r.is_err());
+
+ let r = panic::catch_unwind(|| {
+ [2, i32::MAX].iter().product::<i32>();
+ });
+ assert!(r.is_err());
+
+ let r = panic::catch_unwind(|| {
+ [1, i32::MAX].iter().cloned().sum::<i32>();
+ });
+ assert!(r.is_err());
+
+ let r = panic::catch_unwind(|| {
+ [2, i32::MAX].iter().cloned().product::<i32>();
+ });
+ assert!(r.is_err());
+}
diff --git a/tests/ui/iterators/iter-sum-overflow-ndebug.rs b/tests/ui/iterators/iter-sum-overflow-ndebug.rs
new file mode 100644
index 000000000..69f4744cc
--- /dev/null
+++ b/tests/ui/iterators/iter-sum-overflow-ndebug.rs
@@ -0,0 +1,14 @@
+// run-pass
+// compile-flags: -C debug_assertions=no
+
+fn main() {
+ assert_eq!([1i32, i32::MAX].iter().sum::<i32>(),
+ 1i32.wrapping_add(i32::MAX));
+ assert_eq!([2i32, i32::MAX].iter().product::<i32>(),
+ 2i32.wrapping_mul(i32::MAX));
+
+ assert_eq!([1i32, i32::MAX].iter().cloned().sum::<i32>(),
+ 1i32.wrapping_add(i32::MAX));
+ assert_eq!([2i32, i32::MAX].iter().cloned().product::<i32>(),
+ 2i32.wrapping_mul(i32::MAX));
+}
diff --git a/tests/ui/iterators/iter-sum-overflow-overflow-checks.rs b/tests/ui/iterators/iter-sum-overflow-overflow-checks.rs
new file mode 100644
index 000000000..be45c075d
--- /dev/null
+++ b/tests/ui/iterators/iter-sum-overflow-overflow-checks.rs
@@ -0,0 +1,27 @@
+// run-pass
+// needs-unwind
+// compile-flags: -C overflow-checks
+
+use std::panic;
+
+fn main() {
+ let r = panic::catch_unwind(|| {
+ [1, i32::MAX].iter().sum::<i32>();
+ });
+ assert!(r.is_err());
+
+ let r = panic::catch_unwind(|| {
+ [2, i32::MAX].iter().product::<i32>();
+ });
+ assert!(r.is_err());
+
+ let r = panic::catch_unwind(|| {
+ [1, i32::MAX].iter().cloned().sum::<i32>();
+ });
+ assert!(r.is_err());
+
+ let r = panic::catch_unwind(|| {
+ [2, i32::MAX].iter().cloned().product::<i32>();
+ });
+ assert!(r.is_err());
+}
diff --git a/tests/ui/iterators/ranges.rs b/tests/ui/iterators/ranges.rs
new file mode 100644
index 000000000..925d2d61a
--- /dev/null
+++ b/tests/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/tests/ui/iterators/ranges.stderr b/tests/ui/iterators/ranges.stderr
new file mode 100644
index 000000000..b9fbcd530
--- /dev/null
+++ b/tests/ui/iterators/ranges.stderr
@@ -0,0 +1,23 @@
+error[E0277]: `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 `Iterator` is not implemented for `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 for `RangeTo<{integer}>` to implement `IntoIterator`
+
+error[E0277]: `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 `Iterator` is not implemented for `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 for `RangeToInclusive<{integer}>` to implement `IntoIterator`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/iterators/rsplit-clone.rs b/tests/ui/iterators/rsplit-clone.rs
new file mode 100644
index 000000000..911da7429
--- /dev/null
+++ b/tests/ui/iterators/rsplit-clone.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+// RSplit<T, P> previously required T: Clone in order to be Clone
+
+struct NotClone;
+
+fn main() {
+ let elements = [NotClone, NotClone, NotClone];
+ let rsplit = elements.rsplit(|_| false);
+ rsplit.clone();
+}
diff --git a/tests/ui/iterators/skip-count-overflow.rs b/tests/ui/iterators/skip-count-overflow.rs
new file mode 100644
index 000000000..64dee3e3c
--- /dev/null
+++ b/tests/ui/iterators/skip-count-overflow.rs
@@ -0,0 +1,8 @@
+// run-pass
+// only-32bit too impatient for 2⁶⁴ items
+// compile-flags: -C overflow-checks -C opt-level=3
+
+fn main() {
+ let i = (0..usize::MAX).chain(0..10).skip(usize::MAX);
+ assert_eq!(i.count(), 10);
+}
diff --git a/tests/ui/iterators/string.rs b/tests/ui/iterators/string.rs
new file mode 100644
index 000000000..ad58a463e
--- /dev/null
+++ b/tests/ui/iterators/string.rs
@@ -0,0 +1,6 @@
+fn main() {
+ for _ in "".to_owned() {}
+ //~^ ERROR `String` is not an iterator
+ for _ in "" {}
+ //~^ ERROR `&str` is not an iterator
+}
diff --git a/tests/ui/iterators/string.stderr b/tests/ui/iterators/string.stderr
new file mode 100644
index 000000000..ddfe0169b
--- /dev/null
+++ b/tests/ui/iterators/string.stderr
@@ -0,0 +1,21 @@
+error[E0277]: `String` is not an iterator
+ --> $DIR/string.rs:2:14
+ |
+LL | for _ in "".to_owned() {}
+ | ^^^^^^^^^^^^^ `String` is not an iterator; try calling `.chars()` or `.bytes()`
+ |
+ = help: the trait `Iterator` is not implemented for `String`
+ = note: required for `String` to implement `IntoIterator`
+
+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 `Iterator` is not implemented for `&str`
+ = note: required for `&str` to implement `IntoIterator`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/iterators/vec-on-unimplemented.rs b/tests/ui/iterators/vec-on-unimplemented.rs
new file mode 100644
index 000000000..42b5d36bf
--- /dev/null
+++ b/tests/ui/iterators/vec-on-unimplemented.rs
@@ -0,0 +1,4 @@
+fn main() {
+ vec![true, false].map(|v| !v).collect::<Vec<_>>();
+ //~^ ERROR `Vec<bool>` is not an iterator
+}
diff --git a/tests/ui/iterators/vec-on-unimplemented.stderr b/tests/ui/iterators/vec-on-unimplemented.stderr
new file mode 100644
index 000000000..a7d9c481a
--- /dev/null
+++ b/tests/ui/iterators/vec-on-unimplemented.stderr
@@ -0,0 +1,18 @@
+error[E0599]: `Vec<bool>` is not an iterator
+ --> $DIR/vec-on-unimplemented.rs:2:23
+ |
+LL | vec![true, false].map(|v| !v).collect::<Vec<_>>();
+ | ^^^ `Vec<bool>` is not an iterator; try calling `.into_iter()` or `.iter()`
+ --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ |
+ = note: doesn't satisfy `Vec<bool>: Iterator`
+ |
+ = note: the following trait bounds were not satisfied:
+ `Vec<bool>: Iterator`
+ which is required by `&mut Vec<bool>: Iterator`
+ `[bool]: Iterator`
+ which is required by `&mut [bool]: Iterator`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.