11//! Indexing implementations for `[T]`.
22
3+ #[ cfg( not( bootstrap) ) ]
4+ use crate :: intrinsics:: slice_get_unchecked;
35use crate :: panic:: const_panic;
46use crate :: ub_checks:: assert_unsafe_precondition;
57use crate :: { ops, range} ;
@@ -83,13 +85,15 @@ const fn slice_end_index_overflow_fail() -> ! {
8385// Both the safe and unsafe public methods share these helpers,
8486// which use intrinsics directly to get *no* extra checks.
8587
88+ #[ cfg( bootstrap) ]
8689#[ inline( always) ]
8790const unsafe fn get_noubcheck < T > ( ptr : * const [ T ] , index : usize ) -> * const T {
8891 let ptr = ptr as * const T ;
8992 // SAFETY: The caller already checked these preconditions
9093 unsafe { crate :: intrinsics:: offset ( ptr, index) }
9194}
9295
96+ #[ cfg( bootstrap) ]
9397#[ inline( always) ]
9498const unsafe fn get_mut_noubcheck < T > ( ptr : * mut [ T ] , index : usize ) -> * mut T {
9599 let ptr = ptr as * mut T ;
@@ -103,8 +107,9 @@ const unsafe fn get_offset_len_noubcheck<T>(
103107 offset : usize ,
104108 len : usize ,
105109) -> * const [ T ] {
110+ let ptr = ptr as * const T ;
106111 // SAFETY: The caller already checked these preconditions
107- let ptr = unsafe { get_noubcheck ( ptr, offset) } ;
112+ let ptr = unsafe { crate :: intrinsics :: offset ( ptr, offset) } ;
108113 crate :: intrinsics:: aggregate_raw_ptr ( ptr, len)
109114}
110115
@@ -114,8 +119,9 @@ const unsafe fn get_offset_len_mut_noubcheck<T>(
114119 offset : usize ,
115120 len : usize ,
116121) -> * mut [ T ] {
122+ let ptr = ptr as * mut T ;
117123 // SAFETY: The caller already checked these preconditions
118- let ptr = unsafe { get_mut_noubcheck ( ptr, offset) } ;
124+ let ptr = unsafe { crate :: intrinsics :: offset ( ptr, offset) } ;
119125 crate :: intrinsics:: aggregate_raw_ptr ( ptr, len)
120126}
121127
@@ -224,15 +230,35 @@ unsafe impl<T> SliceIndex<[T]> for usize {
224230
225231 #[ inline]
226232 fn get ( self , slice : & [ T ] ) -> Option < & T > {
227- // SAFETY: `self` is checked to be in bounds.
228- if self < slice. len ( ) { unsafe { Some ( & * get_noubcheck ( slice, self ) ) } } else { None }
233+ if self < slice. len ( ) {
234+ #[ cfg( bootstrap) ]
235+ // SAFETY: `self` is checked to be in bounds.
236+ unsafe {
237+ Some ( & * get_noubcheck ( slice, self ) )
238+ }
239+ #[ cfg( not( bootstrap) ) ]
240+ // SAFETY: `self` is checked to be in bounds.
241+ unsafe {
242+ Some ( slice_get_unchecked ( slice, self ) )
243+ }
244+ } else {
245+ None
246+ }
229247 }
230248
231249 #[ inline]
232250 fn get_mut ( self , slice : & mut [ T ] ) -> Option < & mut T > {
233251 if self < slice. len ( ) {
252+ #[ cfg( bootstrap) ]
253+ // SAFETY: `self` is checked to be in bounds.
254+ unsafe {
255+ Some ( & mut * get_mut_noubcheck ( slice, self ) )
256+ }
257+ #[ cfg( not( bootstrap) ) ]
234258 // SAFETY: `self` is checked to be in bounds.
235- unsafe { Some ( & mut * get_mut_noubcheck ( slice, self ) ) }
259+ unsafe {
260+ Some ( slice_get_unchecked ( slice, self ) )
261+ }
236262 } else {
237263 None
238264 }
@@ -253,7 +279,14 @@ unsafe impl<T> SliceIndex<[T]> for usize {
253279 // Use intrinsics::assume instead of hint::assert_unchecked so that we don't check the
254280 // precondition of this function twice.
255281 crate :: intrinsics:: assume ( self < slice. len ( ) ) ;
256- get_noubcheck ( slice, self )
282+ #[ cfg( bootstrap) ]
283+ {
284+ get_noubcheck ( slice, self )
285+ }
286+ #[ cfg( not( bootstrap) ) ]
287+ {
288+ slice_get_unchecked ( slice, self )
289+ }
257290 }
258291 }
259292
@@ -265,7 +298,16 @@ unsafe impl<T> SliceIndex<[T]> for usize {
265298 ( this: usize = self , len: usize = slice. len( ) ) => this < len
266299 ) ;
267300 // SAFETY: see comments for `get_unchecked` above.
268- unsafe { get_mut_noubcheck ( slice, self ) }
301+ unsafe {
302+ #[ cfg( bootstrap) ]
303+ {
304+ get_mut_noubcheck ( slice, self )
305+ }
306+ #[ cfg( not( bootstrap) ) ]
307+ {
308+ slice_get_unchecked ( slice, self )
309+ }
310+ }
269311 }
270312
271313 #[ inline]
0 commit comments