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 }
@@ -254,7 +280,14 @@ unsafe impl<T> SliceIndex<[T]> for usize {
254280 // Use intrinsics::assume instead of hint::assert_unchecked so that we don't check the
255281 // precondition of this function twice.
256282 crate :: intrinsics:: assume ( self < slice. len ( ) ) ;
257- get_noubcheck ( slice, self )
283+ #[ cfg( bootstrap) ]
284+ {
285+ get_noubcheck ( slice, self )
286+ }
287+ #[ cfg( not( bootstrap) ) ]
288+ {
289+ slice_get_unchecked ( slice, self )
290+ }
258291 }
259292 }
260293
@@ -267,7 +300,16 @@ unsafe impl<T> SliceIndex<[T]> for usize {
267300 ( this: usize = self , len: usize = slice. len( ) ) => this < len
268301 ) ;
269302 // SAFETY: see comments for `get_unchecked` above.
270- unsafe { get_mut_noubcheck ( slice, self ) }
303+ unsafe {
304+ #[ cfg( bootstrap) ]
305+ {
306+ get_mut_noubcheck ( slice, self )
307+ }
308+ #[ cfg( not( bootstrap) ) ]
309+ {
310+ slice_get_unchecked ( slice, self )
311+ }
312+ }
271313 }
272314
273315 #[ inline]
0 commit comments