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.
@@ -2581,18 +2584,21 @@ impl<T> [T] {
2581
2584
// First, find at what point do we split between the first and 2nd slice. Easy with
2582
2585
// ptr.align_offset.
2583
2586
let ptr = self . as_ptr ( ) ;
2584
- let offset = crate :: ptr:: align_offset ( ptr, mem:: align_of :: < U > ( ) ) ;
2587
+ let offset = unsafe { crate :: ptr:: align_offset ( ptr, mem:: align_of :: < U > ( ) ) } ;
2585
2588
if offset > self . len ( ) {
2586
2589
( self , & [ ] , & [ ] )
2587
2590
} else {
2588
2591
let ( left, rest) = self . split_at ( offset) ;
2589
- // now `rest` is definitely aligned, so `from_raw_parts_mut` below is okay
2590
2592
let ( us_len, ts_len) = rest. align_to_offsets :: < U > ( ) ;
2591
- (
2592
- left,
2593
- from_raw_parts ( rest. as_ptr ( ) as * const U , us_len) ,
2594
- from_raw_parts ( rest. as_ptr ( ) . add ( rest. len ( ) - ts_len) , ts_len) ,
2595
- )
2593
+ // SAFETY: now `rest` is definitely aligned, so `from_raw_parts` below is okay,
2594
+ // since the caller guarantees that we can transmute `T` to `U` safely.
2595
+ unsafe {
2596
+ (
2597
+ left,
2598
+ from_raw_parts ( rest. as_ptr ( ) as * const U , us_len) ,
2599
+ from_raw_parts ( rest. as_ptr ( ) . add ( rest. len ( ) - ts_len) , ts_len) ,
2600
+ )
2601
+ }
2596
2602
}
2597
2603
}
2598
2604
@@ -2637,21 +2643,23 @@ impl<T> [T] {
2637
2643
// First, find at what point do we split between the first and 2nd slice. Easy with
2638
2644
// ptr.align_offset.
2639
2645
let ptr = self . as_ptr ( ) ;
2640
- let offset = crate :: ptr:: align_offset ( ptr, mem:: align_of :: < U > ( ) ) ;
2646
+ let offset = unsafe { crate :: ptr:: align_offset ( ptr, mem:: align_of :: < U > ( ) ) } ;
2641
2647
if offset > self . len ( ) {
2642
2648
( self , & mut [ ] , & mut [ ] )
2643
2649
} else {
2644
2650
let ( left, rest) = self . split_at_mut ( offset) ;
2645
- // now `rest` is definitely aligned, so `from_raw_parts_mut` below is okay
2646
2651
let ( us_len, ts_len) = rest. align_to_offsets :: < U > ( ) ;
2647
2652
let rest_len = rest. len ( ) ;
2648
2653
let mut_ptr = rest. as_mut_ptr ( ) ;
2649
2654
// We can't use `rest` again after this, that would invalidate its alias `mut_ptr`!
2650
- (
2651
- left,
2652
- from_raw_parts_mut ( mut_ptr as * mut U , us_len) ,
2653
- from_raw_parts_mut ( mut_ptr. add ( rest_len - ts_len) , ts_len) ,
2654
- )
2655
+ // SAFETY: see comments for `align_to`.
2656
+ unsafe {
2657
+ (
2658
+ left,
2659
+ from_raw_parts_mut ( mut_ptr as * mut U , us_len) ,
2660
+ from_raw_parts_mut ( mut_ptr. add ( rest_len - ts_len) , ts_len) ,
2661
+ )
2662
+ }
2655
2663
}
2656
2664
}
2657
2665
@@ -2976,12 +2984,18 @@ impl<T> SliceIndex<[T]> for usize {
2976
2984
2977
2985
#[ inline]
2978
2986
unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & T {
2979
- & * slice. as_ptr ( ) . add ( self )
2987
+ // SAFETY: `slice` cannot be longer than `isize::MAX` and
2988
+ // the caller guarantees that `self` is in bounds of `slice`
2989
+ // so `self` cannot overflow an `isize`, so the call to `add` is safe.
2990
+ // The obtained pointer comes from a reference which is guaranteed
2991
+ // to be valid.
2992
+ unsafe { & * slice. as_ptr ( ) . add ( self ) }
2980
2993
}
2981
2994
2982
2995
#[ inline]
2983
2996
unsafe fn get_unchecked_mut ( self , slice : & mut [ T ] ) -> & mut T {
2984
- & mut * slice. as_mut_ptr ( ) . add ( self )
2997
+ // SAFETY: see comments for `get_unchecked` above.
2998
+ unsafe { & mut * slice. as_mut_ptr ( ) . add ( self ) }
2985
2999
}
2986
3000
2987
3001
#[ inline]
@@ -3021,12 +3035,18 @@ impl<T> SliceIndex<[T]> for ops::Range<usize> {
3021
3035
3022
3036
#[ inline]
3023
3037
unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3024
- from_raw_parts ( slice. as_ptr ( ) . add ( self . start ) , self . end - self . start )
3038
+ // SAFETY: `slice` cannot be longer than `isize::MAX` and
3039
+ // the caller guarantees that `self` is in bounds of `slice`
3040
+ // so `self` cannot overflow an `isize`, so the call to `add` is safe.
3041
+ // Also, since the caller guarantees that `self` is in bounds of `slice`,
3042
+ // `from_raw_parts` will give a subslice of `slice` which is always safe.
3043
+ unsafe { from_raw_parts ( slice. as_ptr ( ) . add ( self . start ) , self . end - self . start ) }
3025
3044
}
3026
3045
3027
3046
#[ inline]
3028
3047
unsafe fn get_unchecked_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
3029
- from_raw_parts_mut ( slice. as_mut_ptr ( ) . add ( self . start ) , self . end - self . start )
3048
+ // SAFETY: see comments for `get_unchecked` above.
3049
+ unsafe { from_raw_parts_mut ( slice. as_mut_ptr ( ) . add ( self . start ) , self . end - self . start ) }
3030
3050
}
3031
3051
3032
3052
#[ inline]
@@ -3066,12 +3086,14 @@ impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
3066
3086
3067
3087
#[ inline]
3068
3088
unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3069
- ( 0 ..self . end ) . get_unchecked ( slice)
3089
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
3090
+ unsafe { ( 0 ..self . end ) . get_unchecked ( slice) }
3070
3091
}
3071
3092
3072
3093
#[ inline]
3073
3094
unsafe fn get_unchecked_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
3074
- ( 0 ..self . end ) . get_unchecked_mut ( slice)
3095
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
3096
+ unsafe { ( 0 ..self . end ) . get_unchecked_mut ( slice) }
3075
3097
}
3076
3098
3077
3099
#[ inline]
@@ -3101,12 +3123,14 @@ impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
3101
3123
3102
3124
#[ inline]
3103
3125
unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3104
- ( self . start ..slice. len ( ) ) . get_unchecked ( slice)
3126
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
3127
+ unsafe { ( self . start ..slice. len ( ) ) . get_unchecked ( slice) }
3105
3128
}
3106
3129
3107
3130
#[ inline]
3108
3131
unsafe fn get_unchecked_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
3109
- ( self . start ..slice. len ( ) ) . get_unchecked_mut ( slice)
3132
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
3133
+ unsafe { ( self . start ..slice. len ( ) ) . get_unchecked_mut ( slice) }
3110
3134
}
3111
3135
3112
3136
#[ inline]
@@ -3175,12 +3199,14 @@ impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
3175
3199
3176
3200
#[ inline]
3177
3201
unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3178
- ( * self . start ( ) ..self . end ( ) + 1 ) . get_unchecked ( slice)
3202
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
3203
+ unsafe { ( * self . start ( ) ..self . end ( ) + 1 ) . get_unchecked ( slice) }
3179
3204
}
3180
3205
3181
3206
#[ inline]
3182
3207
unsafe fn get_unchecked_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
3183
- ( * self . start ( ) ..self . end ( ) + 1 ) . get_unchecked_mut ( slice)
3208
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
3209
+ unsafe { ( * self . start ( ) ..self . end ( ) + 1 ) . get_unchecked_mut ( slice) }
3184
3210
}
3185
3211
3186
3212
#[ inline]
@@ -3216,12 +3242,14 @@ impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
3216
3242
3217
3243
#[ inline]
3218
3244
unsafe fn get_unchecked ( self , slice : & [ T ] ) -> & [ T ] {
3219
- ( 0 ..=self . end ) . get_unchecked ( slice)
3245
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
3246
+ unsafe { ( 0 ..=self . end ) . get_unchecked ( slice) }
3220
3247
}
3221
3248
3222
3249
#[ inline]
3223
3250
unsafe fn get_unchecked_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
3224
- ( 0 ..=self . end ) . get_unchecked_mut ( slice)
3251
+ // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
3252
+ unsafe { ( 0 ..=self . end ) . get_unchecked_mut ( slice) }
3225
3253
}
3226
3254
3227
3255
#[ inline]
@@ -3370,7 +3398,9 @@ macro_rules! iterator {
3370
3398
self . ptr. as_ptr( )
3371
3399
} else {
3372
3400
let old = self . ptr. as_ptr( ) ;
3373
- self . ptr = NonNull :: new_unchecked( self . ptr. as_ptr( ) . offset( offset) ) ;
3401
+ // SAFETY: the caller guarantees that `offset` doesn't exceed `self.len()`,
3402
+ // so this new pointer is inside `self` and thus guaranteed to be non-null.
3403
+ self . ptr = unsafe { NonNull :: new_unchecked( self . ptr. as_ptr( ) . offset( offset) ) } ;
3374
3404
old
3375
3405
}
3376
3406
}
@@ -3384,7 +3414,10 @@ macro_rules! iterator {
3384
3414
zst_shrink!( self , offset) ;
3385
3415
self . ptr. as_ptr( )
3386
3416
} else {
3387
- self . end = self . end. offset( -offset) ;
3417
+ // SAFETY: the caller guarantees that `offset` doesn't exceed `self.len()`,
3418
+ // which is guaranteed to not overflow an `isize`. Also, the resulting pointer
3419
+ // is in bounds of `slice`, which fulfills the other requirements for `offset`.
3420
+ self . end = unsafe { self . end. offset( -offset) } ;
3388
3421
self . end
3389
3422
}
3390
3423
}
@@ -4702,7 +4735,11 @@ impl<T> FusedIterator for Windows<'_, T> {}
4702
4735
#[ doc( hidden) ]
4703
4736
unsafe impl < ' a , T > TrustedRandomAccess for Windows < ' a , T > {
4704
4737
unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a [ T ] {
4705
- from_raw_parts ( self . v . as_ptr ( ) . add ( i) , self . size )
4738
+ // SAFETY: since the caller guarantees that `i` is in bounds,
4739
+ // which means that `i` cannot overflow an `isize`, and the
4740
+ // slice created by `from_raw_parts` is a subslice of `self.v`
4741
+ // thus is guaranteed to be valid for the lifetime `'a` of `self.v`.
4742
+ unsafe { from_raw_parts ( self . v . as_ptr ( ) . add ( i) , self . size ) }
4706
4743
}
4707
4744
fn may_have_side_effect ( ) -> bool {
4708
4745
false
@@ -4846,7 +4883,14 @@ unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> {
4846
4883
None => self . v . len ( ) ,
4847
4884
Some ( end) => cmp:: min ( end, self . v . len ( ) ) ,
4848
4885
} ;
4849
- from_raw_parts ( self . v . as_ptr ( ) . add ( start) , end - start)
4886
+ // SAFETY: the caller guarantees that `i` is in bounds,
4887
+ // which means that `start` must be in bounds of the
4888
+ // underlying `self.v` slice, and we made sure that `end`
4889
+ // is also in bounds of `self.v`. Thus, `start` cannot overflow
4890
+ // an `isize`, and the slice constructed by `from_raw_parts`
4891
+ // is a subslice of `self.v` which is guaranteed to be valid
4892
+ // for the lifetime `'a` of `self.v`.
4893
+ unsafe { from_raw_parts ( self . v . as_ptr ( ) . add ( start) , end - start) }
4850
4894
}
4851
4895
fn may_have_side_effect ( ) -> bool {
4852
4896
false
@@ -4988,7 +5032,8 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {
4988
5032
None => self . v . len ( ) ,
4989
5033
Some ( end) => cmp:: min ( end, self . v . len ( ) ) ,
4990
5034
} ;
4991
- from_raw_parts_mut ( self . v . as_mut_ptr ( ) . add ( start) , end - start)
5035
+ // SAFETY: see comments for `Chunks::get_unchecked`.
5036
+ unsafe { from_raw_parts_mut ( self . v . as_mut_ptr ( ) . add ( start) , end - start) }
4992
5037
}
4993
5038
fn may_have_side_effect ( ) -> bool {
4994
5039
false
@@ -5125,7 +5170,8 @@ impl<T> FusedIterator for ChunksExact<'_, T> {}
5125
5170
unsafe impl < ' a , T > TrustedRandomAccess for ChunksExact < ' a , T > {
5126
5171
unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a [ T ] {
5127
5172
let start = i * self . chunk_size ;
5128
- from_raw_parts ( self . v . as_ptr ( ) . add ( start) , self . chunk_size )
5173
+ // SAFETY: mostly identical to `Chunks::get_unchecked`.
5174
+ unsafe { from_raw_parts ( self . v . as_ptr ( ) . add ( start) , self . chunk_size ) }
5129
5175
}
5130
5176
fn may_have_side_effect ( ) -> bool {
5131
5177
false
@@ -5259,7 +5305,8 @@ impl<T> FusedIterator for ChunksExactMut<'_, T> {}
5259
5305
unsafe impl < ' a , T > TrustedRandomAccess for ChunksExactMut < ' a , T > {
5260
5306
unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a mut [ T ] {
5261
5307
let start = i * self . chunk_size ;
5262
- from_raw_parts_mut ( self . v . as_mut_ptr ( ) . add ( start) , self . chunk_size )
5308
+ // SAFETY: see comments for `ChunksExactMut::get_unchecked`.
5309
+ unsafe { from_raw_parts_mut ( self . v . as_mut_ptr ( ) . add ( start) , self . chunk_size ) }
5263
5310
}
5264
5311
fn may_have_side_effect ( ) -> bool {
5265
5312
false
@@ -5406,7 +5453,8 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> {
5406
5453
None => 0 ,
5407
5454
Some ( start) => start,
5408
5455
} ;
5409
- from_raw_parts ( self . v . as_ptr ( ) . add ( start) , end - start)
5456
+ // SAFETY: mostly identical to `Chunks::get_unchecked`.
5457
+ unsafe { from_raw_parts ( self . v . as_ptr ( ) . add ( start) , end - start) }
5410
5458
}
5411
5459
fn may_have_side_effect ( ) -> bool {
5412
5460
false
@@ -5551,7 +5599,8 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> {
5551
5599
None => 0 ,
5552
5600
Some ( start) => start,
5553
5601
} ;
5554
- from_raw_parts_mut ( self . v . as_mut_ptr ( ) . add ( start) , end - start)
5602
+ // SAFETY: see comments for `RChunks::get_unchecked`.
5603
+ unsafe { from_raw_parts_mut ( self . v . as_mut_ptr ( ) . add ( start) , end - start) }
5555
5604
}
5556
5605
fn may_have_side_effect ( ) -> bool {
5557
5606
false
@@ -5692,7 +5741,8 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> {
5692
5741
unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a [ T ] {
5693
5742
let end = self . v . len ( ) - i * self . chunk_size ;
5694
5743
let start = end - self . chunk_size ;
5695
- from_raw_parts ( self . v . as_ptr ( ) . add ( start) , self . chunk_size )
5744
+ // SAFETY: mostmy identical to `Chunks::get_unchecked`.
5745
+ unsafe { from_raw_parts ( self . v . as_ptr ( ) . add ( start) , self . chunk_size ) }
5696
5746
}
5697
5747
fn may_have_side_effect ( ) -> bool {
5698
5748
false
@@ -5831,7 +5881,8 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
5831
5881
unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a mut [ T ] {
5832
5882
let end = self . v . len ( ) - i * self . chunk_size ;
5833
5883
let start = end - self . chunk_size ;
5834
- from_raw_parts_mut ( self . v . as_mut_ptr ( ) . add ( start) , self . chunk_size )
5884
+ // SAFETY: see comments for `RChunksExact::get_unchecked`.
5885
+ unsafe { from_raw_parts_mut ( self . v . as_mut_ptr ( ) . add ( start) , self . chunk_size ) }
5835
5886
}
5836
5887
fn may_have_side_effect ( ) -> bool {
5837
5888
false
@@ -5927,7 +5978,8 @@ pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
5927
5978
mem:: size_of:: <T >( ) . saturating_mul( len) <= isize :: MAX as usize ,
5928
5979
"attempt to create slice covering at least half the address space"
5929
5980
) ;
5930
- & * ptr:: slice_from_raw_parts ( data, len)
5981
+ // SAFETY: the caller must uphold the safety contract for `from_raw_parts`.
5982
+ unsafe { & * ptr:: slice_from_raw_parts ( data, len) }
5931
5983
}
5932
5984
5933
5985
/// Performs the same functionality as [`from_raw_parts`], except that a
@@ -5967,7 +6019,8 @@ pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T]
5967
6019
mem:: size_of:: <T >( ) . saturating_mul( len) <= isize :: MAX as usize ,
5968
6020
"attempt to create slice covering at least half the address space"
5969
6021
) ;
5970
- & mut * ptr:: slice_from_raw_parts_mut ( data, len)
6022
+ // SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`.
6023
+ unsafe { & mut * ptr:: slice_from_raw_parts_mut ( data, len) }
5971
6024
}
5972
6025
5973
6026
/// Converts a reference to T into a slice of length 1 (without copying).
@@ -6243,7 +6296,11 @@ impl_marker_for!(BytewiseEquality,
6243
6296
#[ doc( hidden) ]
6244
6297
unsafe impl < ' a , T > TrustedRandomAccess for Iter < ' a , T > {
6245
6298
unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a T {
6246
- & * self . ptr . as_ptr ( ) . add ( i)
6299
+ // SAFETY: the caller must guarantee that `i` is in bounds
6300
+ // of the underlying slice, so `i` cannot overflow an `isize`,
6301
+ // and the returned references is guaranteed to refer to an element
6302
+ // of the slice and thus guaranteed to be valid.
6303
+ unsafe { & * self . ptr . as_ptr ( ) . add ( i) }
6247
6304
}
6248
6305
fn may_have_side_effect ( ) -> bool {
6249
6306
false
@@ -6253,7 +6310,8 @@ unsafe impl<'a, T> TrustedRandomAccess for Iter<'a, T> {
6253
6310
#[ doc( hidden) ]
6254
6311
unsafe impl < ' a , T > TrustedRandomAccess for IterMut < ' a , T > {
6255
6312
unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a mut T {
6256
- & mut * self . ptr . as_ptr ( ) . add ( i)
6313
+ // SAFETY: see comments for `Iter::get_unchecked`.
6314
+ unsafe { & mut * self . ptr . as_ptr ( ) . add ( i) }
6257
6315
}
6258
6316
fn may_have_side_effect ( ) -> bool {
6259
6317
false
0 commit comments