diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 9ec6f6ae1acd5..6fd021fc9fdf7 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1166,10 +1166,14 @@ fn test_from_iter_partially_drained_in_place_specialization() { #[test] fn test_from_iter_specialization_with_iterator_adapters() { fn assert_in_place_trait(_: &T) {} - let src: Vec = vec![0usize; 256]; + let owned: Vec = vec![0usize; 256]; + let refd: Vec<&usize> = owned.iter().collect(); + let src: Vec<&&usize> = refd.iter().collect(); let srcptr = src.as_ptr(); let iter = src .into_iter() + .copied() + .cloned() .enumerate() .map(|i| i.0 + i.1) .zip(std::iter::repeat(1usize)) @@ -1180,7 +1184,7 @@ fn test_from_iter_specialization_with_iterator_adapters() { assert_in_place_trait(&iter); let sink = iter.collect::, _>>().unwrap(); let sinkptr = sink.as_ptr(); - assert_eq!(srcptr, sinkptr as *const usize); + assert_eq!(srcptr as *const usize, sinkptr as *const usize); } #[test] diff --git a/library/core/src/iter/adapters/cloned.rs b/library/core/src/iter/adapters/cloned.rs index d3cceb8d4ad54..3de91267cf5d9 100644 --- a/library/core/src/iter/adapters/cloned.rs +++ b/library/core/src/iter/adapters/cloned.rs @@ -1,8 +1,9 @@ use crate::iter::adapters::{ - zip::try_get_unchecked, TrustedRandomAccess, TrustedRandomAccessNoCoerce, + zip::try_get_unchecked, SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce, }; -use crate::iter::{FusedIterator, TrustedLen, UncheckedIterator}; +use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen, UncheckedIterator}; use crate::ops::Try; +use core::num::NonZeroUsize; /// An iterator that clones the elements of an underlying iterator. /// @@ -167,3 +168,23 @@ impl Default for Cloned { Self::new(Default::default()) } } + +#[unstable(issue = "none", feature = "inplace_iteration")] +unsafe impl SourceIter for Cloned +where + I: SourceIter, +{ + type Source = I::Source; + + #[inline] + unsafe fn as_inner(&mut self) -> &mut I::Source { + // SAFETY: unsafe function forwarding to unsafe function with the same requirements + unsafe { SourceIter::as_inner(&mut self.it) } + } +} + +#[unstable(issue = "none", feature = "inplace_iteration")] +unsafe impl InPlaceIterable for Cloned { + const EXPAND_BY: Option = I::EXPAND_BY; + const MERGE_BY: Option = I::MERGE_BY; +} diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs index 7a2c9d839b7e4..52a5add1132a4 100644 --- a/library/core/src/iter/adapters/copied.rs +++ b/library/core/src/iter/adapters/copied.rs @@ -1,7 +1,7 @@ use crate::iter::adapters::{ - zip::try_get_unchecked, TrustedRandomAccess, TrustedRandomAccessNoCoerce, + zip::try_get_unchecked, SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce, }; -use crate::iter::{FusedIterator, TrustedLen}; +use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen}; use crate::mem::MaybeUninit; use crate::mem::SizedTypeProperties; use crate::num::NonZeroUsize; @@ -255,3 +255,23 @@ impl Default for Copied { Self::new(Default::default()) } } + +#[unstable(issue = "none", feature = "inplace_iteration")] +unsafe impl SourceIter for Copied +where + I: SourceIter, +{ + type Source = I::Source; + + #[inline] + unsafe fn as_inner(&mut self) -> &mut I::Source { + // SAFETY: unsafe function forwarding to unsafe function with the same requirements + unsafe { SourceIter::as_inner(&mut self.it) } + } +} + +#[unstable(issue = "none", feature = "inplace_iteration")] +unsafe impl InPlaceIterable for Copied { + const EXPAND_BY: Option = I::EXPAND_BY; + const MERGE_BY: Option = I::MERGE_BY; +}