diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index b5dd6cf16eefa..6ceaaf6997e26 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -99,7 +99,7 @@ declare_lint! { /// To fix this, remove the `use<'a>`, since the lifetime is already captured /// since it is in scope. pub IMPL_TRAIT_REDUNDANT_CAPTURES, - Warn, + Allow, "redundant precise-capturing `use<...>` syntax on an `impl Trait`", } diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 84679827ba1c0..2e654d3d1ff1e 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1204,22 +1204,16 @@ fn test_from_iter_specialization_with_iterator_adapters() { #[test] fn test_in_place_specialization_step_up_down() { fn assert_in_place_trait(_: &T) {} - let src = vec![[0u8; 4]; 256]; - let srcptr = src.as_ptr(); - let src_cap = src.capacity(); - let iter = src.into_iter().flatten(); - assert_in_place_trait(&iter); - let sink = iter.collect::>(); - let sinkptr = sink.as_ptr(); - assert_eq!(srcptr as *const u8, sinkptr); - assert_eq!(src_cap * 4, sink.capacity()); - let iter = sink.into_iter().array_chunks::<4>(); + let src = vec![0u8; 1024]; + let srcptr = src.as_ptr(); + let src_bytes = src.capacity(); + let iter = src.into_iter().array_chunks::<4>(); assert_in_place_trait(&iter); let sink = iter.collect::>(); let sinkptr = sink.as_ptr(); - assert_eq!(srcptr, sinkptr); - assert_eq!(src_cap, sink.capacity()); + assert_eq!(srcptr.addr(), sinkptr.addr()); + assert_eq!(src_bytes, sink.capacity() * 4); let mut src: Vec = Vec::with_capacity(17); let src_bytes = src.capacity(); @@ -1236,13 +1230,6 @@ fn test_in_place_specialization_step_up_down() { let sink: Vec<[u8; 2]> = iter.collect(); assert_eq!(sink.len(), 8); assert!(sink.capacity() <= 25); - - let src = vec![[0u8; 4]; 256]; - let srcptr = src.as_ptr(); - let iter = src.into_iter().flat_map(|a| a.into_iter().map(|b| b.wrapping_add(1))); - assert_in_place_trait(&iter); - let sink = iter.collect::>(); - assert_eq!(srcptr as *const u8, sink.as_ptr()); } #[test] @@ -1350,6 +1337,20 @@ fn test_collect_after_iterator_clone() { assert_eq!(v, [1, 1, 1, 1, 1]); assert!(v.len() <= v.capacity()); } + +// regression test for #135103, similar to the one above Flatten/FlatMap had an unsound InPlaceIterable +// implementation. +#[test] +fn test_flatten_clone() { + const S: String = String::new(); + + let v = vec![[S, "Hello World!".into()], [S, S]]; + let mut i = v.into_iter().flatten(); + let _ = i.next(); + let result: Vec = i.clone().collect(); + assert_eq!(result, ["Hello World!", "", ""]); +} + #[test] fn test_cow_from() { let borrowed: &[_] = &["borrowed", "(slice)"]; diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index 0023b46031f12..9b9353b800a98 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -1,7 +1,7 @@ use crate::iter::adapters::SourceIter; use crate::iter::{ - Cloned, Copied, Empty, Filter, FilterMap, Fuse, FusedIterator, InPlaceIterable, Map, Once, - OnceWith, TrustedFused, TrustedLen, + Cloned, Copied, Empty, Filter, FilterMap, Fuse, FusedIterator, Map, Once, OnceWith, + TrustedFused, TrustedLen, }; use crate::num::NonZero; use crate::ops::{ControlFlow, Try}; @@ -157,21 +157,6 @@ where { } -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl InPlaceIterable for FlatMap -where - I: InPlaceIterable, - U: BoundedSize + IntoIterator, -{ - const EXPAND_BY: Option> = const { - match (I::EXPAND_BY, U::UPPER_BOUND) { - (Some(m), Some(n)) => m.checked_mul(n), - _ => None, - } - }; - const MERGE_BY: Option> = I::MERGE_BY; -} - #[unstable(issue = "none", feature = "inplace_iteration")] unsafe impl SourceIter for FlatMap where @@ -386,21 +371,6 @@ where { } -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl InPlaceIterable for Flatten -where - I: InPlaceIterable + Iterator, - ::Item: IntoIterator + BoundedSize, -{ - const EXPAND_BY: Option> = const { - match (I::EXPAND_BY, I::Item::UPPER_BOUND) { - (Some(m), Some(n)) => m.checked_mul(n), - _ => None, - } - }; - const MERGE_BY: Option> = I::MERGE_BY; -} - #[unstable(issue = "none", feature = "inplace_iteration")] unsafe impl SourceIter for Flatten where diff --git a/src/llvm-project b/src/llvm-project index 59512b0027382..7e8c93c87c611 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 59512b00273829823da74050d373b8d46dbca558 +Subproject commit 7e8c93c87c611f21d9bd95100563392f4c18bfe7 diff --git a/tests/ui/impl-trait/precise-capturing/redundant.rs b/tests/ui/impl-trait/precise-capturing/redundant.rs index 075d7c70ac653..32dc09273175d 100644 --- a/tests/ui/impl-trait/precise-capturing/redundant.rs +++ b/tests/ui/impl-trait/precise-capturing/redundant.rs @@ -1,24 +1,24 @@ //@ edition: 2024 -//@ check-pass #![feature(precise_capturing_in_traits)] +#![deny(impl_trait_redundant_captures)] fn hello<'a>() -> impl Sized + use<'a> {} -//~^ WARN all possible in-scope parameters are already captured +//~^ ERROR all possible in-scope parameters are already captured struct Inherent; impl Inherent { fn inherent(&self) -> impl Sized + use<'_> {} - //~^ WARN all possible in-scope parameters are already captured + //~^ ERROR all possible in-scope parameters are already captured } trait Test<'a> { fn in_trait() -> impl Sized + use<'a, Self>; - //~^ WARN all possible in-scope parameters are already captured + //~^ ERROR all possible in-scope parameters are already captured } impl<'a> Test<'a> for () { fn in_trait() -> impl Sized + use<'a> {} - //~^ WARN all possible in-scope parameters are already captured + //~^ ERROR all possible in-scope parameters are already captured } fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/redundant.stderr b/tests/ui/impl-trait/precise-capturing/redundant.stderr index 274d9d2375f7d..5c8b35c228585 100644 --- a/tests/ui/impl-trait/precise-capturing/redundant.stderr +++ b/tests/ui/impl-trait/precise-capturing/redundant.stderr @@ -1,4 +1,4 @@ -warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant +error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant --> $DIR/redundant.rs:6:19 | LL | fn hello<'a>() -> impl Sized + use<'a> {} @@ -6,9 +6,13 @@ LL | fn hello<'a>() -> impl Sized + use<'a> {} | | | help: remove the `use<...>` syntax | - = note: `#[warn(impl_trait_redundant_captures)]` on by default +note: the lint level is defined here + --> $DIR/redundant.rs:4:9 + | +LL | #![deny(impl_trait_redundant_captures)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant +error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant --> $DIR/redundant.rs:11:27 | LL | fn inherent(&self) -> impl Sized + use<'_> {} @@ -16,7 +20,7 @@ LL | fn inherent(&self) -> impl Sized + use<'_> {} | | | help: remove the `use<...>` syntax -warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant +error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant --> $DIR/redundant.rs:16:22 | LL | fn in_trait() -> impl Sized + use<'a, Self>; @@ -24,7 +28,7 @@ LL | fn in_trait() -> impl Sized + use<'a, Self>; | | | help: remove the `use<...>` syntax -warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant +error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant --> $DIR/redundant.rs:20:22 | LL | fn in_trait() -> impl Sized + use<'a> {} @@ -32,5 +36,5 @@ LL | fn in_trait() -> impl Sized + use<'a> {} | | | help: remove the `use<...>` syntax -warning: 4 warnings emitted +error: aborting due to 4 previous errors