@@ -310,8 +310,10 @@ impl<T> [T] {
310
310
where
311
311
I : SliceIndex < Self > ,
312
312
{
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 ) }
315
317
}
316
318
317
319
/// Returns a mutable reference to an element or subslice, without doing
@@ -342,8 +344,10 @@ impl<T> [T] {
342
344
where
343
345
I : SliceIndex < Self > ,
344
346
{
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 ) }
347
351
}
348
352
349
353
/// Returns a raw pointer to the slice's buffer.
@@ -2910,6 +2914,9 @@ mod private_slice_index {
2910
2914
}
2911
2915
2912
2916
/// 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.
2913
2920
#[ stable( feature = "slice_get_slice" , since = "1.28.0" ) ]
2914
2921
#[ rustc_on_unimplemented(
2915
2922
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
2921
2928
message = "the type `{T}` cannot be indexed by `{Self}`" ,
2922
2929
label = "slice indices are of type `usize` or ranges of `usize`"
2923
2930
) ]
2924
- pub trait SliceIndex < T : ?Sized > : private_slice_index:: Sealed {
2931
+ pub unsafe trait SliceIndex < T : ?Sized > : private_slice_index:: Sealed {
2925
2932
/// The output type returned by methods.
2926
2933
#[ stable( feature = "slice_get_slice" , since = "1.28.0" ) ]
2927
2934
type Output : ?Sized ;
@@ -2938,21 +2945,21 @@ pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
2938
2945
2939
2946
/// Returns a shared reference to the output at this location, without
2940
2947
/// 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.
2943
2950
///
2944
2951
/// [undefined behavior]: ../../reference/behavior-considered-undefined.html
2945
2952
#[ 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 ;
2947
2954
2948
2955
/// Returns a mutable reference to the output at this location, without
2949
2956
/// 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.
2952
2959
///
2953
2960
/// [undefined behavior]: ../../reference/behavior-considered-undefined.html
2954
2961
#[ 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 ;
2956
2963
2957
2964
/// Returns a shared reference to the output at this location, panicking
2958
2965
/// if out of bounds.
@@ -2968,33 +2975,32 @@ pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
2968
2975
}
2969
2976
2970
2977
#[ 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 {
2972
2979
type Output = T ;
2973
2980
2974
2981
#[ inline]
2975
2982
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 }
2977
2984
}
2978
2985
2979
2986
#[ inline]
2980
2987
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 }
2982
2989
}
2983
2990
2984
2991
#[ 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 ) }
2992
2998
}
2993
2999
2994
3000
#[ 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 {
2996
3002
// SAFETY: see comments for `get_unchecked` above.
2997
- unsafe { & mut * slice. as_mut_ptr ( ) . add ( self ) }
3003
+ unsafe { slice. as_mut_ptr ( ) . add ( self ) }
2998
3004
}
2999
3005
3000
3006
#[ inline]
@@ -3011,15 +3017,15 @@ impl<T> SliceIndex<[T]> for usize {
3011
3017
}
3012
3018
3013
3019
#[ 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 > {
3015
3021
type Output = [ T ] ;
3016
3022
3017
3023
#[ inline]
3018
3024
fn get ( self , slice : & [ T ] ) -> Option < & [ T ] > {
3019
3025
if self . start > self . end || self . end > slice. len ( ) {
3020
3026
None
3021
3027
} else {
3022
- unsafe { Some ( self . get_unchecked ( slice) ) }
3028
+ unsafe { Some ( & * self . get_unchecked ( slice) ) }
3023
3029
}
3024
3030
}
3025
3031
@@ -3028,24 +3034,25 @@ impl<T> SliceIndex<[T]> for ops::Range<usize> {
3028
3034
if self . start > self . end || self . end > slice. len ( ) {
3029
3035
None
3030
3036
} else {
3031
- unsafe { Some ( self . get_unchecked_mut ( slice) ) }
3037
+ unsafe { Some ( & mut * self . get_unchecked_mut ( slice) ) }
3032
3038
}
3033
3039
}
3034
3040
3035
3041
#[ 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 ) }
3043
3048
}
3044
3049
3045
3050
#[ 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 ] {
3047
3052
// 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
+ }
3049
3056
}
3050
3057
3051
3058
#[ inline]
@@ -3055,7 +3062,7 @@ impl<T> SliceIndex<[T]> for ops::Range<usize> {
3055
3062
} else if self . end > slice. len ( ) {
3056
3063
slice_index_len_fail ( self . end , slice. len ( ) ) ;
3057
3064
}
3058
- unsafe { self . get_unchecked ( slice) }
3065
+ unsafe { & * self . get_unchecked ( slice) }
3059
3066
}
3060
3067
3061
3068
#[ inline]
@@ -3065,12 +3072,12 @@ impl<T> SliceIndex<[T]> for ops::Range<usize> {
3065
3072
} else if self . end > slice. len ( ) {
3066
3073
slice_index_len_fail ( self . end , slice. len ( ) ) ;
3067
3074
}
3068
- unsafe { self . get_unchecked_mut ( slice) }
3075
+ unsafe { & mut * self . get_unchecked_mut ( slice) }
3069
3076
}
3070
3077
}
3071
3078
3072
3079
#[ 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 > {
3074
3081
type Output = [ T ] ;
3075
3082
3076
3083
#[ inline]
@@ -3084,13 +3091,13 @@ impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
3084
3091
}
3085
3092
3086
3093
#[ inline]
3087
- unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3094
+ unsafe fn get_unchecked ( self , slice : * const [ T ] ) -> * const [ T ] {
3088
3095
// SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
3089
3096
unsafe { ( 0 ..self . end ) . get_unchecked ( slice) }
3090
3097
}
3091
3098
3092
3099
#[ 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 ] {
3094
3101
// SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
3095
3102
unsafe { ( 0 ..self . end ) . get_unchecked_mut ( slice) }
3096
3103
}
@@ -3107,7 +3114,7 @@ impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
3107
3114
}
3108
3115
3109
3116
#[ 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 > {
3111
3118
type Output = [ T ] ;
3112
3119
3113
3120
#[ inline]
@@ -3121,13 +3128,13 @@ impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
3121
3128
}
3122
3129
3123
3130
#[ inline]
3124
- unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3131
+ unsafe fn get_unchecked ( self , slice : * const [ T ] ) -> * const [ T ] {
3125
3132
// SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
3126
3133
unsafe { ( self . start ..slice. len ( ) ) . get_unchecked ( slice) }
3127
3134
}
3128
3135
3129
3136
#[ 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 ] {
3131
3138
// SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
3132
3139
unsafe { ( self . start ..slice. len ( ) ) . get_unchecked_mut ( slice) }
3133
3140
}
@@ -3144,7 +3151,7 @@ impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
3144
3151
}
3145
3152
3146
3153
#[ 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 {
3148
3155
type Output = [ T ] ;
3149
3156
3150
3157
#[ inline]
@@ -3158,12 +3165,12 @@ impl<T> SliceIndex<[T]> for ops::RangeFull {
3158
3165
}
3159
3166
3160
3167
#[ inline]
3161
- unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3168
+ unsafe fn get_unchecked ( self , slice : * const [ T ] ) -> * const [ T ] {
3162
3169
slice
3163
3170
}
3164
3171
3165
3172
#[ 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 ] {
3167
3174
slice
3168
3175
}
3169
3176
@@ -3179,7 +3186,7 @@ impl<T> SliceIndex<[T]> for ops::RangeFull {
3179
3186
}
3180
3187
3181
3188
#[ 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 > {
3183
3190
type Output = [ T ] ;
3184
3191
3185
3192
#[ inline]
@@ -3197,13 +3204,13 @@ impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
3197
3204
}
3198
3205
3199
3206
#[ inline]
3200
- unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3207
+ unsafe fn get_unchecked ( self , slice : * const [ T ] ) -> * const [ T ] {
3201
3208
// SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
3202
3209
unsafe { ( * self . start ( ) ..self . end ( ) + 1 ) . get_unchecked ( slice) }
3203
3210
}
3204
3211
3205
3212
#[ 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 ] {
3207
3214
// SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
3208
3215
unsafe { ( * self . start ( ) ..self . end ( ) + 1 ) . get_unchecked_mut ( slice) }
3209
3216
}
@@ -3226,7 +3233,7 @@ impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
3226
3233
}
3227
3234
3228
3235
#[ 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 > {
3230
3237
type Output = [ T ] ;
3231
3238
3232
3239
#[ inline]
@@ -3240,13 +3247,13 @@ impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
3240
3247
}
3241
3248
3242
3249
#[ inline]
3243
- unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3250
+ unsafe fn get_unchecked ( self , slice : * const [ T ] ) -> * const [ T ] {
3244
3251
// SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
3245
3252
unsafe { ( 0 ..=self . end ) . get_unchecked ( slice) }
3246
3253
}
3247
3254
3248
3255
#[ 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 ] {
3250
3257
// SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
3251
3258
unsafe { ( 0 ..=self . end ) . get_unchecked_mut ( slice) }
3252
3259
}
0 commit comments