diff --git a/library/core/benches/iter.rs b/library/core/benches/iter.rs index 24257ba98785d..0abe20e4ca3b2 100644 --- a/library/core/benches/iter.rs +++ b/library/core/benches/iter.rs @@ -367,3 +367,27 @@ fn bench_partial_cmp(b: &mut Bencher) { fn bench_lt(b: &mut Bencher) { b.iter(|| (0..100000).map(black_box).lt((0..100000).map(black_box))) } + +#[bench] +fn bench_trusted_random_access_adapters(b: &mut Bencher) { + let vec1: Vec<_> = (0usize..100000).collect(); + let vec2 = black_box(vec1.clone()); + b.iter(|| { + let mut iter = vec1 + .iter() + .copied() + .enumerate() + .map(|(idx, e)| idx.wrapping_add(e)) + .zip(vec2.iter().copied()) + .map(|(a, b)| a.wrapping_add(b)) + .fuse(); + let mut acc: usize = 0; + let size = iter.size(); + for i in 0..size { + // SAFETY: TRA requirements are satisfied by 0..size iteration and then dropping the + // iterator. + acc = acc.wrapping_add(unsafe { iter.__iterator_get_unchecked(i) }); + } + acc + }) +} diff --git a/library/core/benches/lib.rs b/library/core/benches/lib.rs index d5e1ec083f95d..f1f1ae6e4635d 100644 --- a/library/core/benches/lib.rs +++ b/library/core/benches/lib.rs @@ -3,6 +3,7 @@ #![feature(flt2dec)] #![feature(int_log)] #![feature(test)] +#![feature(trusted_random_access)] extern crate test; diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index 84e4618844a61..10b4db84b3904 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -129,6 +129,7 @@ where #[rustc_inherit_overflow_checks] #[doc(hidden)] + #[inline] unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> ::Item where Self: TrustedRandomAccessNoCoerce, diff --git a/library/core/src/iter/adapters/map.rs b/library/core/src/iter/adapters/map.rs index 4b03449972c9a..6cbb35dc7c629 100644 --- a/library/core/src/iter/adapters/map.rs +++ b/library/core/src/iter/adapters/map.rs @@ -125,6 +125,7 @@ where } #[doc(hidden)] + #[inline] unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> B where Self: TrustedRandomAccessNoCoerce, diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs index f50e71da20f16..de44bd66501e2 100644 --- a/library/core/src/iter/adapters/zip.rs +++ b/library/core/src/iter/adapters/zip.rs @@ -554,6 +554,7 @@ pub unsafe trait TrustedRandomAccessNoCoerce: Sized { /// /// Same requirements calling `get_unchecked` directly. #[doc(hidden)] +#[inline] pub(in crate::iter::adapters) unsafe fn try_get_unchecked(it: &mut I, idx: usize) -> I::Item where I: Iterator, @@ -576,6 +577,7 @@ unsafe impl SpecTrustedRandomAccess for I { } unsafe impl SpecTrustedRandomAccess for I { + #[inline] unsafe fn try_get_unchecked(&mut self, index: usize) -> Self::Item { // SAFETY: the caller must uphold the contract for // `Iterator::__iterator_get_unchecked`. diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index b74ab28fc092a..78bf3381b4d26 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -326,6 +326,7 @@ macro_rules! iterator { } #[doc(hidden)] + #[inline] unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item { // SAFETY: the caller must guarantee that `i` is in bounds of // the underlying slice, so `i` cannot overflow an `isize`, and