From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- src/test/ui/iterators/array-of-ranges.rs | 16 +++ src/test/ui/iterators/array.rs | 8 ++ src/test/ui/iterators/bound.rs | 4 + src/test/ui/iterators/bound.stderr | 17 +++ src/test/ui/iterators/collect-into-array.rs | 7 + src/test/ui/iterators/collect-into-array.stderr | 16 +++ src/test/ui/iterators/collect-into-slice.rs | 15 +++ src/test/ui/iterators/collect-into-slice.stderr | 26 ++++ src/test/ui/iterators/integral.rs | 26 ++++ src/test/ui/iterators/integral.stderr | 122 ++++++++++++++++++ src/test/ui/iterators/into-iter-on-arrays-2018.rs | 46 +++++++ .../ui/iterators/into-iter-on-arrays-2018.stderr | 65 ++++++++++ src/test/ui/iterators/into-iter-on-arrays-2021.rs | 32 +++++ .../ui/iterators/into-iter-on-arrays-lint.fixed | 63 +++++++++ src/test/ui/iterators/into-iter-on-arrays-lint.rs | 63 +++++++++ .../ui/iterators/into-iter-on-arrays-lint.stderr | 143 +++++++++++++++++++++ .../into-iterator-type-inference-shift.rs | 36 ++++++ src/test/ui/iterators/issue-28098.rs | 27 ++++ src/test/ui/iterators/issue-28098.stderr | 77 +++++++++++ .../ui/iterators/issue-58952-filter-type-length.rs | 32 +++++ .../ui/iterators/iter-cloned-type-inference.rs | 16 +++ src/test/ui/iterators/iter-count-overflow-debug.rs | 16 +++ .../ui/iterators/iter-count-overflow-ndebug.rs | 8 ++ src/test/ui/iterators/iter-map-fold-type-length.rs | 38 ++++++ .../ui/iterators/iter-position-overflow-debug.rs | 22 ++++ .../ui/iterators/iter-position-overflow-ndebug.rs | 10 ++ src/test/ui/iterators/iter-range.rs | 14 ++ src/test/ui/iterators/iter-step-overflow-debug.rs | 22 ++++ src/test/ui/iterators/iter-step-overflow-ndebug.rs | 12 ++ src/test/ui/iterators/iter-sum-overflow-debug.rs | 28 ++++ src/test/ui/iterators/iter-sum-overflow-ndebug.rs | 14 ++ .../iterators/iter-sum-overflow-overflow-checks.rs | 28 ++++ src/test/ui/iterators/ranges.rs | 9 ++ src/test/ui/iterators/ranges.stderr | 23 ++++ src/test/ui/iterators/rsplit-clone.rs | 11 ++ src/test/ui/iterators/skip-count-overflow.rs | 8 ++ src/test/ui/iterators/string.rs | 6 + src/test/ui/iterators/string.stderr | 21 +++ src/test/ui/iterators/vec-on-unimplemented.rs | 4 + src/test/ui/iterators/vec-on-unimplemented.stderr | 20 +++ 40 files changed, 1171 insertions(+) create mode 100644 src/test/ui/iterators/array-of-ranges.rs create mode 100644 src/test/ui/iterators/array.rs create mode 100644 src/test/ui/iterators/bound.rs create mode 100644 src/test/ui/iterators/bound.stderr create mode 100644 src/test/ui/iterators/collect-into-array.rs create mode 100644 src/test/ui/iterators/collect-into-array.stderr create mode 100644 src/test/ui/iterators/collect-into-slice.rs create mode 100644 src/test/ui/iterators/collect-into-slice.stderr create mode 100644 src/test/ui/iterators/integral.rs create mode 100644 src/test/ui/iterators/integral.stderr create mode 100644 src/test/ui/iterators/into-iter-on-arrays-2018.rs create mode 100644 src/test/ui/iterators/into-iter-on-arrays-2018.stderr create mode 100644 src/test/ui/iterators/into-iter-on-arrays-2021.rs create mode 100644 src/test/ui/iterators/into-iter-on-arrays-lint.fixed create mode 100644 src/test/ui/iterators/into-iter-on-arrays-lint.rs create mode 100644 src/test/ui/iterators/into-iter-on-arrays-lint.stderr create mode 100644 src/test/ui/iterators/into-iterator-type-inference-shift.rs create mode 100644 src/test/ui/iterators/issue-28098.rs create mode 100644 src/test/ui/iterators/issue-28098.stderr create mode 100644 src/test/ui/iterators/issue-58952-filter-type-length.rs create mode 100644 src/test/ui/iterators/iter-cloned-type-inference.rs create mode 100644 src/test/ui/iterators/iter-count-overflow-debug.rs create mode 100644 src/test/ui/iterators/iter-count-overflow-ndebug.rs create mode 100644 src/test/ui/iterators/iter-map-fold-type-length.rs create mode 100644 src/test/ui/iterators/iter-position-overflow-debug.rs create mode 100644 src/test/ui/iterators/iter-position-overflow-ndebug.rs create mode 100644 src/test/ui/iterators/iter-range.rs create mode 100644 src/test/ui/iterators/iter-step-overflow-debug.rs create mode 100644 src/test/ui/iterators/iter-step-overflow-ndebug.rs create mode 100644 src/test/ui/iterators/iter-sum-overflow-debug.rs create mode 100644 src/test/ui/iterators/iter-sum-overflow-ndebug.rs create mode 100644 src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs create mode 100644 src/test/ui/iterators/ranges.rs create mode 100644 src/test/ui/iterators/ranges.stderr create mode 100644 src/test/ui/iterators/rsplit-clone.rs create mode 100644 src/test/ui/iterators/skip-count-overflow.rs create mode 100644 src/test/ui/iterators/string.rs create mode 100644 src/test/ui/iterators/string.stderr create mode 100644 src/test/ui/iterators/vec-on-unimplemented.rs create mode 100644 src/test/ui/iterators/vec-on-unimplemented.stderr (limited to 'src/test/ui/iterators') 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); +struct T(S); +//~^ 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` 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); + | ^^^^^^^^ 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>(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>(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 = 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 +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 + +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 + +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 + +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 +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 = array.into_iter(); + let _: IntoIter = Box::new(array).into_iter(); + + // The `array_into_iter` lint doesn't cover other wrappers that deref to an array. + let _: IntoIter = Rc::new(array).into_iter(); + let _: IntoIter = Array(array).into_iter(); + + // You can always use the trait method explicitly as an array. + let _: IntoIter = 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 +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 +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 +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 +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 + +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 + +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 + +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 + +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 + +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 + +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 + +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 + +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 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::>(); +} 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); + +impl Iterator for Iter +where + I: Iterator +{ + type Item = I::Item; + + fn next(&mut self) -> Option { + 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_(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::(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + [2, i32::MAX].iter().product::(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + [1, i32::MAX].iter().cloned().sum::(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + [2, i32::MAX].iter().cloned().product::(); + }); + 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::(), + 1i32.wrapping_add(i32::MAX)); + assert_eq!([2i32, i32::MAX].iter().product::(), + 2i32.wrapping_mul(i32::MAX)); + + assert_eq!([1i32, i32::MAX].iter().cloned().sum::(), + 1i32.wrapping_add(i32::MAX)); + assert_eq!([2i32, i32::MAX].iter().cloned().product::(), + 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::(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + [2, i32::MAX].iter().product::(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + [1, i32::MAX].iter().cloned().sum::(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + [2, i32::MAX].iter().cloned().product::(); + }); + 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 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::>(); + //~^ ERROR `Vec` 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` is not an iterator + --> $DIR/vec-on-unimplemented.rs:2:23 + | +LL | vec![true, false].map(|v| !v).collect::>(); + | ^^^ `Vec` is not an iterator; try calling `.into_iter()` or `.iter()` + | + ::: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + | +LL | pub struct Vec { + | ------------------------------------------------------------------------------------------------ doesn't satisfy `Vec: Iterator` + | + = note: the following trait bounds were not satisfied: + `Vec: Iterator` + which is required by `&mut Vec: 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`. -- cgit v1.2.3