summaryrefslogtreecommitdiffstats
path: root/src/test/ui/iterators
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/iterators
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/iterators')
-rw-r--r--src/test/ui/iterators/array-of-ranges.rs16
-rw-r--r--src/test/ui/iterators/array.rs8
-rw-r--r--src/test/ui/iterators/bound.rs4
-rw-r--r--src/test/ui/iterators/bound.stderr17
-rw-r--r--src/test/ui/iterators/collect-into-array.rs7
-rw-r--r--src/test/ui/iterators/collect-into-array.stderr16
-rw-r--r--src/test/ui/iterators/collect-into-slice.rs15
-rw-r--r--src/test/ui/iterators/collect-into-slice.stderr26
-rw-r--r--src/test/ui/iterators/integral.rs26
-rw-r--r--src/test/ui/iterators/integral.stderr122
-rw-r--r--src/test/ui/iterators/into-iter-on-arrays-2018.rs46
-rw-r--r--src/test/ui/iterators/into-iter-on-arrays-2018.stderr65
-rw-r--r--src/test/ui/iterators/into-iter-on-arrays-2021.rs32
-rw-r--r--src/test/ui/iterators/into-iter-on-arrays-lint.fixed63
-rw-r--r--src/test/ui/iterators/into-iter-on-arrays-lint.rs63
-rw-r--r--src/test/ui/iterators/into-iter-on-arrays-lint.stderr143
-rw-r--r--src/test/ui/iterators/into-iterator-type-inference-shift.rs36
-rw-r--r--src/test/ui/iterators/issue-28098.rs27
-rw-r--r--src/test/ui/iterators/issue-28098.stderr77
-rw-r--r--src/test/ui/iterators/issue-58952-filter-type-length.rs32
-rw-r--r--src/test/ui/iterators/iter-cloned-type-inference.rs16
-rw-r--r--src/test/ui/iterators/iter-count-overflow-debug.rs16
-rw-r--r--src/test/ui/iterators/iter-count-overflow-ndebug.rs8
-rw-r--r--src/test/ui/iterators/iter-map-fold-type-length.rs38
-rw-r--r--src/test/ui/iterators/iter-position-overflow-debug.rs22
-rw-r--r--src/test/ui/iterators/iter-position-overflow-ndebug.rs10
-rw-r--r--src/test/ui/iterators/iter-range.rs14
-rw-r--r--src/test/ui/iterators/iter-step-overflow-debug.rs22
-rw-r--r--src/test/ui/iterators/iter-step-overflow-ndebug.rs12
-rw-r--r--src/test/ui/iterators/iter-sum-overflow-debug.rs28
-rw-r--r--src/test/ui/iterators/iter-sum-overflow-ndebug.rs14
-rw-r--r--src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs28
-rw-r--r--src/test/ui/iterators/ranges.rs9
-rw-r--r--src/test/ui/iterators/ranges.stderr23
-rw-r--r--src/test/ui/iterators/rsplit-clone.rs11
-rw-r--r--src/test/ui/iterators/skip-count-overflow.rs8
-rw-r--r--src/test/ui/iterators/string.rs6
-rw-r--r--src/test/ui/iterators/string.stderr21
-rw-r--r--src/test/ui/iterators/vec-on-unimplemented.rs4
-rw-r--r--src/test/ui/iterators/vec-on-unimplemented.stderr20
40 files changed, 1171 insertions, 0 deletions
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 000000000..037540a3e
--- /dev/null
+++ b/src/test/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/src/test/ui/iterators/array.rs b/src/test/ui/iterators/array.rs
new file mode 100644
index 000000000..5985c74e1
--- /dev/null
+++ b/src/test/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/src/test/ui/iterators/bound.rs b/src/test/ui/iterators/bound.rs
new file mode 100644
index 000000000..bdd99ef8d
--- /dev/null
+++ b/src/test/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/src/test/ui/iterators/bound.stderr b/src/test/ui/iterators/bound.stderr
new file mode 100644
index 000000000..cc7ded498
--- /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>);
+ | ^^^^^ `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/src/test/ui/iterators/collect-into-array.rs b/src/test/ui/iterators/collect-into-array.rs
new file mode 100644
index 000000000..a1144c8cb
--- /dev/null
+++ b/src/test/ui/iterators/collect-into-array.rs
@@ -0,0 +1,7 @@
+fn main() {
+ //~^ NOTE required by a bound in this
+ 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/src/test/ui/iterators/collect-into-array.stderr b/src/test/ui/iterators/collect-into-array.stderr
new file mode 100644
index 000000000..7be53a487
--- /dev/null
+++ b/src/test/ui/iterators/collect-into-array.stderr
@@ -0,0 +1,16 @@
+error[E0277]: an array of type `[u32; 10]` cannot be built directly from an iterator
+ --> $DIR/collect-into-array.rs:3: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
+ |
+LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/iterators/collect-into-slice.rs b/src/test/ui/iterators/collect-into-slice.rs
new file mode 100644
index 000000000..aafa6bc8b
--- /dev/null
+++ b/src/test/ui/iterators/collect-into-slice.rs
@@ -0,0 +1,15 @@
+fn process_slice(data: &[i32]) {
+ //~^ NOTE required by a bound in this
+ 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 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 all local variables must have a statically known size
+ //~| NOTE doesn't have a size known at compile-time
+ process_slice(&some_generated_vec);
+}
diff --git a/src/test/ui/iterators/collect-into-slice.stderr b/src/test/ui/iterators/collect-into-slice.stderr
new file mode 100644
index 000000000..4842e65fe
--- /dev/null
+++ b/src/test/ui/iterators/collect-into-slice.stderr
@@ -0,0 +1,26 @@
+error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
+ --> $DIR/collect-into-slice.rs:7: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]: a slice of type `[i32]` cannot be built since `[i32]` has no definite size
+ --> $DIR/collect-into-slice.rs:7: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
+ |
+LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect`
+
+error: aborting due to 2 previous errors
+
+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 000000000..7537c7904
--- /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 000000000..5e2744bab
--- /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 `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 because of the requirements on the impl of `IntoIterator` for `{integer}`
+
+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 because of the requirements on the impl of `IntoIterator` for `u8`
+
+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 because of the requirements on the impl of `IntoIterator` for `i8`
+
+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 because of the requirements on the impl of `IntoIterator` for `u16`
+
+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 because of the requirements on the impl of `IntoIterator` for `i16`
+
+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 because of the requirements on the impl of `IntoIterator` for `u32`
+
+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 because of the requirements on the impl of `IntoIterator` for `i32`
+
+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 because of the requirements on the impl of `IntoIterator` for `u64`
+
+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 because of the requirements on the impl of `IntoIterator` for `i64`
+
+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 because of the requirements on the impl of `IntoIterator` for `usize`
+
+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 because of the requirements on the impl of `IntoIterator` for `isize`
+
+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: required because of the requirements on the impl of `IntoIterator` for `{float}`
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/iterators/into-iter-on-arrays-2018.rs b/src/test/ui/iterators/into-iter-on-arrays-2018.rs
new file mode 100644
index 000000000..60995170a
--- /dev/null
+++ b/src/test/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/src/test/ui/iterators/into-iter-on-arrays-2018.stderr b/src/test/ui/iterators/into-iter-on-arrays-2018.stderr
new file mode 100644
index 000000000..9b3125058
--- /dev/null
+++ b/src/test/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();
+ | ^^^^^^^^^
+ |
+ = note: `#[warn(array_into_iter)]` on by default
+ = 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 | 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/src/test/ui/iterators/into-iter-on-arrays-2021.rs b/src/test/ui/iterators/into-iter-on-arrays-2021.rs
new file mode 100644
index 000000000..158317efe
--- /dev/null
+++ b/src/test/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/src/test/ui/iterators/into-iter-on-arrays-lint.fixed b/src/test/ui/iterators/into-iter-on-arrays-lint.fixed
new file mode 100644
index 000000000..6e02a7024
--- /dev/null
+++ b/src/test/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/src/test/ui/iterators/into-iter-on-arrays-lint.rs b/src/test/ui/iterators/into-iter-on-arrays-lint.rs
new file mode 100644
index 000000000..582d5cadd
--- /dev/null
+++ b/src/test/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/src/test/ui/iterators/into-iter-on-arrays-lint.stderr b/src/test/ui/iterators/into-iter-on-arrays-lint.stderr
new file mode 100644
index 000000000..e32d35d86
--- /dev/null
+++ b/src/test/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();
+ | ^^^^^^^^^
+ |
+ = note: `#[warn(array_into_iter)]` on by default
+ = 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 | 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/src/test/ui/iterators/into-iterator-type-inference-shift.rs b/src/test/ui/iterators/into-iterator-type-inference-shift.rs
new file mode 100644
index 000000000..9151172fd
--- /dev/null
+++ b/src/test/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/src/test/ui/iterators/issue-28098.rs b/src/test/ui/iterators/issue-28098.rs
new file mode 100644
index 000000000..62a90d90d
--- /dev/null
+++ b/src/test/ui/iterators/issue-28098.rs
@@ -0,0 +1,27 @@
+fn main() {
+ let _ = Iterator::next(&mut ());
+ //~^ 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
+
+ other()
+}
+
+pub fn other() {
+ // check errors are still reported globally
+
+ let _ = Iterator::next(&mut ());
+ //~^ ERROR `()` is not an iterator
+ //~| ERROR `()` is not an iterator
+
+ let _ = Iterator::next(&mut ());
+ //~^ ERROR `()` is not an iterator
+
+ for _ in false {}
+ //~^ ERROR `bool` is not an iterator
+}
diff --git a/src/test/ui/iterators/issue-28098.stderr b/src/test/ui/iterators/issue-28098.stderr
new file mode 100644
index 000000000..3beb99292
--- /dev/null
+++ b/src/test/ui/iterators/issue-28098.stderr
@@ -0,0 +1,77 @@
+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]: `bool` is not an iterator
+ --> $DIR/issue-28098.rs:6:14
+ |
+LL | for _ in false {}
+ | ^^^^^ `bool` is not an iterator
+ |
+ = help: the trait `Iterator` is not implemented for `bool`
+ = note: required because of the requirements on the impl of `IntoIterator` for `bool`
+
+error[E0277]: `()` is not an iterator
+ --> $DIR/issue-28098.rs:9: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]: `()` is not an iterator
+ --> $DIR/issue-28098.rs:18: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:22: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]: `bool` is not an iterator
+ --> $DIR/issue-28098.rs:25:14
+ |
+LL | for _ in false {}
+ | ^^^^^ `bool` is not an iterator
+ |
+ = help: the trait `Iterator` is not implemented for `bool`
+ = note: required because of the requirements on the impl of `IntoIterator` for `bool`
+
+error[E0277]: `()` is not an iterator
+ --> $DIR/issue-28098.rs:18:13
+ |
+LL | let _ = Iterator::next(&mut ());
+ | ^^^^^^^^^^^^^^ `()` is not an iterator
+ |
+ = help: the trait `Iterator` is not implemented for `()`
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/iterators/issue-58952-filter-type-length.rs b/src/test/ui/iterators/issue-58952-filter-type-length.rs
new file mode 100644
index 000000000..ffbe89a14
--- /dev/null
+++ b/src/test/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 accidentially 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/src/test/ui/iterators/iter-cloned-type-inference.rs b/src/test/ui/iterators/iter-cloned-type-inference.rs
new file mode 100644
index 000000000..898e33719
--- /dev/null
+++ b/src/test/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/src/test/ui/iterators/iter-count-overflow-debug.rs b/src/test/ui/iterators/iter-count-overflow-debug.rs
new file mode 100644
index 000000000..15f25f1ca
--- /dev/null
+++ b/src/test/ui/iterators/iter-count-overflow-debug.rs
@@ -0,0 +1,16 @@
+// run-pass
+// only-32bit too impatient for 2⁶⁴ items
+// needs-unwind
+// ignore-wasm32-bare compiled with panic=abort by default
+// 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/src/test/ui/iterators/iter-count-overflow-ndebug.rs b/src/test/ui/iterators/iter-count-overflow-ndebug.rs
new file mode 100644
index 000000000..dcaaff671
--- /dev/null
+++ b/src/test/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/src/test/ui/iterators/iter-map-fold-type-length.rs b/src/test/ui/iterators/iter-map-fold-type-length.rs
new file mode 100644
index 000000000..8ce4fcd87
--- /dev/null
+++ b/src/test/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/src/test/ui/iterators/iter-position-overflow-debug.rs b/src/test/ui/iterators/iter-position-overflow-debug.rs
new file mode 100644
index 000000000..65124c282
--- /dev/null
+++ b/src/test/ui/iterators/iter-position-overflow-debug.rs
@@ -0,0 +1,22 @@
+// run-pass
+// only-32bit too impatient for 2⁶⁴ items
+// needs-unwind
+// ignore-wasm32-bare compiled with panic=abort by default
+// 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/src/test/ui/iterators/iter-position-overflow-ndebug.rs b/src/test/ui/iterators/iter-position-overflow-ndebug.rs
new file mode 100644
index 000000000..e610c3559
--- /dev/null
+++ b/src/test/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/src/test/ui/iterators/iter-range.rs b/src/test/ui/iterators/iter-range.rs
new file mode 100644
index 000000000..993d93790
--- /dev/null
+++ b/src/test/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/src/test/ui/iterators/iter-step-overflow-debug.rs b/src/test/ui/iterators/iter-step-overflow-debug.rs
new file mode 100644
index 000000000..e16f984de
--- /dev/null
+++ b/src/test/ui/iterators/iter-step-overflow-debug.rs
@@ -0,0 +1,22 @@
+// run-pass
+// needs-unwind
+// ignore-wasm32-bare compiled with panic=abort by default
+// 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/src/test/ui/iterators/iter-step-overflow-ndebug.rs b/src/test/ui/iterators/iter-step-overflow-ndebug.rs
new file mode 100644
index 000000000..33e708769
--- /dev/null
+++ b/src/test/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/src/test/ui/iterators/iter-sum-overflow-debug.rs b/src/test/ui/iterators/iter-sum-overflow-debug.rs
new file mode 100644
index 000000000..d8ce43848
--- /dev/null
+++ b/src/test/ui/iterators/iter-sum-overflow-debug.rs
@@ -0,0 +1,28 @@
+// run-pass
+// needs-unwind
+// ignore-wasm32-bare compiled with panic=abort by default
+// 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/src/test/ui/iterators/iter-sum-overflow-ndebug.rs b/src/test/ui/iterators/iter-sum-overflow-ndebug.rs
new file mode 100644
index 000000000..69f4744cc
--- /dev/null
+++ b/src/test/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/src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs b/src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs
new file mode 100644
index 000000000..bc8dcbdbb
--- /dev/null
+++ b/src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs
@@ -0,0 +1,28 @@
+// run-pass
+// needs-unwind
+// ignore-wasm32-bare compiled with panic=abort by default
+// 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/src/test/ui/iterators/ranges.rs b/src/test/ui/iterators/ranges.rs
new file mode 100644
index 000000000..925d2d61a
--- /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 000000000..440a8960a
--- /dev/null
+++ b/src/test/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 because of the requirements on the impl of `IntoIterator` for `RangeTo<{integer}>`
+
+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 because of the requirements on the impl of `IntoIterator` for `RangeToInclusive<{integer}>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/iterators/rsplit-clone.rs b/src/test/ui/iterators/rsplit-clone.rs
new file mode 100644
index 000000000..911da7429
--- /dev/null
+++ b/src/test/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/src/test/ui/iterators/skip-count-overflow.rs b/src/test/ui/iterators/skip-count-overflow.rs
new file mode 100644
index 000000000..64dee3e3c
--- /dev/null
+++ b/src/test/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/src/test/ui/iterators/string.rs b/src/test/ui/iterators/string.rs
new file mode 100644
index 000000000..ad58a463e
--- /dev/null
+++ b/src/test/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/src/test/ui/iterators/string.stderr b/src/test/ui/iterators/string.stderr
new file mode 100644
index 000000000..d9c40fe1b
--- /dev/null
+++ b/src/test/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 because of the requirements on the impl of `IntoIterator` for `String`
+
+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 because of the requirements on the impl of `IntoIterator` for `&str`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/iterators/vec-on-unimplemented.rs b/src/test/ui/iterators/vec-on-unimplemented.rs
new file mode 100644
index 000000000..42b5d36bf
--- /dev/null
+++ b/src/test/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/src/test/ui/iterators/vec-on-unimplemented.stderr b/src/test/ui/iterators/vec-on-unimplemented.stderr
new file mode 100644
index 000000000..afcce5c30
--- /dev/null
+++ b/src/test/ui/iterators/vec-on-unimplemented.stderr
@@ -0,0 +1,20 @@
+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
+ |
+LL | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
+ | ------------------------------------------------------------------------------------------------ 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`.