Skip to content

Commit d9d4d39

Browse files
committed
Auto merge of #73565 - matthewjasper:core-min-spec, r=nagisa
Use min_specialization in libcore Getting `TrustedRandomAccess` to work is the main interesting thing here. - `get_unchecked` is now an unstable, hidden method on `Iterator` - The contract for `TrustedRandomAccess` is made clearer in documentation - Fixed a bug where `Debug` would create aliasing references when using the specialized zip impl - Added tests for the side effects of `next_back` and `nth`. closes #68536
2 parents e15510c + dbad8c9 commit d9d4d39

File tree

8 files changed

+487
-200
lines changed

8 files changed

+487
-200
lines changed

library/core/src/iter/adapters/fuse.rs

+18-12
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::intrinsics;
2-
use crate::iter::{
3-
DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator, TrustedRandomAccess,
4-
};
2+
use crate::iter::adapters::zip::try_get_unchecked;
3+
use crate::iter::TrustedRandomAccess;
4+
use crate::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator};
55
use crate::ops::Try;
66

77
/// An iterator that yields `None` forever after the underlying iterator
@@ -114,6 +114,19 @@ where
114114
{
115115
FuseImpl::find(self, predicate)
116116
}
117+
118+
#[inline]
119+
unsafe fn get_unchecked(&mut self, idx: usize) -> Self::Item
120+
where
121+
Self: TrustedRandomAccess,
122+
{
123+
match self.iter {
124+
// SAFETY: the caller must uphold the contract for `Iterator::get_unchecked`.
125+
Some(ref mut iter) => unsafe { try_get_unchecked(iter, idx) },
126+
// SAFETY: the caller asserts there is an item at `i`, so we're not exhausted.
127+
None => unsafe { intrinsics::unreachable() },
128+
}
129+
}
117130
}
118131

119132
#[stable(feature = "rust1", since = "1.0.0")]
@@ -172,19 +185,12 @@ where
172185
}
173186
}
174187

188+
#[doc(hidden)]
189+
#[unstable(feature = "trusted_random_access", issue = "none")]
175190
unsafe impl<I> TrustedRandomAccess for Fuse<I>
176191
where
177192
I: TrustedRandomAccess,
178193
{
179-
unsafe fn get_unchecked(&mut self, i: usize) -> I::Item {
180-
match self.iter {
181-
// SAFETY: the caller must uphold the contract for `TrustedRandomAccess::get_unchecked`.
182-
Some(ref mut iter) => unsafe { iter.get_unchecked(i) },
183-
// SAFETY: the caller asserts there is an item at `i`, so we're not exhausted.
184-
None => unsafe { intrinsics::unreachable() },
185-
}
186-
}
187-
188194
fn may_have_side_effect() -> bool {
189195
I::may_have_side_effect()
190196
}

library/core/src/iter/adapters/mod.rs

+48-45
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub use self::chain::Chain;
1515
#[stable(feature = "rust1", since = "1.0.0")]
1616
pub use self::flatten::{FlatMap, Flatten};
1717
pub use self::fuse::Fuse;
18+
use self::zip::try_get_unchecked;
1819
pub(crate) use self::zip::TrustedRandomAccess;
1920
pub use self::zip::Zip;
2021

@@ -213,6 +214,15 @@ where
213214
fn count(self) -> usize {
214215
self.it.count()
215216
}
217+
218+
unsafe fn get_unchecked(&mut self, idx: usize) -> T
219+
where
220+
Self: TrustedRandomAccess,
221+
{
222+
// SAFETY: the caller must uphold the contract for
223+
// `Iterator::get_unchecked`.
224+
*unsafe { try_get_unchecked(&mut self.it, idx) }
225+
}
216226
}
217227

218228
#[stable(feature = "iter_copied", since = "1.36.0")]
@@ -266,16 +276,11 @@ where
266276
}
267277

268278
#[doc(hidden)]
269-
unsafe impl<'a, I, T: 'a> TrustedRandomAccess for Copied<I>
279+
#[unstable(feature = "trusted_random_access", issue = "none")]
280+
unsafe impl<I> TrustedRandomAccess for Copied<I>
270281
where
271-
I: TrustedRandomAccess<Item = &'a T>,
272-
T: Copy,
282+
I: TrustedRandomAccess,
273283
{
274-
unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item {
275-
// SAFETY: the caller must uphold the contract for `TrustedRandomAccess::get_unchecked`.
276-
unsafe { *self.it.get_unchecked(i) }
277-
}
278-
279284
#[inline]
280285
fn may_have_side_effect() -> bool {
281286
I::may_have_side_effect()
@@ -344,6 +349,15 @@ where
344349
{
345350
self.it.map(T::clone).fold(init, f)
346351
}
352+
353+
unsafe fn get_unchecked(&mut self, idx: usize) -> T
354+
where
355+
Self: TrustedRandomAccess,
356+
{
357+
// SAFETY: the caller must uphold the contract for
358+
// `Iterator::get_unchecked`.
359+
unsafe { try_get_unchecked(&mut self.it, idx).clone() }
360+
}
347361
}
348362

349363
#[stable(feature = "iter_cloned", since = "1.1.0")]
@@ -397,36 +411,14 @@ where
397411
}
398412

