@@ -310,8 +310,10 @@ impl<T> [T] {
310310 where
311311 I : SliceIndex < Self > ,
312312 {
313- // SAFETY: the caller must uphold the safety requirements for `get_unchecked`.
314- unsafe { index. get_unchecked ( self ) }
313+ // SAFETY: the caller must uphold most of the safety requirements for `get_unchecked`;
314+ // the slice is dereferencable because `self` is a safe reference.
315+ // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is.
316+ unsafe { & * index. get_unchecked ( self ) }
315317 }
316318
317319 /// Returns a mutable reference to an element or subslice, without doing
@@ -342,8 +344,10 @@ impl<T> [T] {
342344 where
343345 I : SliceIndex < Self > ,
344346 {
345- // SAFETY: the caller must uphold the safety requirements for `get_unchecked_mut`.
346- unsafe { index. get_unchecked_mut ( self ) }
347+ // SAFETY: the caller must uphold the safety requirements for `get_unchecked_mut`;
348+ // the slice is dereferencable because `self` is a safe reference.
349+ // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is.
350+ unsafe { & mut * index. get_unchecked_mut ( self ) }
347351 }
348352
349353 /// Returns a raw pointer to the slice's buffer.
@@ -2910,6 +2914,9 @@ mod private_slice_index {
29102914}
29112915
29122916/// A helper trait used for indexing operations.
2917+ ///
2918+ /// Implementations of this trait have to promise that if the argument
2919+ /// to `get_(mut_)unchecked` is a safe reference, then so is the result.
29132920#[ stable( feature = "slice_get_slice" , since = "1.28.0" ) ]
29142921#[ rustc_on_unimplemented(
29152922 on( T = "str" , label = "string indices are ranges of `usize`" , ) ,
@@ -2921,7 +2928,7 @@ see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#ind
29212928 message = "the type `{T}` cannot be indexed by `{Self}`" ,
29222929 label = "slice indices are of type `usize` or ranges of `usize`"
29232930) ]
2924- pub trait SliceIndex < T : ?Sized > : private_slice_index:: Sealed {
2931+ pub unsafe trait SliceIndex < T : ?Sized > : private_slice_index:: Sealed {
29252932 /// The output type returned by methods.
29262933 #[ stable( feature = "slice_get_slice" , since = "1.28.0" ) ]
29272934 type Output : ?Sized ;
@@ -2938,21 +2945,21 @@ pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
29382945
29392946 /// Returns a shared reference to the output at this location, without
29402947 /// performing any bounds checking.
2941- /// Calling this method with an out-of-bounds index is *[undefined behavior]*
2942- /// even if the resulting reference is not used.
2948+ /// Calling this method with an out-of-bounds index or a dangling `slice` pointer
2949+ /// is *[undefined behavior]* even if the resulting reference is not used.
29432950 ///
29442951 /// [undefined behavior]: ../../reference/behavior-considered-undefined.html
29452952 #[ unstable( feature = "slice_index_methods" , issue = "none" ) ]
2946- unsafe fn get_unchecked ( self , slice : & T ) -> & Self :: Output ;
2953+ unsafe fn get_unchecked ( self , slice : * const T ) -> * const Self :: Output ;
29472954
29482955 /// Returns a mutable reference to the output at this location, without
29492956 /// performing any bounds checking.
2950- /// Calling this method with an out-of-bounds index is *[undefined behavior]*
2951- /// even if the resulting reference is not used.
2957+ /// Calling this method with an out-of-bounds index or a dangling `slice` pointer
2958+ /// is *[undefined behavior]* even if the resulting reference is not used.
29522959 ///
29532960 /// [undefined behavior]: ../../reference/behavior-considered-undefined.html
29542961 #[ unstable( feature = "slice_index_methods" , issue = "none" ) ]
2955- unsafe fn get_unchecked_mut ( self , slice : & mut T ) -> & mut Self :: Output ;
2962+ unsafe fn get_unchecked_mut ( self , slice : * mut T ) -> * mut Self :: Output ;
29562963
29572964 /// Returns a shared reference to the output at this location, panicking
29582965 /// if out of bounds.
@@ -2968,33 +2975,32 @@ pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
29682975}
29692976
29702977#[ stable( feature = "slice_get_slice_impls" , since = "1.15.0" ) ]
2971- impl < T > SliceIndex < [ T ] > for usize {
2978+ unsafe impl < T > SliceIndex < [ T ] > for usize {
29722979 type Output = T ;
29732980
29742981 #[ inline]
29752982 fn get ( self , slice : & [ T ] ) -> Option < & T > {
2976- if self < slice. len ( ) { unsafe { Some ( self . get_unchecked ( slice) ) } } else { None }
2983+ if self < slice. len ( ) { unsafe { Some ( & * self . get_unchecked ( slice) ) } } else { None }
29772984 }
29782985
29792986 #[ inline]
29802987 fn get_mut ( self , slice : & mut [ T ] ) -> Option < & mut T > {
2981- if self < slice. len ( ) { unsafe { Some ( self . get_unchecked_mut ( slice) ) } } else { None }
2988+ if self < slice. len ( ) { unsafe { Some ( & mut * self . get_unchecked_mut ( slice) ) } } else { None }
29822989 }
29832990
29842991 #[ inline]
2985- unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & T {
2986- // SAFETY: `slice` cannot be longer than `isize::MAX` and
2987- // the caller guarantees that `self` is in bounds of `slice`
2988- // so `self` cannot overflow an `isize`, so the call to `add` is safe.
2989- // The obtained pointer comes from a reference which is guaranteed
2990- // to be valid.
2991- unsafe { & * slice. as_ptr ( ) . add ( self ) }
2992+ unsafe fn get_unchecked ( self , slice : * const [ T ] ) -> * const T {
2993+ // SAFETY: the caller guarantees that `slice` is not dangling, so it
2994+ // cannot be longer than `isize::MAX`. They also guarantee that
2995+ // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
2996+ // so the call to `add` is safe.
2997+ unsafe { slice. as_ptr ( ) . add ( self ) }
29922998 }
29932999
29943000 #[ inline]
2995- unsafe fn get_unchecked_mut ( self , slice : & mut [ T ] ) -> & mut T {
3001+ unsafe fn get_unchecked_mut ( self , slice : * mut [ T ] ) -> * mut T {
29963002 // SAFETY: see comments for `get_unchecked` above.
2997- unsafe { & mut * slice. as_mut_ptr ( ) . add ( self ) }
3003+ unsafe { slice. as_mut_ptr ( ) . add ( self ) }
29983004 }
29993005
30003006 #[ inline]
@@ -3011,15 +3017,15 @@ impl<T> SliceIndex<[T]> for usize {
30113017}
30123018
30133019#[ stable( feature = "slice_get_slice_impls" , since = "1.15.0" ) ]
3014- impl < T > SliceIndex < [ T ] > for ops:: Range < usize > {
3020+ unsafe impl < T > SliceIndex < [ T ] > for ops:: Range < usize > {
30153021 type Output = [ T ] ;
30163022
30173023 #[ inline]
30183024 fn get ( self , slice : & [ T ] ) -> Option < & [ T ] > {
30193025 if self . start > self . end || self . end > slice. len ( ) {
30203026 None
30213027 } else {
3022- unsafe { Some ( self . get_unchecked ( slice) ) }
3028+ unsafe { Some ( & * self . get_unchecked ( slice) ) }
30233029 }
30243030 }
30253031
@@ -3028,24 +3034,25 @@ impl<T> SliceIndex<[T]> for ops::Range<usize> {
30283034 if self . start > self . end || self . end > slice. len ( ) {
30293035 None
30303036 } else {
3031- unsafe { Some ( self . get_unchecked_mut ( slice) ) }
3037+ unsafe { Some ( & mut * self . get_unchecked_mut ( slice) ) }
30323038 }
30333039 }
30343040
30353041 #[ inline]
3036- unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3037- // SAFETY: `slice` cannot be longer than `isize::MAX` and
3038- // the caller guarantees that `self` is in bounds of `slice`
3039- // so `self` cannot overflow an `isize`, so the call to `add` is safe.
3040- // Also, since the caller guarantees that `self` is in bounds of `slice`,
3041- // `from_raw_parts` will give a subslice of `slice` which is always safe.
3042- unsafe { from_raw_parts ( slice. as_ptr ( ) . add ( self . start ) , self . end - self . start ) }
3042+ unsafe fn get_unchecked ( self , slice : * const [ T ] ) -> * const [ T ] {
3043+ // SAFETY: the caller guarantees that `slice` is not dangling, so it
3044+ // cannot be longer than `isize::MAX`. They also guarantee that
3045+ // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
3046+ // so the call to `add` is safe.
3047+ unsafe { ptr:: slice_from_raw_parts ( slice. as_ptr ( ) . add ( self . start ) , self . end - self . start ) }
30433048 }
30443049
30453050 #[ inline]
3046- unsafe fn get_unchecked_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
3051+ unsafe fn get_unchecked_mut ( self , slice : * mut [ T ] ) -> * mut [ T ] {
30473052 // SAFETY: see comments for `get_unchecked` above.
3048- unsafe { from_raw_parts_mut ( slice. as_mut_ptr ( ) . add ( self . start ) , self . end - self . start ) }
3053+ unsafe {
3054+ ptr:: slice_from_raw_parts_mut ( slice. as_mut_ptr ( ) . add ( self . start ) , self . end - self . start )
3055+ }
30493056 }
30503057
30513058 #[ inline]
@@ -3055,7 +3062,7 @@ impl<T> SliceIndex<[T]> for ops::Range<usize> {
30553062 } else if self . end > slice. len ( ) {
30563063 slice_index_len_fail ( self . end , slice. len ( ) ) ;
30573064 }
3058- unsafe { self . get_unchecked ( slice) }
3065+ unsafe { & * self . get_unchecked ( slice) }
30593066 }
30603067
30613068 #[ inline]
@@ -3065,12 +3072,12 @@ impl<T> SliceIndex<[T]> for ops::Range<usize> {
30653072 } else if self . end > slice. len ( ) {
30663073 slice_index_len_fail ( self . end , slice. len ( ) ) ;
30673074 }
3068- unsafe { self . get_unchecked_mut ( slice) }
3075+ unsafe { & mut * self . get_unchecked_mut ( slice) }
30693076 }
30703077}
30713078
30723079#[ stable( feature = "slice_get_slice_impls" , since = "1.15.0" ) ]
3073- impl < T > SliceIndex < [ T ] > for ops:: RangeTo < usize > {
3080+ unsafe impl < T > SliceIndex < [ T ] > for ops:: RangeTo < usize > {
30743081 type Output = [ T ] ;
30753082
30763083 #[ inline]
@@ -3084,13 +3091,13 @@ impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
30843091 }
30853092
30863093 #[ inline]
3087- unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3094+ unsafe fn get_unchecked ( self , slice : * const [ T ] ) -> * const [ T ] {
30883095 // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
30893096 unsafe { ( 0 ..self . end ) . get_unchecked ( slice) }
30903097 }
30913098
30923099 #[ inline]
3093- unsafe fn get_unchecked_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
3100+ unsafe fn get_unchecked_mut ( self , slice : * mut [ T ] ) -> * mut [ T ] {
30943101 // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
30953102 unsafe { ( 0 ..self . end ) . get_unchecked_mut ( slice) }
30963103 }
@@ -3107,7 +3114,7 @@ impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
31073114}
31083115
31093116#[ stable( feature = "slice_get_slice_impls" , since = "1.15.0" ) ]
3110- impl < T > SliceIndex < [ T ] > for ops:: RangeFrom < usize > {
3117+ unsafe impl < T > SliceIndex < [ T ] > for ops:: RangeFrom < usize > {
31113118 type Output = [ T ] ;
31123119
31133120 #[ inline]
@@ -3121,13 +3128,13 @@ impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
31213128 }
31223129
31233130 #[ inline]
3124- unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3131+ unsafe fn get_unchecked ( self , slice : * const [ T ] ) -> * const [ T ] {
31253132 // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
31263133 unsafe { ( self . start ..slice. len ( ) ) . get_unchecked ( slice) }
31273134 }
31283135
31293136 #[ inline]
3130- unsafe fn get_unchecked_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
3137+ unsafe fn get_unchecked_mut ( self , slice : * mut [ T ] ) -> * mut [ T ] {
31313138 // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
31323139 unsafe { ( self . start ..slice. len ( ) ) . get_unchecked_mut ( slice) }
31333140 }
@@ -3144,7 +3151,7 @@ impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
31443151}
31453152
31463153#[ stable( feature = "slice_get_slice_impls" , since = "1.15.0" ) ]
3147- impl < T > SliceIndex < [ T ] > for ops:: RangeFull {
3154+ unsafe impl < T > SliceIndex < [ T ] > for ops:: RangeFull {
31483155 type Output = [ T ] ;
31493156
31503157 #[ inline]
@@ -3158,12 +3165,12 @@ impl<T> SliceIndex<[T]> for ops::RangeFull {
31583165 }
31593166
31603167 #[ inline]
3161- unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3168+ unsafe fn get_unchecked ( self , slice : * const [ T ] ) -> * const [ T ] {
31623169 slice
31633170 }
31643171
31653172 #[ inline]
3166- unsafe fn get_unchecked_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
3173+ unsafe fn get_unchecked_mut ( self , slice : * mut [ T ] ) -> * mut [ T ] {
31673174 slice
31683175 }
31693176
@@ -3179,7 +3186,7 @@ impl<T> SliceIndex<[T]> for ops::RangeFull {
31793186}
31803187
31813188#[ stable( feature = "inclusive_range" , since = "1.26.0" ) ]
3182- impl < T > SliceIndex < [ T ] > for ops:: RangeInclusive < usize > {
3189+ unsafe impl < T > SliceIndex < [ T ] > for ops:: RangeInclusive < usize > {
31833190 type Output = [ T ] ;
31843191
31853192 #[ inline]
@@ -3197,13 +3204,13 @@ impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
31973204 }
31983205
31993206 #[ inline]
3200- unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3207+ unsafe fn get_unchecked ( self , slice : * const [ T ] ) -> * const [ T ] {
32013208 // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
32023209 unsafe { ( * self . start ( ) ..self . end ( ) + 1 ) . get_unchecked ( slice) }
32033210 }
32043211
32053212 #[ inline]
3206- unsafe fn get_unchecked_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
3213+ unsafe fn get_unchecked_mut ( self , slice : * mut [ T ] ) -> * mut [ T ] {
32073214 // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
32083215 unsafe { ( * self . start ( ) ..self . end ( ) + 1 ) . get_unchecked_mut ( slice) }
32093216 }
@@ -3226,7 +3233,7 @@ impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
32263233}
32273234
32283235#[ stable( feature = "inclusive_range" , since = "1.26.0" ) ]
3229- impl < T > SliceIndex < [ T ] > for ops:: RangeToInclusive < usize > {
3236+ unsafe impl < T > SliceIndex < [ T ] > for ops:: RangeToInclusive < usize > {
32303237 type Output = [ T ] ;
32313238
32323239 #[ inline]
@@ -3240,13 +3247,13 @@ impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
32403247 }
32413248
32423249 #[ inline]
3243- unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3250+ unsafe fn get_unchecked ( self , slice : * const [ T ] ) -> * const [ T ] {
32443251 // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
32453252 unsafe { ( 0 ..=self . end ) . get_unchecked ( slice) }
32463253 }
32473254
32483255 #[ inline]
3249- unsafe fn get_unchecked_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
3256+ unsafe fn get_unchecked_mut ( self , slice : * mut [ T ] ) -> * mut [ T ] {
32503257 // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
32513258 unsafe { ( 0 ..=self . end ) . get_unchecked_mut ( slice) }
32523259 }
0 commit comments