@@ -1628,14 +1628,21 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Chunks<'a, T> {
1628
1628
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1629
1629
#[ must_use = "iterators are lazy and do nothing unless consumed" ]
1630
1630
pub struct ChunksMut < ' a , T : ' a > {
1631
- v : & ' a mut [ T ] ,
1631
+ /// # Safety
1632
+ /// This slice pointer must point at a valid region of `T` with at least length `v.len()`. Normally,
1633
+ /// those requirements would mean that we could instead use a `&mut [T]` here, but we cannot
1634
+ /// because `__iterator_get_unchecked` needs to return `&mut [T]`, which guarantees certain aliasing
1635
+ /// properties that we cannot uphold if we hold on to the full original `&mut [T]`. Wrapping a raw
1636
+ /// slice instead lets us hand out non-overlapping `&mut [T]` subslices of the slice we wrap.
1637
+ v : * mut [ T ] ,
1632
1638
chunk_size : usize ,
1639
+ _marker : PhantomData < & ' a mut T > ,
1633
1640
}
1634
1641
1635
1642
impl < ' a , T : ' a > ChunksMut < ' a , T > {
1636
1643
#[ inline]
1637
1644
pub ( super ) fn new ( slice : & ' a mut [ T ] , size : usize ) -> Self {
1638
- Self { v : slice, chunk_size : size }
1645
+ Self { v : slice, chunk_size : size, _marker : PhantomData }
1639
1646
}
1640
1647
}
1641
1648
@@ -1649,10 +1656,11 @@ impl<'a, T> Iterator for ChunksMut<'a, T> {
1649
1656
None
1650
1657
} else {
1651
1658
let sz = cmp:: min ( self . v . len ( ) , self . chunk_size ) ;
1652
- let tmp = mem :: replace ( & mut self . v , & mut [ ] ) ;
1653
- let ( head, tail) = tmp . split_at_mut ( sz) ;
1659
+ // SAFETY: The self.v contract ensures that any split_at_mut is valid.
1660
+ let ( head, tail) = unsafe { self . v . split_at_mut ( sz) } ;
1654
1661
self . v = tail;
1655
- Some ( head)
1662
+ // SAFETY: Nothing else points to or will point to the contents of this slice.
1663
+ Some ( unsafe { & mut * head } )
1656
1664
}
1657
1665
}
1658
1666
@@ -1684,11 +1692,13 @@ impl<'a, T> Iterator for ChunksMut<'a, T> {
1684
1692
Some ( sum) => cmp:: min ( self . v . len ( ) , sum) ,
1685
1693
None => self . v . len ( ) ,
1686
1694
} ;
1687
- let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
1688
- let ( head, tail) = tmp. split_at_mut ( end) ;
1689
- let ( _, nth) = head. split_at_mut ( start) ;
1695
+ // SAFETY: The self.v contract ensures that any split_at_mut is valid.
1696
+ let ( head, tail) = unsafe { self . v . split_at_mut ( end) } ;
1697
+ // SAFETY: The self.v contract ensures that any split_at_mut is valid.
1698
+ let ( _, nth) = unsafe { head. split_at_mut ( start) } ;
1690
1699
self . v = tail;
1691
- Some ( nth)
1700
+ // SAFETY: Nothing else points to or will point to the contents of this slice.
1701
+ Some ( unsafe { & mut * nth } )
1692
1702
}
1693
1703
}
1694
1704
@@ -1698,13 +1708,14 @@ impl<'a, T> Iterator for ChunksMut<'a, T> {
1698
1708
None
1699
1709
} else {
1700
1710
let start = ( self . v . len ( ) - 1 ) / self . chunk_size * self . chunk_size ;
1701
- Some ( & mut self . v [ start..] )
1711
+ // SAFETY: Nothing else points to or will point to the contents of this slice.
1712
+ Some ( unsafe { & mut * self . v . get_unchecked_mut ( start..) } )
1702
1713
}
1703
1714
}
1704
1715
1705
1716
unsafe fn __iterator_get_unchecked ( & mut self , idx : usize ) -> Self :: Item {
1706
1717
let start = idx * self . chunk_size ;
1707
- // SAFETY: see comments for `Chunks::__iterator_get_unchecked`.
1718
+ // SAFETY: see comments for `Chunks::__iterator_get_unchecked` and `self.v` .
1708
1719
//
1709
1720
// Also note that the caller also guarantees that we're never called
1710
1721
// with the same index again, and that no other methods that will
@@ -1726,12 +1737,12 @@ impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
1726
1737
} else {
1727
1738
let remainder = self . v . len ( ) % self . chunk_size ;
1728
1739
let sz = if remainder != 0 { remainder } else { self . chunk_size } ;
1729
- let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
1730
- let tmp_len = tmp. len ( ) ;
1740
+ let len = self . v . len ( ) ;
1731
1741
// SAFETY: Similar to `Chunks::next_back`
1732
- let ( head, tail) = unsafe { tmp . split_at_mut_unchecked ( tmp_len - sz) } ;
1742
+ let ( head, tail) = unsafe { self . v . split_at_mut_unchecked ( len - sz) } ;
1733
1743
self . v = head;
1734
- Some ( tail)
1744
+ // SAFETY: Nothing else points to or will point to the contents of this slice.
1745
+ Some ( unsafe { & mut * tail } )
1735
1746
}
1736
1747
}
1737
1748
@@ -1747,10 +1758,13 @@ impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
1747
1758
Some ( res) => cmp:: min ( self . v . len ( ) , res) ,
1748
1759
None => self . v . len ( ) ,
1749
1760
} ;
1750
- let ( temp, _tail) = mem:: replace ( & mut self . v , & mut [ ] ) . split_at_mut ( end) ;
1751
- let ( head, nth_back) = temp. split_at_mut ( start) ;
1761
+ // SAFETY: The self.v contract ensures that any split_at_mut is valid.
1762
+ let ( temp, _tail) = unsafe { self . v . split_at_mut ( end) } ;
1763
+ // SAFETY: The self.v contract ensures that any split_at_mut is valid.
1764
+ let ( head, nth_back) = unsafe { temp. split_at_mut ( start) } ;
1752
1765
self . v = head;
1753
- Some ( nth_back)
1766
+ // SAFETY: Nothing else points to or will point to the contents of this slice.
1767
+ Some ( unsafe { & mut * nth_back } )
1754
1768
}
1755
1769
}
1756
1770
}
@@ -1956,9 +1970,16 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksExact<'a, T> {
1956
1970
#[ stable( feature = "chunks_exact" , since = "1.31.0" ) ]
1957
1971
#[ must_use = "iterators are lazy and do nothing unless consumed" ]
1958
1972
pub struct ChunksExactMut < ' a , T : ' a > {
1959
- v : & ' a mut [ T ] ,
1960
- rem : & ' a mut [ T ] ,
1973
+ /// # Safety
1974
+ /// This slice pointer must point at a valid region of `T` with at least length `v.len()`. Normally,
1975
+ /// those requirements would mean that we could instead use a `&mut [T]` here, but we cannot
1976
+ /// because `__iterator_get_unchecked` needs to return `&mut [T]`, which guarantees certain aliasing
1977
+ /// properties that we cannot uphold if we hold on to the full original `&mut [T]`. Wrapping a raw
1978
+ /// slice instead lets us hand out non-overlapping `&mut [T]` subslices of the slice we wrap.
1979
+ v : * mut [ T ] ,
1980
+ rem : & ' a mut [ T ] , // The iterator never yields from here, so this can be unique
1961
1981
chunk_size : usize ,
1982
+ _marker : PhantomData < & ' a mut T > ,
1962
1983
}
1963
1984
1964
1985
impl < ' a , T > ChunksExactMut < ' a , T > {
@@ -1968,7 +1989,7 @@ impl<'a, T> ChunksExactMut<'a, T> {
1968
1989
let fst_len = slice. len ( ) - rem;
1969
1990
// SAFETY: 0 <= fst_len <= slice.len() by construction above
1970
1991
let ( fst, snd) = unsafe { slice. split_at_mut_unchecked ( fst_len) } ;
1971
- Self { v : fst, rem : snd, chunk_size }
1992
+ Self { v : fst, rem : snd, chunk_size, _marker : PhantomData }
1972
1993
}
1973
1994
1974
1995
/// Returns the remainder of the original slice that is not going to be
@@ -1990,10 +2011,11 @@ impl<'a, T> Iterator for ChunksExactMut<'a, T> {
1990
2011
if self . v . len ( ) < self . chunk_size {
1991
2012
None
1992
2013
} else {
1993
- let tmp = mem :: replace ( & mut self . v , & mut [ ] ) ;
1994
- let ( head, tail) = tmp . split_at_mut ( self . chunk_size ) ;
2014
+ // SAFETY: self.chunk_size is inbounds because we compared above against self.v.len()
2015
+ let ( head, tail) = unsafe { self . v . split_at_mut ( self . chunk_size ) } ;
1995
2016
self . v = tail;
1996
- Some ( head)
2017
+ // SAFETY: Nothing else points to or will point to the contents of this slice.
2018
+ Some ( unsafe { & mut * head } )
1997
2019
}
1998
2020
}
1999
2021
@@ -2015,8 +2037,8 @@ impl<'a, T> Iterator for ChunksExactMut<'a, T> {
2015
2037
self . v = & mut [ ] ;
2016
2038
None
2017
2039
} else {
2018
- let tmp = mem :: replace ( & mut self . v , & mut [ ] ) ;
2019
- let ( _, snd) = tmp . split_at_mut ( start) ;
2040
+ // SAFETY: The self.v contract ensures that any split_at_mut is valid.
2041
+ let ( _, snd) = unsafe { self . v . split_at_mut ( start) } ;
2020
2042
self . v = snd;
2021
2043
self . next ( )
2022
2044
}
@@ -2029,7 +2051,7 @@ impl<'a, T> Iterator for ChunksExactMut<'a, T> {
2029
2051
2030
2052
unsafe fn __iterator_get_unchecked ( & mut self , idx : usize ) -> Self :: Item {
2031
2053
let start = idx * self . chunk_size ;
2032
- // SAFETY: see comments for `ChunksMut ::__iterator_get_unchecked`.
2054
+ // SAFETY: see comments for `Chunks ::__iterator_get_unchecked` and `self.v `.
2033
2055
unsafe { from_raw_parts_mut ( self . v . as_mut_ptr ( ) . add ( start) , self . chunk_size ) }
2034
2056
}
2035
2057
}
@@ -2041,11 +2063,11 @@ impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> {
2041
2063
if self . v . len ( ) < self . chunk_size {
2042
2064
None
2043
2065
} else {
2044
- let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
2045
- let tmp_len = tmp. len ( ) ;
2046
- let ( head, tail) = tmp. split_at_mut ( tmp_len - self . chunk_size ) ;
2066
+ // SAFETY: This subtraction is inbounds because of the check above
2067
+ let ( head, tail) = unsafe { self . v . split_at_mut ( self . v . len ( ) - self . chunk_size ) } ;
2047
2068
self . v = head;
2048
- Some ( tail)
2069
+ // SAFETY: Nothing else points to or will point to the contents of this slice.
2070
+ Some ( unsafe { & mut * tail } )
2049
2071
}
2050
2072
}
2051
2073
@@ -2058,10 +2080,13 @@ impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> {
2058
2080
} else {
2059
2081
let start = ( len - 1 - n) * self . chunk_size ;
2060
2082
let end = start + self . chunk_size ;
2061
- let ( temp, _tail) = mem:: replace ( & mut self . v , & mut [ ] ) . split_at_mut ( end) ;
2062
- let ( head, nth_back) = temp. split_at_mut ( start) ;
2083
+ // SAFETY: The self.v contract ensures that any split_at_mut is valid.
2084
+ let ( temp, _tail) = unsafe { mem:: replace ( & mut self . v , & mut [ ] ) . split_at_mut ( end) } ;
2085
+ // SAFETY: The self.v contract ensures that any split_at_mut is valid.
2086
+ let ( head, nth_back) = unsafe { temp. split_at_mut ( start) } ;
2063
2087
self . v = head;
2064
- Some ( nth_back)
2088
+ // SAFETY: Nothing else points to or will point to the contents of this slice.
2089
+ Some ( unsafe { & mut * nth_back } )
2065
2090
}
2066
2091
}
2067
2092
}
@@ -2645,14 +2670,21 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunks<'a, T> {
2645
2670
#[ stable( feature = "rchunks" , since = "1.31.0" ) ]
2646
2671
#[ must_use = "iterators are lazy and do nothing unless consumed" ]
2647
2672
pub struct RChunksMut < ' a , T : ' a > {
2648
- v : & ' a mut [ T ] ,
2673
+ /// # Safety
2674
+ /// This slice pointer must point at a valid region of `T` with at least length `v.len()`. Normally,
2675
+ /// those requirements would mean that we could instead use a `&mut [T]` here, but we cannot
2676
+ /// because `__iterator_get_unchecked` needs to return `&mut [T]`, which guarantees certain aliasing
2677
+ /// properties that we cannot uphold if we hold on to the full original `&mut [T]`. Wrapping a raw
2678
+ /// slice instead lets us hand out non-overlapping `&mut [T]` subslices of the slice we wrap.
2679
+ v : * mut [ T ] ,
2649
2680
chunk_size : usize ,
2681
+ _marker : PhantomData < & ' a mut T > ,
2650
2682
}
2651
2683
2652
2684
impl < ' a , T : ' a > RChunksMut < ' a , T > {
2653
2685
#[ inline]
2654
2686
pub ( super ) fn new ( slice : & ' a mut [ T ] , size : usize ) -> Self {
2655
- Self { v : slice, chunk_size : size }
2687
+ Self { v : slice, chunk_size : size, _marker : PhantomData }
2656
2688
}
2657
2689
}
2658
2690
@@ -2666,16 +2698,16 @@ impl<'a, T> Iterator for RChunksMut<'a, T> {
2666
2698
None
2667
2699
} else {
2668
2700
let sz = cmp:: min ( self . v . len ( ) , self . chunk_size ) ;
2669
- let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
2670
- let tmp_len = tmp. len ( ) ;
2701
+ let len = self . v . len ( ) ;
2671
2702
// SAFETY: split_at_mut_unchecked just requires the argument be less
2672
2703
// than the length. This could only happen if the expression
2673
- // `tmp_len - sz` overflows. This could only happen if `sz >
2674
- // tmp_len `, which is impossible as we initialize it as the `min` of
2675
- // `self.v.len()` (e.g. `tmp_len `) and `self.chunk_size`.
2676
- let ( head, tail) = unsafe { tmp . split_at_mut_unchecked ( tmp_len - sz) } ;
2704
+ // `len - sz` overflows. This could only happen if `sz >
2705
+ // len `, which is impossible as we initialize it as the `min` of
2706
+ // `self.v.len()` (e.g. `len `) and `self.chunk_size`.
2707
+ let ( head, tail) = unsafe { self . v . split_at_mut_unchecked ( len - sz) } ;
2677
2708
self . v = head;
2678
- Some ( tail)
2709
+ // SAFETY: Nothing else points to or will point to the contents of this slice.
2710
+ Some ( unsafe { & mut * tail } )
2679
2711
}
2680
2712
}
2681
2713
@@ -2709,11 +2741,15 @@ impl<'a, T> Iterator for RChunksMut<'a, T> {
2709
2741
Some ( sum) => sum,
2710
2742
None => 0 ,
2711
2743
} ;
2712
- let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
2713
- let ( head, tail) = tmp. split_at_mut ( start) ;
2714
- let ( nth, _) = tail. split_at_mut ( end - start) ;
2744
+ // SAFETY: This type ensures that self.v is a valid pointer with a correct len.
2745
+ // Therefore the bounds check in split_at_mut guarantess the split point is inbounds.
2746
+ let ( head, tail) = unsafe { self . v . split_at_mut ( start) } ;
2747
+ // SAFETY: This type ensures that self.v is a valid pointer with a correct len.
2748
+ // Therefore the bounds check in split_at_mut guarantess the split point is inbounds.
2749
+ let ( nth, _) = unsafe { tail. split_at_mut ( end - start) } ;
2715
2750
self . v = head;
2716
- Some ( nth)
2751
+ // SAFETY: Nothing else points to or will point to the contents of this slice.
2752
+ Some ( unsafe { & mut * nth } )
2717
2753
}
2718
2754
}
2719
2755
@@ -2724,7 +2760,8 @@ impl<'a, T> Iterator for RChunksMut<'a, T> {
2724
2760
} else {
2725
2761
let rem = self . v . len ( ) % self . chunk_size ;
2726
2762
let end = if rem == 0 { self . chunk_size } else { rem } ;
2727
- Some ( & mut self . v [ 0 ..end] )
2763
+ // SAFETY: Nothing else points to or will point to the contents of this slice.
2764
+ Some ( unsafe { & mut * self . v . get_unchecked_mut ( 0 ..end) } )
2728
2765
}
2729
2766
}
2730
2767
@@ -2735,7 +2772,7 @@ impl<'a, T> Iterator for RChunksMut<'a, T> {
2735
2772
Some ( start) => start,
2736
2773
} ;
2737
2774
// SAFETY: see comments for `RChunks::__iterator_get_unchecked` and
2738
- // `ChunksMut::__iterator_get_unchecked`
2775
+ // `ChunksMut::__iterator_get_unchecked`, `self.v`.
2739
2776
unsafe { from_raw_parts_mut ( self . v . as_mut_ptr ( ) . add ( start) , end - start) }
2740
2777
}
2741
2778
}
@@ -2749,11 +2786,11 @@ impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T> {
2749
2786
} else {
2750
2787
let remainder = self . v . len ( ) % self . chunk_size ;
2751
2788
let sz = if remainder != 0 { remainder } else { self . chunk_size } ;
2752
- let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
2753
2789
// SAFETY: Similar to `Chunks::next_back`
2754
- let ( head, tail) = unsafe { tmp . split_at_mut_unchecked ( sz) } ;
2790
+ let ( head, tail) = unsafe { self . v . split_at_mut_unchecked ( sz) } ;
2755
2791
self . v = tail;
2756
- Some ( head)
2792
+ // SAFETY: Nothing else points to or will point to the contents of this slice.
2793
+ Some ( unsafe { & mut * head } )
2757
2794
}
2758
2795
}
2759
2796
@@ -2768,10 +2805,13 @@ impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T> {
2768
2805
let offset_from_end = ( len - 1 - n) * self . chunk_size ;
2769
2806
let end = self . v . len ( ) - offset_from_end;
2770
2807
let start = end. saturating_sub ( self . chunk_size ) ;
2771
- let ( tmp, tail) = mem:: replace ( & mut self . v , & mut [ ] ) . split_at_mut ( end) ;
2772
- let ( _, nth_back) = tmp. split_at_mut ( start) ;
2808
+ // SAFETY: The self.v contract ensures that any split_at_mut is valid.
2809
+ let ( tmp, tail) = unsafe { self . v . split_at_mut ( end) } ;
2810
+ // SAFETY: The self.v contract ensures that any split_at_mut is valid.
2811
+ let ( _, nth_back) = unsafe { tmp. split_at_mut ( start) } ;
2773
2812
self . v = tail;
2774
- Some ( nth_back)
2813
+ // SAFETY: Nothing else points to or will point to the contents of this slice.
2814
+ Some ( unsafe { & mut * nth_back } )
2775
2815
}
2776
2816
}
2777
2817
}
@@ -2897,8 +2937,7 @@ impl<'a, T> Iterator for RChunksExact<'a, T> {
2897
2937
unsafe fn __iterator_get_unchecked ( & mut self , idx : usize ) -> Self :: Item {
2898
2938
let end = self . v . len ( ) - idx * self . chunk_size ;
2899
2939
let start = end - self . chunk_size ;
2900
- // SAFETY:
2901
- // SAFETY: mostmy identical to `Chunks::__iterator_get_unchecked`.
2940
+ // SAFETY: mostly identical to `Chunks::__iterator_get_unchecked`.
2902
2941
unsafe { from_raw_parts ( self . v . as_ptr ( ) . add ( start) , self . chunk_size ) }
2903
2942
}
2904
2943
}
@@ -2981,7 +3020,13 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksExact<'a, T> {
2981
3020
#[ stable( feature = "rchunks" , since = "1.31.0" ) ]
2982
3021
#[ must_use = "iterators are lazy and do nothing unless consumed" ]
2983
3022
pub struct RChunksExactMut < ' a , T : ' a > {
2984
- v : & ' a mut [ T ] ,
3023
+ /// # Safety
3024
+ /// This slice pointer must point at a valid region of `T` with at least length `v.len()`. Normally,
3025
+ /// those requirements would mean that we could instead use a `&mut [T]` here, but we cannot
3026
+ /// because `__iterator_get_unchecked` needs to return `&mut [T]`, which guarantees certain aliasing
3027
+ /// properties that we cannot uphold if we hold on to the full original `&mut [T]`. Wrapping a raw
3028
+ /// slice instead lets us hand out non-overlapping `&mut [T]` subslices of the slice we wrap.
3029
+ v : * mut [ T ] ,
2985
3030
rem : & ' a mut [ T ] ,
2986
3031
chunk_size : usize ,
2987
3032
}
@@ -3014,11 +3059,12 @@ impl<'a, T> Iterator for RChunksExactMut<'a, T> {
3014
3059
if self . v . len ( ) < self . chunk_size {
3015
3060
None
3016
3061
} else {
3017
- let tmp = mem :: replace ( & mut self . v , & mut [ ] ) ;
3018
- let tmp_len = tmp . len ( ) ;
3019
- let ( head, tail) = tmp . split_at_mut ( tmp_len - self . chunk_size ) ;
3062
+ let len = self . v . len ( ) ;
3063
+ // SAFETY: The self.v contract ensures that any split_at_mut is valid.
3064
+ let ( head, tail) = unsafe { self . v . split_at_mut ( len - self . chunk_size ) } ;
3020
3065
self . v = head;
3021
- Some ( tail)
3066
+ // SAFETY: Nothing else points to or will point to the contents of this slice.
3067
+ Some ( unsafe { & mut * tail } )
3022
3068
}
3023
3069
}
3024
3070
@@ -3040,9 +3086,9 @@ impl<'a, T> Iterator for RChunksExactMut<'a, T> {
3040
3086
self . v = & mut [ ] ;
3041
3087
None
3042
3088
} else {
3043
- let tmp = mem :: replace ( & mut self . v , & mut [ ] ) ;
3044
- let tmp_len = tmp . len ( ) ;
3045
- let ( fst, _) = tmp . split_at_mut ( tmp_len - end) ;
3089
+ let len = self . v . len ( ) ;
3090
+ // SAFETY: The self.v contract ensures that any split_at_mut is valid.
3091
+ let ( fst, _) = unsafe { self . v . split_at_mut ( len - end) } ;
3046
3092
self . v = fst;
3047
3093
self . next ( )
3048
3094
}
@@ -3056,7 +3102,7 @@ impl<'a, T> Iterator for RChunksExactMut<'a, T> {
3056
3102
unsafe fn __iterator_get_unchecked ( & mut self , idx : usize ) -> Self :: Item {
3057
3103
let end = self . v . len ( ) - idx * self . chunk_size ;
3058
3104
let start = end - self . chunk_size ;
3059
- // SAFETY: see comments for `RChunksMut::__iterator_get_unchecked`.
3105
+ // SAFETY: see comments for `RChunksMut::__iterator_get_unchecked` and `self.v` .
3060
3106
unsafe { from_raw_parts_mut ( self . v . as_mut_ptr ( ) . add ( start) , self . chunk_size ) }
3061
3107
}
3062
3108
}
@@ -3068,10 +3114,11 @@ impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T> {
3068
3114
if self . v . len ( ) < self . chunk_size {
3069
3115
None
3070
3116
} else {
3071
- let tmp = mem :: replace ( & mut self . v , & mut [ ] ) ;
3072
- let ( head, tail) = tmp . split_at_mut ( self . chunk_size ) ;
3117
+ // SAFETY: The self.v contract ensures that any split_at_mut is valid.
3118
+ let ( head, tail) = unsafe { self . v . split_at_mut ( self . chunk_size ) } ;
3073
3119
self . v = tail;
3074
- Some ( head)
3120
+ // SAFETY: Nothing else points to or will point to the contents of this slice.
3121
+ Some ( unsafe { & mut * head } )
3075
3122
}
3076
3123
}
3077
3124
@@ -3087,10 +3134,13 @@ impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T> {
3087
3134
let offset = ( len - n) * self . chunk_size ;
3088
3135
let start = self . v . len ( ) - offset;
3089
3136
let end = start + self . chunk_size ;
3090
- let ( tmp, tail) = mem:: replace ( & mut self . v , & mut [ ] ) . split_at_mut ( end) ;
3091
- let ( _, nth_back) = tmp. split_at_mut ( start) ;
3137
+ // SAFETY: The self.v contract ensures that any split_at_mut is valid.
3138
+ let ( tmp, tail) = unsafe { self . v . split_at_mut ( end) } ;
3139
+ // SAFETY: The self.v contract ensures that any split_at_mut is valid.
3140
+ let ( _, nth_back) = unsafe { tmp. split_at_mut ( start) } ;
3092
3141
self . v = tail;
3093
- Some ( nth_back)
3142
+ // SAFETY: Nothing else points to or will point to the contents of this slice.
3143
+ Some ( unsafe { & mut * nth_back } )
3094
3144
}
3095
3145
}
3096
3146
}
0 commit comments