@@ -3,7 +3,7 @@ use crate::convert::TryFrom;
33use crate :: mem;
44use 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+
496508macro_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+
577618range_incl_exact_iter_impl ! {
578619 u8
579620 i8
0 commit comments