8
8
//! [`std::slice`]: ../../std/slice/index.html
9
9
10
10
#![ stable( feature = "rust1" , since = "1.0.0" ) ]
11
+ #![ deny( unsafe_op_in_unsafe_fn) ]
11
12
12
13
// How this module is organized.
13
14
//
@@ -310,7 +311,8 @@ impl<T> [T] {
310
311
where
311
312
I : SliceIndex < Self > ,
312
313
{
313
- index. get_unchecked ( self )
314
+ // SAFETY: the caller must uphold the safety requirements for `get_unchecked`.
315
+ unsafe { index. get_unchecked ( self ) }
314
316
}
315
317
316
318
/// Returns a mutable reference to an element or subslice, without doing
@@ -341,7 +343,8 @@ impl<T> [T] {
341
343
where
342
344
I : SliceIndex < Self > ,
343
345
{
344
- index. get_unchecked_mut ( self )
346
+ // SAFETY: the caller must uphold the safety requirements for `get_unchecked_mut`.
347
+ unsafe { index. get_unchecked_mut ( self ) }
345
348
}
346
349
347
350
/// Returns a raw pointer to the slice's buffer.
@@ -2519,18 +2522,21 @@ impl<T> [T] {
2519
2522
// First, find at what point do we split between the first and 2nd slice. Easy with
2520
2523
// ptr.align_offset.
2521
2524
let ptr = self . as_ptr ( ) ;
2522
- let offset = crate :: ptr:: align_offset ( ptr, mem:: align_of :: < U > ( ) ) ;
2525
+ let offset = unsafe { crate :: ptr:: align_offset ( ptr, mem:: align_of :: < U > ( ) ) } ;
2523
2526
if offset > self . len ( ) {
2524
2527
( self , & [ ] , & [ ] )
2525
2528
} else {
2526
2529
let ( left, rest) = self . split_at ( offset) ;
2527
- // now `rest` is definitely aligned, so `from_raw_parts_mut` below is okay
2528
2530
let ( us_len, ts_len) = rest. align_to_offsets :: < U > ( ) ;
2529
- (
2530
- left,
2531
- from_raw_parts ( rest. as_ptr ( ) as * const U , us_len) ,
2532
- from_raw_parts ( rest. as_ptr ( ) . add ( rest. len ( ) - ts_len) , ts_len) ,
2533
- )
2531
+ // SAFETY: now `rest` is definitely aligned, so `from_raw_parts` below is okay,
2532
+ // since the caller guarantees that we can transmute `T` to `U` safely.
2533
+ unsafe {
2534
+ (
2535
+ left,
2536
+ from_raw_parts ( rest. as_ptr ( ) as * const U , us_len) ,
2537
+ from_raw_parts ( rest. as_ptr ( ) . add ( rest. len ( ) - ts_len) , ts_len) ,
2538
+ )
2539
+ }
2534
2540
}
2535
2541
}
2536
2542
@@ -2575,21 +2581,23 @@ impl<T> [T] {
2575
2581
// First, find at what point do we split between the first and 2nd slice. Easy with
2576
2582
// ptr.align_offset.
2577
2583
let ptr = self . as_ptr ( ) ;
2578
- let offset = crate :: ptr:: align_offset ( ptr, mem:: align_of :: < U > ( ) ) ;
2584
+ let offset = unsafe { crate :: ptr:: align_offset ( ptr, mem:: align_of :: < U > ( ) ) } ;
2579
2585
if offset > self . len ( ) {
2580
2586
( self , & mut [ ] , & mut [ ] )
2581
2587
} else {
2582
2588
let ( left, rest) = self . split_at_mut ( offset) ;
2583
- // now `rest` is definitely aligned, so `from_raw_parts_mut` below is okay
2584
2589
let ( us_len, ts_len) = rest. align_to_offsets :: < U > ( ) ;
2585
2590
let rest_len = rest. len ( ) ;
2586
2591
let mut_ptr = rest. as_mut_ptr ( ) ;
2587
2592
// We can't use `rest` again after this, that would invalidate its alias `mut_ptr`!
2588
- (
2589
- left,
2590
- from_raw_parts_mut ( mut_ptr as * mut U , us_len) ,
2591
- from_raw_parts_mut ( mut_ptr. add ( rest_len - ts_len) , ts_len) ,
2592
- )
2593
+ // SAFETY: see comments for `align_to`.
2594
+ unsafe {
2595
+ (
2596
+ left,
2597
+ from_raw_parts_mut ( mut_ptr as * mut U , us_len) ,
2598
+ from_raw_parts_mut ( mut_ptr. add ( rest_len - ts_len) , ts_len) ,
2599
+ )
2600
+ }
2593
2601
}
2594
2602
}
2595
2603
@@ -2914,12 +2922,18 @@ impl<T> SliceIndex<[T]> for usize {
2914
2922
2915
2923
#[ inline]
2916
2924
unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & T {
2917
- & * slice. as_ptr ( ) . add ( self )
2925
+ // SAFETY: `slice` cannot be longer than `isize::MAX` and
2926
+ // the caller guarantees that `self` is in bounds of `slice`
2927
+ // so `self` cannot overflow an `isize`, so the call to `add` is safe.
2928
+ // The obtained pointer comes from a reference which is guaranteed
2929
+ // to be valid.
2930
+ unsafe { & * slice. as_ptr ( ) . add ( self ) }
2918
2931
}
2919
2932
2920
2933
#[ inline]
2921
2934
unsafe fn get_unchecked_mut ( self , slice : & mut [ T ] ) -> & mut T {
2922
- & mut * slice. as_mut_ptr ( ) . add ( self )
2935
+ // SAFETY: see comments for `get_unchecked` above.
2936
+ unsafe { & mut * slice. as_mut_ptr ( ) . add ( self ) }
2923
2937
}
2924
2938
2925
2939
#[ inline]
@@ -2959,12 +2973,18 @@ impl<T> SliceIndex<[T]> for ops::Range<usize> {
2959
2973
2960
2974
#[ inline]
2961
2975
unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
2962
- from_raw_parts ( slice. as_ptr ( ) . add ( self . start ) , self . end - self . start )
2976
+ // SAFETY: `slice` cannot be longer than `isize::MAX` and
2977
+ // the caller guarantees that `self` is in bounds of `slice`
2978
+ // so `self` cannot overflow an `isize`, so the call to `add` is safe.
2979
+ // Also, since the caller guarantees that `self` is in bounds of `slice`,
2980
+ // `from_raw_parts` will give a subslice of `slice` which is always safe.
2981
+ unsafe { from_raw_parts ( slice. as_ptr ( ) . add ( self . start ) , self . end - self . start ) }
2963
2982
}
2964
2983
2965
2984
#[ inline]
2966
2985
unsafe fn get_unchecked_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
2967
- from_raw_parts_mut ( slice. as_mut_ptr ( ) . add ( self . start ) , self . end - self . start )
2986
+ // SAFETY: see comments for `get_unchecked` above.
2987
+ unsafe { from_raw_parts_mut ( slice. as_mut_ptr ( ) . add ( self . start ) , self . end - self . start ) }
2968
2988
}
2969
2989
2970
2990
#[ inline]
@@ -3004,12 +3024,14 @@ impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
3004
3024
3005
3025
#[ inline]
3006
3026
unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3007
- ( 0 ..self . end ) . get_unchecked ( slice)
3027
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
3028
+ unsafe { ( 0 ..self . end ) . get_unchecked ( slice) }
3008
3029
}
3009
3030
3010
3031
#[ inline]
3011
3032
unsafe fn get_unchecked_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
3012
- ( 0 ..self . end ) . get_unchecked_mut ( slice)
3033
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
3034
+ unsafe { ( 0 ..self . end ) . get_unchecked_mut ( slice) }
3013
3035
}
3014
3036
3015
3037
#[ inline]
@@ -3039,12 +3061,14 @@ impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
3039
3061
3040
3062
#[ inline]
3041
3063
unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3042
- ( self . start ..slice. len ( ) ) . get_unchecked ( slice)
3064
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
3065
+ unsafe { ( self . start ..slice. len ( ) ) . get_unchecked ( slice) }
3043
3066
}
3044
3067
3045
3068
#[ inline]
3046
3069
unsafe fn get_unchecked_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
3047
- ( self . start ..slice. len ( ) ) . get_unchecked_mut ( slice)
3070
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
3071
+ unsafe { ( self . start ..slice. len ( ) ) . get_unchecked_mut ( slice) }
3048
3072
}
3049
3073
3050
3074
#[ inline]
@@ -3113,12 +3137,14 @@ impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
3113
3137
3114
3138
#[ inline]
3115
3139
unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3116
- ( * self . start ( ) ..self . end ( ) + 1 ) . get_unchecked ( slice)
3140
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
3141
+ unsafe { ( * self . start ( ) ..self . end ( ) + 1 ) . get_unchecked ( slice) }
3117
3142
}
3118
3143
3119
3144
#[ inline]
3120
3145
unsafe fn get_unchecked_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
3121
- ( * self . start ( ) ..self . end ( ) + 1 ) . get_unchecked_mut ( slice)
3146
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
3147
+ unsafe { ( * self . start ( ) ..self . end ( ) + 1 ) . get_unchecked_mut ( slice) }
3122
3148
}
3123
3149
3124
3150
#[ inline]
@@ -3154,12 +3180,14 @@ impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
3154
3180
3155
3181
#[ inline]
3156
3182
unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3157
- ( 0 ..=self . end ) . get_unchecked ( slice)
3183
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
3184
+ unsafe { ( 0 ..=self . end ) . get_unchecked ( slice) }
3158
3185
}
3159
3186
3160
3187
#[ inline]
3161
3188
unsafe fn get_unchecked_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
3162
- ( 0 ..=self . end ) . get_unchecked_mut ( slice)
3189
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
3190
+ unsafe { ( 0 ..=self . end ) . get_unchecked_mut ( slice) }
3163
3191
}
3164
3192
3165
3193
#[ inline]
@@ -3308,7 +3336,9 @@ macro_rules! iterator {
3308
3336
self . ptr. as_ptr( )
3309
3337
} else {
3310
3338
let old = self . ptr. as_ptr( ) ;
3311
- self . ptr = NonNull :: new_unchecked( self . ptr. as_ptr( ) . offset( offset) ) ;
3339
+ // SAFETY: the caller guarantees that `offset` doesn't exceed `self.len()`,
3340
+ // so this new pointer is inside `self` and thus guaranteed to be non-null.
3341
+ self . ptr = unsafe { NonNull :: new_unchecked( self . ptr. as_ptr( ) . offset( offset) ) } ;
3312
3342
old
3313
3343
}
3314
3344
}
@@ -3322,7 +3352,10 @@ macro_rules! iterator {
3322
3352
zst_shrink!( self , offset) ;
3323
3353
self . ptr. as_ptr( )
3324
3354
} else {
3325
- self . end = self . end. offset( -offset) ;
3355
+ // SAFETY: the caller guarantees that `offset` doesn't exceed `self.len()`,
3356
+ // which is guaranteed to not overflow an `isize`. Also, the resulting pointer
3357
+ // is in bounds of `slice`, which fulfills the other requirements for `offset`.
3358
+ self . end = unsafe { self . end. offset( -offset) } ;
3326
3359
self . end
3327
3360
}
3328
3361
}
@@ -4640,7 +4673,11 @@ impl<T> FusedIterator for Windows<'_, T> {}
4640
4673
#[ doc( hidden) ]
4641
4674
unsafe impl < ' a , T > TrustedRandomAccess for Windows < ' a , T > {
4642
4675
unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a [ T ] {
4643
- from_raw_parts ( self . v . as_ptr ( ) . add ( i) , self . size )
4676
+ // SAFETY: since the caller guarantees that `i` is in bounds,
4677
+ // which means that `i` cannot overflow an `isize`, and the
4678
+ // slice created by `from_raw_parts` is a subslice of `self.v`
4679
+ // thus is guaranteed to be valid for the lifetime `'a` of `self.v`.
4680
+ unsafe { from_raw_parts ( self . v . as_ptr ( ) . add ( i) , self . size ) }
4644
4681
}
4645
4682
fn may_have_side_effect ( ) -> bool {
4646
4683
false
@@ -4784,7 +4821,14 @@ unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> {
4784
4821
None => self . v . len ( ) ,
4785
4822
Some ( end) => cmp:: min ( end, self . v . len ( ) ) ,
4786
4823
} ;
4787
- from_raw_parts ( self . v . as_ptr ( ) . add ( start) , end - start)
4824
+ // SAFETY: the caller guarantees that `i` is in bounds,
4825
+ // which means that `start` must be in bounds of the
4826
+ // underlying `self.v` slice, and we made sure that `end`
4827
+ // is also in bounds of `self.v`. Thus, `start` cannot overflow
4828
+ // an `isize`, and the slice constructed by `from_raw_parts`
4829
+ // is a subslice of `self.v` which is guaranteed to be valid
4830
+ // for the lifetime `'a` of `self.v`.
4831
+ unsafe { from_raw_parts ( self . v . as_ptr ( ) . add ( start) , end - start) }
4788
4832
}
4789
4833
fn may_have_side_effect ( ) -> bool {
4790
4834
false
@@ -4926,7 +4970,8 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {
4926
4970
None => self . v . len ( ) ,
4927
4971
Some ( end) => cmp:: min ( end, self . v . len ( ) ) ,
4928
4972
} ;
4929
- from_raw_parts_mut ( self . v . as_mut_ptr ( ) . add ( start) , end - start)
4973
+ // SAFETY: see comments for `Chunks::get_unchecked`.
4974
+ unsafe { from_raw_parts_mut ( self . v . as_mut_ptr ( ) . add ( start) , end - start) }
4930
4975
}
4931
4976
fn may_have_side_effect ( ) -> bool {
4932
4977
false
@@ -5063,7 +5108,8 @@ impl<T> FusedIterator for ChunksExact<'_, T> {}
5063
5108
unsafe impl < ' a , T > TrustedRandomAccess for ChunksExact < ' a , T > {
5064
5109
unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a [ T ] {
5065
5110
let start = i * self . chunk_size ;
5066
- from_raw_parts ( self . v . as_ptr ( ) . add ( start) , self . chunk_size )
5111
+ // SAFETY: mostly identical to `Chunks::get_unchecked`.
5112
+ unsafe { from_raw_parts ( self . v . as_ptr ( ) . add ( start) , self . chunk_size ) }
5067
5113
}
5068
5114
fn may_have_side_effect ( ) -> bool {
5069
5115
false
@@ -5197,7 +5243,8 @@ impl<T> FusedIterator for ChunksExactMut<'_, T> {}
5197
5243
unsafe impl < ' a , T > TrustedRandomAccess for ChunksExactMut < ' a , T > {
5198
5244
unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a mut [ T ] {
5199
5245
let start = i * self . chunk_size ;
5200
- from_raw_parts_mut ( self . v . as_mut_ptr ( ) . add ( start) , self . chunk_size )
5246
+ // SAFETY: see comments for `ChunksExactMut::get_unchecked`.
5247
+ unsafe { from_raw_parts_mut ( self . v . as_mut_ptr ( ) . add ( start) , self . chunk_size ) }
5201
5248
}
5202
5249
fn may_have_side_effect ( ) -> bool {
5203
5250
false
@@ -5344,7 +5391,8 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> {
5344
5391
None => 0 ,
5345
5392
Some ( start) => start,
5346
5393
} ;
5347
- from_raw_parts ( self . v . as_ptr ( ) . add ( start) , end - start)
5394
+ // SAFETY: mostly identical to `Chunks::get_unchecked`.
5395
+ unsafe { from_raw_parts ( self . v . as_ptr ( ) . add ( start) , end - start) }
5348
5396
}
5349
5397
fn may_have_side_effect ( ) -> bool {
5350
5398
false
@@ -5489,7 +5537,8 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> {
5489
5537
None => 0 ,
5490
5538
Some ( start) => start,
5491
5539
} ;
5492
- from_raw_parts_mut ( self . v . as_mut_ptr ( ) . add ( start) , end - start)
5540
+ // SAFETY: see comments for `RChunks::get_unchecked`.
5541
+ unsafe { from_raw_parts_mut ( self . v . as_mut_ptr ( ) . add ( start) , end - start) }
5493
5542
}
5494
5543
fn may_have_side_effect ( ) -> bool {
5495
5544
false
@@ -5630,7 +5679,8 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> {
5630
5679
unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a [ T ] {
5631
5680
let end = self . v . len ( ) - i * self . chunk_size ;
5632
5681
let start = end - self . chunk_size ;
5633
- from_raw_parts ( self . v . as_ptr ( ) . add ( start) , self . chunk_size )
5682
+ // SAFETY: mostmy identical to `Chunks::get_unchecked`.
5683
+ unsafe { from_raw_parts ( self . v . as_ptr ( ) . add ( start) , self . chunk_size ) }
5634
5684
}
5635
5685
fn may_have_side_effect ( ) -> bool {
5636
5686
false
@@ -5769,7 +5819,8 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
5769
5819
unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a mut [ T ] {
5770
5820
let end = self . v . len ( ) - i * self . chunk_size ;
5771
5821
let start = end - self . chunk_size ;
5772
- from_raw_parts_mut ( self . v . as_mut_ptr ( ) . add ( start) , self . chunk_size )
5822
+ // SAFETY: see comments for `RChunksExact::get_unchecked`.
5823
+ unsafe { from_raw_parts_mut ( self . v . as_mut_ptr ( ) . add ( start) , self . chunk_size ) }
5773
5824
}
5774
5825
fn may_have_side_effect ( ) -> bool {
5775
5826
false
@@ -5865,7 +5916,8 @@ pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
5865
5916
mem:: size_of:: <T >( ) . saturating_mul( len) <= isize :: MAX as usize ,
5866
5917
"attempt to create slice covering at least half the address space"
5867
5918
) ;
5868
- & * ptr:: slice_from_raw_parts ( data, len)
5919
+ // SAFETY: the caller must uphold the safety contract for `from_raw_parts`.
5920
+ unsafe { & * ptr:: slice_from_raw_parts ( data, len) }
5869
5921
}
5870
5922
5871
5923
/// Performs the same functionality as [`from_raw_parts`], except that a
@@ -5905,7 +5957,8 @@ pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T]
5905
5957
mem:: size_of:: <T >( ) . saturating_mul( len) <= isize :: MAX as usize ,
5906
5958
"attempt to create slice covering at least half the address space"
5907
5959
) ;
5908
- & mut * ptr:: slice_from_raw_parts_mut ( data, len)
5960
+ // SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`.
5961
+ unsafe { & mut * ptr:: slice_from_raw_parts_mut ( data, len) }
5909
5962
}
5910
5963
5911
5964
/// Converts a reference to T into a slice of length 1 (without copying).
@@ -6181,7 +6234,11 @@ impl_marker_for!(BytewiseEquality,
6181
6234
#[ doc( hidden) ]
6182
6235
unsafe impl < ' a , T > TrustedRandomAccess for Iter < ' a , T > {
6183
6236
unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a T {
6184
- & * self . ptr . as_ptr ( ) . add ( i)
6237
+ // SAFETY: the caller must guarantee that `i` is in bounds
6238
+ // of the underlying slice, so `i` cannot overflow an `isize`,
6239
+ // and the returned references is guaranteed to refer to an element
6240
+ // of the slice and thus guaranteed to be valid.
6241
+ unsafe { & * self . ptr . as_ptr ( ) . add ( i) }
6185
6242
}
6186
6243
fn may_have_side_effect ( ) -> bool {
6187
6244
false
@@ -6191,7 +6248,8 @@ unsafe impl<'a, T> TrustedRandomAccess for Iter<'a, T> {
6191
6248
#[ doc( hidden) ]
6192
6249
unsafe impl < ' a , T > TrustedRandomAccess for IterMut < ' a , T > {
6193
6250
unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a mut T {
6194
- & mut * self . ptr . as_ptr ( ) . add ( i)
6251
+ // SAFETY: see comments for `Iter::get_unchecked`.
6252
+ unsafe { & mut * self . ptr . as_ptr ( ) . add ( i) }
6195
6253
}
6196
6254
fn may_have_side_effect ( ) -> bool {
6197
6255
false
0 commit comments