399413
#[doc(hidden)]
400-
unsafe impl<'a, I, T: 'a> TrustedRandomAccess for Cloned<I>
414+
#[unstable(feature = "trusted_random_access", issue = "none")]
415+
unsafe impl<I> TrustedRandomAccess for Cloned<I>
401416
where
402-
I: TrustedRandomAccess<Item = &'a T>,
403-
T: Clone,
404-
{
405-
default unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item {
406-
// SAFETY: the caller must uphold the contract for `TrustedRandomAccess::get_unchecked`.
407-
unsafe { self.it.get_unchecked(i) }.clone()
408-
}
409-
410-
#[inline]
411-
default fn may_have_side_effect() -> bool {
412-
true
413-
}
414-
}
415-
416-
#[doc(hidden)]
417-
unsafe impl<'a, I, T: 'a> TrustedRandomAccess for Cloned<I>
418-
where
419-
I: TrustedRandomAccess<Item = &'a T>,
420-
T: Copy,
417+
I: TrustedRandomAccess,
421418
{
422-
unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item {
423-
// SAFETY: the caller must uphold the contract for `TrustedRandomAccess::get_unchecked`.
424-
unsafe { *self.it.get_unchecked(i) }
425-
}
426-
427419
#[inline]
428420
fn may_have_side_effect() -> bool {
429-
I::may_have_side_effect()
421+
true
430422
}
431423
}
432424

@@ -872,6 +864,15 @@ where
872864
{
873865
self.iter.fold(init, map_fold(self.f, g))
874866
}
867+
868+
unsafe fn get_unchecked(&mut self, idx: usize) -> B
869+
where
870+
Self: TrustedRandomAccess,
871+
{
872+
// SAFETY: the caller must uphold the contract for
873+
// `Iterator::get_unchecked`.
874+
unsafe { (self.f)(try_get_unchecked(&mut self.iter, idx)) }
875+
}
875876
}
876877

877878
#[stable(feature = "rust1", since = "1.0.0")]
@@ -927,15 +928,11 @@ where
927928
}
928929

929930
#[doc(hidden)]
930-
unsafe impl<B, I, F> TrustedRandomAccess for Map<I, F>
931+
#[unstable(feature = "trusted_random_access", issue = "none")]
932+
unsafe impl<I, F> TrustedRandomAccess for Map<I, F>
931933
where
932934
I: TrustedRandomAccess,
933-
F: FnMut(I::Item) -> B,
934935
{
935-
unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item {
936-
// SAFETY: the caller must uphold the contract for `TrustedRandomAccess::get_unchecked`.
937-
(self.f)(unsafe { self.iter.get_unchecked(i) })
938-
}
939936
#[inline]
940937
fn may_have_side_effect() -> bool {
941938
true
@@ -1306,6 +1303,16 @@ where
13061303

13071304
self.iter.fold(init, enumerate(self.count, fold))
13081305
}
1306+
1307+
unsafe fn get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
1308+
where
1309+
Self: TrustedRandomAccess,
1310+
{
1311+
// SAFETY: the caller must uphold the contract for
1312+
// `Iterator::get_unchecked`.
1313+
let value = unsafe { try_get_unchecked(&mut self.iter, idx) };
1314+
(Add::add(self.count, idx), value)
1315+
}
13091316
}
13101317

13111318
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1391,15 +1398,11 @@ where
13911398
}
13921399

13931400
#[doc(hidden)]
1401+
#[unstable(feature = "trusted_random_access", issue = "none")]
13941402
unsafe impl<I> TrustedRandomAccess for Enumerate<I>
13951403
where
13961404
I: TrustedRandomAccess,
13971405
{
1398-
unsafe fn get_unchecked(&mut self, i: usize) -> (usize, I::Item) {
1399-
// SAFETY: the caller must uphold the contract for `TrustedRandomAccess::get_unchecked`.
1400-
(self.count + i, unsafe { self.iter.get_unchecked(i) })
1401-
}
1402-
14031406
fn may_have_side_effect() -> bool {
14041407
I::may_have_side_effect()
14051408
}

0 commit comments

Comments
 (0)