@@ -1629,14 +1629,15 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Chunks<'a, T> {
1629
1629
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1630
1630
#[ must_use = "iterators are lazy and do nothing unless consumed" ]
1631
1631
pub struct ChunksMut < ' a , T : ' a > {
1632
- v : & ' a mut [ T ] ,
1632
+ v : * mut [ T ] ,
1633
1633
chunk_size : usize ,
1634
+ _marker : PhantomData < & ' a mut T > ,
1634
1635
}
1635
1636
1636
1637
impl < ' a , T : ' a > ChunksMut < ' a , T > {
1637
1638
#[ inline]
1638
1639
pub ( super ) fn new ( slice : & ' a mut [ T ] , size : usize ) -> Self {
1639
- Self { v : slice, chunk_size : size }
1640
+ Self { v : slice, chunk_size : size, _marker : PhantomData }
1640
1641
}
1641
1642
}
1642
1643
@@ -1650,10 +1651,11 @@ impl<'a, T> Iterator for ChunksMut<'a, T> {
1650
1651
None
1651
1652
} else {
1652
1653
let sz = cmp:: min ( self . v . len ( ) , self . chunk_size ) ;
1653
- let tmp = mem :: replace ( & mut self . v , & mut [ ] ) ;
1654
- let ( head, tail) = tmp . split_at_mut ( sz) ;
1654
+ // SAFETY: sz cannot exceed the slice length based on the calculation above
1655
+ let ( head, tail) = unsafe { self . v . split_at_mut ( sz) } ;
1655
1656
self . v = tail;
1656
- Some ( head)
1657
+ // SAFETY: Nothing points to or will point to the contents of this slice
1658
+ Some ( unsafe { & mut * head } )
1657
1659
}
1658
1660
}
1659
1661
@@ -1685,11 +1687,13 @@ impl<'a, T> Iterator for ChunksMut<'a, T> {
1685
1687
Some ( sum) => cmp:: min ( self . v . len ( ) , sum) ,
1686
1688
None => self . v . len ( ) ,
1687
1689
} ;
1688
- let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
1689
- let ( head, tail) = tmp. split_at_mut ( end) ;
1690
- let ( _, nth) = head. split_at_mut ( start) ;
1690
+ // SAFETY: end is inbounds because we compared above against self.v.len()
1691
+ let ( head, tail) = unsafe { self . v . split_at_mut ( end) } ;
1692
+ // SAFETY: start is inbounds because
1693
+ let ( _, nth) = unsafe { head. split_at_mut ( start) } ;
1691
1694
self . v = tail;
1692
- Some ( nth)
1695
+ // SAFETY: Nothing points to or will point to the contents of this slice
1696
+ Some ( unsafe { & mut * nth } )
1693
1697
}
1694
1698
}
1695
1699
@@ -1699,7 +1703,8 @@ impl<'a, T> Iterator for ChunksMut<'a, T> {
1699
1703
None
1700
1704
} else {
1701
1705
let start = ( self . v . len ( ) - 1 ) / self . chunk_size * self . chunk_size ;
1702
- Some ( & mut self . v [ start..] )
1706
+ // SAFETY: Nothing points to or will point to the contents of this slice
1707
+ Some ( unsafe { & mut * self . v . get_unchecked_mut ( start..) } )
1703
1708
}
1704
1709
}
1705
1710
@@ -1727,12 +1732,12 @@ impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
1727
1732
} else {
1728
1733
let remainder = self . v . len ( ) % self . chunk_size ;
1729
1734
let sz = if remainder != 0 { remainder } else { self . chunk_size } ;
1730
- let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
1731
- let tmp_len = tmp. len ( ) ;
1735
+ let len = self . v . len ( ) ;
1732
1736
// SAFETY: Similar to `Chunks::next_back`
1733
- let ( head, tail) = unsafe { tmp . split_at_mut_unchecked ( tmp_len - sz) } ;
1737
+ let ( head, tail) = unsafe { self . v . split_at_mut_unchecked ( len - sz) } ;
1734
1738
self . v = head;
1735
- Some ( tail)
1739
+ // SAFETY: Nothing points to or will point to the contents of this slice
1740
+ Some ( unsafe { & mut * tail } )
1736
1741
}
1737
1742
}
1738
1743
@@ -1748,10 +1753,12 @@ impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
1748
1753
Some ( res) => cmp:: min ( self . v . len ( ) , res) ,
1749
1754
None => self . v . len ( ) ,
1750
1755
} ;
1751
- let ( temp, _tail) = mem:: replace ( & mut self . v , & mut [ ] ) . split_at_mut ( end) ;
1752
- let ( head, nth_back) = temp. split_at_mut ( start) ;
1756
+ // SAFETY: end is inbounds because we compared above against self.v.len()
1757
+ let ( temp, _tail) = unsafe { self . v . split_at_mut ( end) } ;
1758
+ let ( head, nth_back) = unsafe { temp. split_at_mut ( start) } ;
1753
1759
self . v = head;
1754
- Some ( nth_back)
1760
+ // SAFETY: Nothing points to or will point to the contents of this slice
1761
+ Some ( unsafe { & mut * nth_back } )
1755
1762
}
1756
1763
}
1757
1764
}
@@ -1957,9 +1964,10 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksExact<'a, T> {
1957
1964
#[ stable( feature = "chunks_exact" , since = "1.31.0" ) ]
1958
1965
#[ must_use = "iterators are lazy and do nothing unless consumed" ]
1959
1966
pub struct ChunksExactMut < ' a , T : ' a > {
1960
- v : & ' a mut [ T ] ,
1961
- rem : & ' a mut [ T ] ,
1967
+ v : * mut [ T ] ,
1968
+ rem : & ' a mut [ T ] , // The iterator never yields from here, so this can be unique
1962
1969
chunk_size : usize ,
1970
+ _marker : PhantomData < & ' a mut T > ,
1963
1971
}
1964
1972
1965
1973
impl < ' a , T > ChunksExactMut < ' a , T > {
@@ -1969,7 +1977,7 @@ impl<'a, T> ChunksExactMut<'a, T> {
1969
1977
let fst_len = slice. len ( ) - rem;
1970
1978
// SAFETY: 0 <= fst_len <= slice.len() by construction above
1971
1979
let ( fst, snd) = unsafe { slice. split_at_mut_unchecked ( fst_len) } ;
1972
- Self { v : fst, rem : snd, chunk_size }
1980
+ Self { v : fst, rem : snd, chunk_size, _marker : PhantomData }
1973
1981
}
1974
1982
1975
1983
/// Returns the remainder of the original slice that is not going to be
@@ -1991,10 +1999,11 @@ impl<'a, T> Iterator for ChunksExactMut<'a, T> {
1991
1999
if self . v . len ( ) < self . chunk_size {
1992
2000
None
1993
2001
} else {
1994
- let tmp = mem :: replace ( & mut self . v , & mut [ ] ) ;
1995
- let ( head, tail) = tmp . split_at_mut ( self . chunk_size ) ;
2002
+ // SAFETY: self.chunk_size is inbounds because we compared above against self.v.len()
2003
+ let ( head, tail) = unsafe { self . v . split_at_mut ( self . chunk_size ) } ;
1996
2004
self . v = tail;
1997
- Some ( head)
2005
+ // SAFETY: Nothing points to or will point to the contents of this slice
2006
+ Some ( unsafe { & mut * head } )
1998
2007
}
1999
2008
}
2000
2009
@@ -2016,8 +2025,7 @@ impl<'a, T> Iterator for ChunksExactMut<'a, T> {
2016
2025
self . v = & mut [ ] ;
2017
2026
None
2018
2027
} else {
2019
- let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
2020
- let ( _, snd) = tmp. split_at_mut ( start) ;
2028
+ let ( _, snd) = unsafe { self . v . split_at_mut ( start) } ;
2021
2029
self . v = snd;
2022
2030
self . next ( )
2023
2031
}
@@ -2042,11 +2050,11 @@ impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> {
2042
2050
if self . v . len ( ) < self . chunk_size {
2043
2051
None
2044
2052
} else {
2045
- let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
2046
- let tmp_len = tmp. len ( ) ;
2047
- let ( head, tail) = tmp. split_at_mut ( tmp_len - self . chunk_size ) ;
2053
+ // SAFETY: This subtraction is inbounds because of the check above
2054
+ let ( head, tail) = unsafe { self . v . split_at_mut ( self . v . len ( ) - self . chunk_size ) } ;
2048
2055
self . v = head;
2049
- Some ( tail)
2056
+ // SAFETY: Nothing points to or will point to the contents of this slice
2057
+ Some ( unsafe { & mut * tail } )
2050
2058
}
2051
2059
}
2052
2060
@@ -2059,10 +2067,11 @@ impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> {
2059
2067
} else {
2060
2068
let start = ( len - 1 - n) * self . chunk_size ;
2061
2069
let end = start + self . chunk_size ;
2062
- let ( temp, _tail) = mem:: replace ( & mut self . v , & mut [ ] ) . split_at_mut ( end) ;
2063
- let ( head, nth_back) = temp. split_at_mut ( start) ;
2070
+ let ( temp, _tail) = unsafe { mem:: replace ( & mut self . v , & mut [ ] ) . split_at_mut ( end) } ;
2071
+ let ( head, nth_back) = unsafe { temp. split_at_mut ( start) } ;
2064
2072
self . v = head;
2065
- Some ( nth_back)
2073
+ // SAFETY: Nothing points to or will point to the contents of this slice
2074
+ Some ( unsafe { & mut * nth_back } )
2066
2075
}
2067
2076
}
2068
2077
}
@@ -2646,14 +2655,15 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunks<'a, T> {
2646
2655
#[ stable( feature = "rchunks" , since = "1.31.0" ) ]
2647
2656
#[ must_use = "iterators are lazy and do nothing unless consumed" ]
2648
2657
pub struct RChunksMut < ' a , T : ' a > {
2649
- v : & ' a mut [ T ] ,
2658
+ v : * mut [ T ] ,
2650
2659
chunk_size : usize ,
2660
+ _marker : PhantomData < & ' a mut T > ,
2651
2661
}
2652
2662
2653
2663
impl < ' a , T : ' a > RChunksMut < ' a , T > {
2654
2664
#[ inline]
2655
2665
pub ( super ) fn new ( slice : & ' a mut [ T ] , size : usize ) -> Self {
2656
- Self { v : slice, chunk_size : size }
2666
+ Self { v : slice, chunk_size : size, _marker : PhantomData }
2657
2667
}
2658
2668
}
2659
2669
@@ -2667,16 +2677,16 @@ impl<'a, T> Iterator for RChunksMut<'a, T> {
2667
2677
None
2668
2678
} else {
2669
2679
let sz = cmp:: min ( self . v . len ( ) , self . chunk_size ) ;
2670
- let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
2671
- let tmp_len = tmp. len ( ) ;
2680
+ let len = self . v . len ( ) ;
2672
2681
// SAFETY: split_at_mut_unchecked just requires the argument be less
2673
2682
// than the length. This could only happen if the expression
2674
- // `tmp_len - sz` overflows. This could only happen if `sz >
2675
- // tmp_len `, which is impossible as we initialize it as the `min` of
2676
- // `self.v.len()` (e.g. `tmp_len `) and `self.chunk_size`.
2677
- let ( head, tail) = unsafe { tmp . split_at_mut_unchecked ( tmp_len - sz) } ;
2683
+ // `len - sz` overflows. This could only happen if `sz >
2684
+ // len `, which is impossible as we initialize it as the `min` of
2685
+ // `self.v.len()` (e.g. `len `) and `self.chunk_size`.
2686
+ let ( head, tail) = unsafe { self . v . split_at_mut_unchecked ( len - sz) } ;
2678
2687
self . v = head;
2679
- Some ( tail)
2688
+ // SAFETY: Nothing points to or will point to the contents of this slice
2689
+ Some ( unsafe { & mut * tail } )
2680
2690
}
2681
2691
}
2682
2692
@@ -2710,11 +2720,11 @@ impl<'a, T> Iterator for RChunksMut<'a, T> {
2710
2720
Some ( sum) => sum,
2711
2721
None => 0 ,
2712
2722
} ;
2713
- let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
2714
- let ( head, tail) = tmp. split_at_mut ( start) ;
2715
- let ( nth, _) = tail. split_at_mut ( end - start) ;
2723
+ let ( head, tail) = unsafe { self . v . split_at_mut ( start) } ;
2724
+ let ( nth, _) = unsafe { tail. split_at_mut ( end - start) } ;
2716
2725
self . v = head;
2717
- Some ( nth)
2726
+ // SAFETY: Nothing points to or will point to the contents of this slice
2727
+ Some ( unsafe { & mut * nth } )
2718
2728
}
2719
2729
}
2720
2730
@@ -2725,7 +2735,8 @@ impl<'a, T> Iterator for RChunksMut<'a, T> {
2725
2735
} else {
2726
2736
let rem = self . v . len ( ) % self . chunk_size ;
2727
2737
let end = if rem == 0 { self . chunk_size } else { rem } ;
2728
- Some ( & mut self . v [ 0 ..end] )
2738
+ // SAFETY: Nothing points to or will point to the contents of this slice
2739
+ Some ( unsafe { & mut * self . v . get_unchecked_mut ( 0 ..end) } )
2729
2740
}
2730
2741
}
2731
2742
@@ -2750,11 +2761,11 @@ impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T> {
2750
2761
} else {
2751
2762
let remainder = self . v . len ( ) % self . chunk_size ;
2752
2763
let sz = if remainder != 0 { remainder } else { self . chunk_size } ;
2753
- let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
2754
2764
// SAFETY: Similar to `Chunks::next_back`
2755
- let ( head, tail) = unsafe { tmp . split_at_mut_unchecked ( sz) } ;
2765
+ let ( head, tail) = unsafe { self . v . split_at_mut_unchecked ( sz) } ;
2756
2766
self . v = tail;
2757
- Some ( head)
2767
+ // SAFETY: Nothing points to or will point to the contents of this slice
2768
+ Some ( unsafe { & mut * head } )
2758
2769
}
2759
2770
}
2760
2771
@@ -2769,10 +2780,11 @@ impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T> {
2769
2780
let offset_from_end = ( len - 1 - n) * self . chunk_size ;
2770
2781
let end = self . v . len ( ) - offset_from_end;
2771
2782
let start = end. saturating_sub ( self . chunk_size ) ;
2772
- let ( tmp, tail) = mem :: replace ( & mut self . v , & mut [ ] ) . split_at_mut ( end) ;
2773
- let ( _, nth_back) = tmp. split_at_mut ( start) ;
2783
+ let ( tmp, tail) = unsafe { self . v . split_at_mut ( end) } ;
2784
+ let ( _, nth_back) = unsafe { tmp. split_at_mut ( start) } ;
2774
2785
self . v = tail;
2775
- Some ( nth_back)
2786
+ // SAFETY: Nothing points to or will point to the contents of this slice
2787
+ Some ( unsafe { & mut * nth_back } )
2776
2788
}
2777
2789
}
2778
2790
}
@@ -2898,8 +2910,7 @@ impl<'a, T> Iterator for RChunksExact<'a, T> {
2898
2910
unsafe fn __iterator_get_unchecked ( & mut self , idx : usize ) -> Self :: Item {
2899
2911
let end = self . v . len ( ) - idx * self . chunk_size ;
2900
2912
let start = end - self . chunk_size ;
2901
- // SAFETY:
2902
- // SAFETY: mostmy identical to `Chunks::__iterator_get_unchecked`.
2913
+ // SAFETY: mostly identical to `Chunks::__iterator_get_unchecked`.
2903
2914
unsafe { from_raw_parts ( self . v . as_ptr ( ) . add ( start) , self . chunk_size ) }
2904
2915
}
2905
2916
}
@@ -2982,7 +2993,7 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksExact<'a, T> {
2982
2993
#[ stable( feature = "rchunks" , since = "1.31.0" ) ]
2983
2994
#[ must_use = "iterators are lazy and do nothing unless consumed" ]
2984
2995
pub struct RChunksExactMut < ' a , T : ' a > {
2985
- v : & ' a mut [ T ] ,
2996
+ v : * mut [ T ] ,
2986
2997
rem : & ' a mut [ T ] ,
2987
2998
chunk_size : usize ,
2988
2999
}
@@ -3015,11 +3026,11 @@ impl<'a, T> Iterator for RChunksExactMut<'a, T> {
3015
3026
if self . v . len ( ) < self . chunk_size {
3016
3027
None
3017
3028
} else {
3018
- let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
3019
- let tmp_len = tmp. len ( ) ;
3020
- let ( head, tail) = tmp. split_at_mut ( tmp_len - self . chunk_size ) ;
3029
+ let len = self . v . len ( ) ;
3030
+ let ( head, tail) = unsafe { self . v . split_at_mut ( len - self . chunk_size ) } ;
3021
3031
self . v = head;
3022
- Some ( tail)
3032
+ // SAFETY: Nothing points to or will point to the contents of this slice
3033
+ Some ( unsafe { & mut * tail } )
3023
3034
}
3024
3035
}
3025
3036
@@ -3041,9 +3052,8 @@ impl<'a, T> Iterator for RChunksExactMut<'a, T> {
3041
3052
self . v = & mut [ ] ;
3042
3053
None
3043
3054
} else {
3044
- let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
3045
- let tmp_len = tmp. len ( ) ;
3046
- let ( fst, _) = tmp. split_at_mut ( tmp_len - end) ;
3055
+ let len = self . v . len ( ) ;
3056
+ let ( fst, _) = unsafe { self . v . split_at_mut ( len - end) } ;
3047
3057
self . v = fst;
3048
3058
self . next ( )
3049
3059
}
@@ -3069,10 +3079,10 @@ impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T> {
3069
3079
if self . v . len ( ) < self . chunk_size {
3070
3080
None
3071
3081
} else {
3072
- let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
3073
- let ( head, tail) = tmp. split_at_mut ( self . chunk_size ) ;
3082
+ let ( head, tail) = unsafe { self . v . split_at_mut ( self . chunk_size ) } ;
3074
3083
self . v = tail;
3075
- Some ( head)
3084
+ // SAFETY: Nothing points to or will point to the contents of this slice
3085
+ Some ( unsafe { & mut * head } )
3076
3086
}
3077
3087
}
3078
3088
@@ -3088,10 +3098,11 @@ impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T> {
3088
3098
let offset = ( len - n) * self . chunk_size ;
3089
3099
let start = self . v . len ( ) - offset;
3090
3100
let end = start + self . chunk_size ;
3091
- let ( tmp, tail) = mem :: replace ( & mut self . v , & mut [ ] ) . split_at_mut ( end) ;
3092
- let ( _, nth_back) = tmp. split_at_mut ( start) ;
3101
+ let ( tmp, tail) = unsafe { self . v . split_at_mut ( end) } ;
3102
+ let ( _, nth_back) = unsafe { tmp. split_at_mut ( start) } ;
3093
3103
self . v = tail;
3094
- Some ( nth_back)
3104
+ // SAFETY: Nothing points to or will point to the contents of this slice
3105
+ Some ( unsafe { & mut * nth_back } )
3095
3106
}
3096
3107
}
3097
3108
}
@@ -3174,7 +3185,11 @@ where
3174
3185
let mut len = 1 ;
3175
3186
let mut iter = self . slice . windows ( 2 ) ;
3176
3187
while let Some ( [ l, r] ) = iter. next ( ) {
3177
- if ( self . predicate ) ( l, r) { len += 1 } else { break }
3188
+ if ( self . predicate ) ( l, r) {
3189
+ len += 1
3190
+ } else {
3191
+ break ;
3192
+ }
3178
3193
}
3179
3194
let ( head, tail) = self . slice . split_at ( len) ;
3180
3195
self . slice = tail;
@@ -3206,7 +3221,11 @@ where
3206
3221
let mut len = 1 ;
3207
3222
let mut iter = self . slice . windows ( 2 ) ;
3208
3223
while let Some ( [ l, r] ) = iter. next_back ( ) {
3209
- if ( self . predicate ) ( l, r) { len += 1 } else { break }
3224
+ if ( self . predicate ) ( l, r) {
3225
+ len += 1
3226
+ } else {
3227
+ break ;
3228
+ }
3210
3229
}
3211
3230
let ( head, tail) = self . slice . split_at ( self . slice . len ( ) - len) ;
3212
3231
self . slice = head;
@@ -3261,7 +3280,11 @@ where
3261
3280
let mut len = 1 ;
3262
3281
let mut iter = self . slice . windows ( 2 ) ;
3263
3282
while let Some ( [ l, r] ) = iter. next ( ) {
3264
- if ( self . predicate ) ( l, r) { len += 1 } else { break }
3283
+ if ( self . predicate ) ( l, r) {
3284
+ len += 1
3285
+ } else {
3286
+ break ;
3287
+ }
3265
3288
}
3266
3289
let slice = mem:: take ( & mut self . slice ) ;
3267
3290
let ( head, tail) = slice. split_at_mut ( len) ;
@@ -3294,7 +3317,11 @@ where
3294
3317
let mut len = 1 ;
3295
3318
let mut iter = self . slice . windows ( 2 ) ;
3296
3319
while let Some ( [ l, r] ) = iter. next_back ( ) {
3297
- if ( self . predicate ) ( l, r) { len += 1 } else { break }
3320
+ if ( self . predicate ) ( l, r) {
3321
+ len += 1
3322
+ } else {
3323
+ break ;
3324
+ }
3298
3325
}
3299
3326
let slice = mem:: take ( & mut self . slice ) ;
3300
3327
let ( head, tail) = slice. split_at_mut ( slice. len ( ) - len) ;
0 commit comments