Skip to content

Commit 895d7a9

Browse files
committed
implement TrustedRandomAccess for Ranges over int types
1 parent 1438207 commit 895d7a9

File tree

1 file changed

+42
-1
lines changed

1 file changed

+42
-1
lines changed

library/core/src/iter/range.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::convert::TryFrom;
33
use crate::mem;
44
use crate::ops::{self, Try};
55

6-
use super::{FusedIterator, TrustedLen};
6+
use super::{FusedIterator, TrustedLen, TrustedRandomAccess};
77

88
/// Objects that have a notion of *successor* and *predecessor* operations.
99
///
@@ -493,6 +493,18 @@ macro_rules! range_exact_iter_impl {
493493
)*)
494494
}
495495

496+
/// Safety: This macro must only be used on types that are `Copy` and result in ranges
497+
/// which have an exact `size_hint()` where the upper bound must not be `None`.
498+
macro_rules! unsafe_range_trusted_random_access_impl {
499+
($($t:ty)*) => ($(
500+
#[doc(hidden)]
501+
#[unstable(feature = "trusted_random_access", issue = "none")]
502+
unsafe impl TrustedRandomAccess for ops::Range<$t> {
503+
const MAY_HAVE_SIDE_EFFECT: bool = false;
504+
}
505+
)*)
506+
}
507+
496508
macro_rules! range_incl_exact_iter_impl {
497509
($($t:ty)*) => ($(
498510
#[stable(feature = "inclusive_range", since = "1.26.0")]
@@ -553,6 +565,18 @@ impl<A: Step> Iterator for ops::Range<A> {
553565
fn max(mut self) -> Option<A> {
554566
self.next_back()
555567
}
568+
569+
#[inline]
570+
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
571+
where
572+
Self: TrustedRandomAccess,
573+
{
574+
// SAFETY: The TrustedRandomAccess contract requires that callers only pass an index
575+
// that is in bounds.
576+
// Additionally Self: TrustedRandomAccess is only implemented for Copy types
577+
// which means even repeated reads of the same index would be safe.
578+
unsafe { Step::forward_unchecked(self.start.clone(), idx) }
579+
}
556580
}
557581

558582
// These macros generate `ExactSizeIterator` impls for various range types.
@@ -574,6 +598,23 @@ range_exact_iter_impl! {
574598
u32
575599
i32
576600
}
601+
602+
unsafe_range_trusted_random_access_impl! {
603+
usize u8 u16
604+
isize i8 i16
605+
}
606+
607+
#[cfg(target_pointer_width = "32")]
608+
unsafe_range_trusted_random_access_impl! {
609+
u32 i32
610+
}
611+
612+
#[cfg(target_pointer_width = "64")]
613+
unsafe_range_trusted_random_access_impl! {
614+
u32 i32
615+
u64 i64
616+
}
617+
577618
range_incl_exact_iter_impl! {
578619
u8
579620
i8

0 commit comments

Comments
 (0)