88//! [`std::slice`]: ../../std/slice/index.html
99
1010#![ stable( feature = "rust1" , since = "1.0.0" ) ]
11+ #![ deny( unsafe_op_in_unsafe_fn) ]
1112
1213// How this module is organized.
1314//
@@ -310,7 +311,8 @@ impl<T> [T] {
310311 where
311312 I : SliceIndex < Self > ,
312313 {
313- index. get_unchecked ( self )
314+ // SAFETY: the caller must uphold the safety requirements for `get_unchecked`.
315+ unsafe { index. get_unchecked ( self ) }
314316 }
315317
316318 /// Returns a mutable reference to an element or subslice, without doing
@@ -341,7 +343,8 @@ impl<T> [T] {
341343 where
342344 I : SliceIndex < Self > ,
343345 {
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 ) }
345348 }
346349
347350 /// Returns a raw pointer to the slice's buffer.
@@ -2519,18 +2522,21 @@ impl<T> [T] {
25192522 // First, find at what point do we split between the first and 2nd slice. Easy with
25202523 // ptr.align_offset.
25212524 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 > ( ) ) } ;
25232526 if offset > self . len ( ) {
25242527 ( self , & [ ] , & [ ] )
25252528 } else {
25262529 let ( left, rest) = self . split_at ( offset) ;
2527- // now `rest` is definitely aligned, so `from_raw_parts_mut` below is okay
25282530 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+ }
25342540 }
25352541 }
25362542
@@ -2575,21 +2581,23 @@ impl<T> [T] {
25752581 // First, find at what point do we split between the first and 2nd slice. Easy with
25762582 // ptr.align_offset.
25772583 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 > ( ) ) } ;
25792585 if offset > self . len ( ) {
25802586 ( self , & mut [ ] , & mut [ ] )
25812587 } else {
25822588 let ( left, rest) = self . split_at_mut ( offset) ;
2583- // now `rest` is definitely aligned, so `from_raw_parts_mut` below is okay
25842589 let ( us_len, ts_len) = rest. align_to_offsets :: < U > ( ) ;
25852590 let rest_len = rest. len ( ) ;
25862591 let mut_ptr = rest. as_mut_ptr ( ) ;
25872592 // 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+ }
25932601 }
25942602 }
25952603
@@ -2914,12 +2922,18 @@ impl<T> SliceIndex<[T]> for usize {
29142922
29152923 #[ inline]
29162924 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 ) }
29182931 }
29192932
29202933 #[ inline]
29212934 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 ) }
29232937 }
29242938
29252939 #[ inline]
@@ -2959,12 +2973,18 @@ impl<T> SliceIndex<[T]> for ops::Range<usize> {
29592973
29602974 #[ inline]
29612975 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 ) }
29632982 }
29642983
29652984 #[ inline]
29662985 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 ) }
29682988 }
29692989
29702990 #[ inline]
@@ -3004,12 +3024,14 @@ impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
30043024
30053025 #[ inline]
30063026 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) }
30083029 }
30093030
30103031 #[ inline]
30113032 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) }
30133035 }
30143036
30153037 #[ inline]
@@ -3039,12 +3061,14 @@ impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
30393061
30403062 #[ inline]
30413063 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) }
30433066 }
30443067
30453068 #[ inline]
30463069 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) }
30483072 }
30493073
30503074 #[ inline]
@@ -3113,12 +3137,14 @@ impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
31133137
31143138 #[ inline]
31153139 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) }
31173142 }
31183143
31193144 #[ inline]
31203145 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) }
31223148 }
31233149
31243150 #[ inline]
@@ -3154,12 +3180,14 @@ impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
31543180
31553181 #[ inline]
31563182 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) }
31583185 }
31593186
31603187 #[ inline]
31613188 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) }
31633191 }
31643192
31653193 #[ inline]
@@ -3308,7 +3336,9 @@ macro_rules! iterator {
33083336 self . ptr. as_ptr( )
33093337 } else {
33103338 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) ) } ;
33123342 old
33133343 }
33143344 }
@@ -3322,7 +3352,10 @@ macro_rules! iterator {
33223352 zst_shrink!( self , offset) ;
33233353 self . ptr. as_ptr( )
33243354 } 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) } ;
33263359 self . end
33273360 }
33283361 }
@@ -4640,7 +4673,11 @@ impl<T> FusedIterator for Windows<'_, T> {}
46404673#[ doc( hidden) ]
46414674unsafe impl < ' a , T > TrustedRandomAccess for Windows < ' a , T > {
46424675 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 ) }
46444681 }
46454682 fn may_have_side_effect ( ) -> bool {
46464683 false
@@ -4784,7 +4821,14 @@ unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> {
47844821 None => self . v . len ( ) ,
47854822 Some ( end) => cmp:: min ( end, self . v . len ( ) ) ,
47864823 } ;
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) }
47884832 }
47894833 fn may_have_side_effect ( ) -> bool {
47904834 false
@@ -4926,7 +4970,8 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {
49264970 None => self . v . len ( ) ,
49274971 Some ( end) => cmp:: min ( end, self . v . len ( ) ) ,
49284972 } ;
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) }
49304975 }
49314976 fn may_have_side_effect ( ) -> bool {
49324977 false
@@ -5063,7 +5108,8 @@ impl<T> FusedIterator for ChunksExact<'_, T> {}
50635108unsafe impl < ' a , T > TrustedRandomAccess for ChunksExact < ' a , T > {
50645109 unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a [ T ] {
50655110 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 ) }
50675113 }
50685114 fn may_have_side_effect ( ) -> bool {
50695115 false
@@ -5197,7 +5243,8 @@ impl<T> FusedIterator for ChunksExactMut<'_, T> {}
51975243unsafe impl < ' a , T > TrustedRandomAccess for ChunksExactMut < ' a , T > {
51985244 unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a mut [ T ] {
51995245 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 ) }
52015248 }
52025249 fn may_have_side_effect ( ) -> bool {
52035250 false
@@ -5344,7 +5391,8 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> {
53445391 None => 0 ,
53455392 Some ( start) => start,
53465393 } ;
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) }
53485396 }
53495397 fn may_have_side_effect ( ) -> bool {
53505398 false
@@ -5489,7 +5537,8 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> {
54895537 None => 0 ,
54905538 Some ( start) => start,
54915539 } ;
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) }
54935542 }
54945543 fn may_have_side_effect ( ) -> bool {
54955544 false
@@ -5630,7 +5679,8 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> {
56305679 unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a [ T ] {
56315680 let end = self . v . len ( ) - i * self . chunk_size ;
56325681 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 ) }
56345684 }
56355685 fn may_have_side_effect ( ) -> bool {
56365686 false
@@ -5769,7 +5819,8 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
57695819 unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a mut [ T ] {
57705820 let end = self . v . len ( ) - i * self . chunk_size ;
57715821 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 ) }
57735824 }
57745825 fn may_have_side_effect ( ) -> bool {
57755826 false
@@ -5865,7 +5916,8 @@ pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
58655916 mem:: size_of:: <T >( ) . saturating_mul( len) <= isize :: MAX as usize ,
58665917 "attempt to create slice covering at least half the address space"
58675918 ) ;
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) }
58695921}
58705922
58715923/// 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]
59055957 mem:: size_of:: <T >( ) . saturating_mul( len) <= isize :: MAX as usize ,
59065958 "attempt to create slice covering at least half the address space"
59075959 ) ;
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) }
59095962}
59105963
59115964/// Converts a reference to T into a slice of length 1 (without copying).
@@ -6181,7 +6234,11 @@ impl_marker_for!(BytewiseEquality,
61816234#[ doc( hidden) ]
61826235unsafe impl < ' a , T > TrustedRandomAccess for Iter < ' a , T > {
61836236 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) }
61856242 }
61866243 fn may_have_side_effect ( ) -> bool {
61876244 false
@@ -6191,7 +6248,8 @@ unsafe impl<'a, T> TrustedRandomAccess for Iter<'a, T> {
61916248#[ doc( hidden) ]
61926249unsafe impl < ' a , T > TrustedRandomAccess for IterMut < ' a , T > {
61936250 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) }
61956253 }
61966254 fn may_have_side_effect ( ) -> bool {
61976255 false
0 commit comments