Skip to content

Commit 746afe8

Browse files
committed
Clarify safety comments
1 parent e2e3a88 commit 746afe8

File tree

1 file changed

+47
-59
lines changed

1 file changed

+47
-59
lines changed

library/core/src/slice/iter.rs

+47-59
Original file line numberDiff line numberDiff line change
@@ -1629,11 +1629,12 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Chunks<'a, T> {
16291629
#[stable(feature = "rust1", since = "1.0.0")]
16301630
#[must_use = "iterators are lazy and do nothing unless consumed"]
16311631
pub struct ChunksMut<'a, T: 'a> {
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.
1632+
/// # Safety
1633+
/// This slice pointer must point at a valid region of `T` with at least length `v.len()`. Normally,
1634+
/// those requirements would mean that we could instead use a `&mut [T]` here, but we cannot
1635+
/// because `__iterator_get_unchecked` needs to return `&mut [T]`, which guarantees certain aliasing
1636+
/// properties that we cannot uphold if we hold on to the full original `&mut [T]`. Wrapping a raw
1637+
/// slice instead lets us hand out non-overlapping `&mut [T]` subslices of the slice we wrap.
16371638
v: *mut [T],
16381639
chunk_size: usize,
16391640
_marker: PhantomData<&'a mut T>,
@@ -1656,7 +1657,7 @@ impl<'a, T> Iterator for ChunksMut<'a, T> {
16561657
None
16571658
} else {
16581659
let sz = cmp::min(self.v.len(), self.chunk_size);
1659-
// SAFETY: This type ensures that any split_at_mut on self.v is valid.
1660+
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
16601661
let (head, tail) = unsafe { self.v.split_at_mut(sz) };
16611662
self.v = tail;
16621663
// SAFETY: Nothing else points to or will point to the contents of this slice.
@@ -1692,9 +1693,9 @@ impl<'a, T> Iterator for ChunksMut<'a, T> {
16921693
Some(sum) => cmp::min(self.v.len(), sum),
16931694
None => self.v.len(),
16941695
};
1695-
// SAFETY: This type ensures that any split_at_mut on self.v is valid.
1696+
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
16961697
let (head, tail) = unsafe { self.v.split_at_mut(end) };
1697-
// SAFETY: This type ensures that any split_at_mut on self.v is valid.
1698+
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
16981699
let (_, nth) = unsafe { head.split_at_mut(start) };
16991700
self.v = tail;
17001701
// SAFETY: Nothing else points to or will point to the contents of this slice.
@@ -1715,7 +1716,7 @@ impl<'a, T> Iterator for ChunksMut<'a, T> {
17151716

17161717
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
17171718
let start = idx * self.chunk_size;
1718-
// SAFETY: see comments for `Chunks::__iterator_get_unchecked`.
1719+
// SAFETY: see comments for `Chunks::__iterator_get_unchecked` and `self.v`.
17191720
//
17201721
// Also note that the caller also guarantees that we're never called
17211722
// with the same index again, and that no other methods that will
@@ -1758,9 +1759,9 @@ impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
17581759
Some(res) => cmp::min(self.v.len(), res),
17591760
None => self.v.len(),
17601761
};
1761-
// SAFETY: This type ensures that any split_at_mut on self.v is valid.
1762+
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
17621763
let (temp, _tail) = unsafe { self.v.split_at_mut(end) };
1763-
// SAFETY: This type ensures that any split_at_mut on self.v is valid.
1764+
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
17641765
let (head, nth_back) = unsafe { temp.split_at_mut(start) };
17651766
self.v = head;
17661767
// SAFETY: Nothing else points to or will point to the contents of this slice.
@@ -1970,11 +1971,12 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksExact<'a, T> {
19701971
#[stable(feature = "chunks_exact", since = "1.31.0")]
19711972
#[must_use = "iterators are lazy and do nothing unless consumed"]
19721973
pub struct ChunksExactMut<'a, T: 'a> {
1973-
// This slice pointer must point at a valid region of T with at least length v.len(). Normally,
1974-
// those requirements would mean that we could instead use a &mut [T] here, but we cannot
1975-
// because __iterator_get_unchecked needs to return &mut [T], which guarantees certain aliasing
1976-
// properties that we cannot uphold if we hold on to the full original &mut [T]. Wrapping a raw
1977-
// slice instead lets us hand out non-overlapping &mut [T] subslices of the slice we wrap.
1974+
/// # Safety
1975+
/// This slice pointer must point at a valid region of `T` with at least length `v.len()`. Normally,
1976+
/// those requirements would mean that we could instead use a `&mut [T]` here, but we cannot
1977+
/// because `__iterator_get_unchecked` needs to return `&mut [T]`, which guarantees certain aliasing
1978+
/// properties that we cannot uphold if we hold on to the full original `&mut [T]`. Wrapping a raw
1979+
/// slice instead lets us hand out non-overlapping `&mut [T]` subslices of the slice we wrap.
19781980
v: *mut [T],
19791981
rem: &'a mut [T], // The iterator never yields from here, so this can be unique
19801982
chunk_size: usize,
@@ -2036,7 +2038,7 @@ impl<'a, T> Iterator for ChunksExactMut<'a, T> {
20362038
self.v = &mut [];
20372039
None
20382040
} else {
2039-
// SAFETY: This type ensures that any split_at_mut on self.v is valid.
2041+
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
20402042
let (_, snd) = unsafe { self.v.split_at_mut(start) };
20412043
self.v = snd;
20422044
self.next()
@@ -2050,7 +2052,7 @@ impl<'a, T> Iterator for ChunksExactMut<'a, T> {
20502052

20512053
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
20522054
let start = idx * self.chunk_size;
2053-
// SAFETY: see comments for `ChunksMut::__iterator_get_unchecked`.
2055+
// SAFETY: see comments for `Chunks::__iterator_get_unchecked` and `self.v`.
20542056
unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), self.chunk_size) }
20552057
}
20562058
}
@@ -2079,9 +2081,9 @@ impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> {
20792081
} else {
20802082
let start = (len - 1 - n) * self.chunk_size;
20812083
let end = start + self.chunk_size;
2082-
// SAFETY: This type ensures that any split_at_mut on self.v is valid.
2084+
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
20832085
let (temp, _tail) = unsafe { mem::replace(&mut self.v, &mut []).split_at_mut(end) };
2084-
// SAFETY: This type ensures that any split_at_mut on self.v is valid.
2086+
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
20852087
let (head, nth_back) = unsafe { temp.split_at_mut(start) };
20862088
self.v = head;
20872089
// SAFETY: Nothing else points to or will point to the contents of this slice.
@@ -2669,11 +2671,12 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunks<'a, T> {
26692671
#[stable(feature = "rchunks", since = "1.31.0")]
26702672
#[must_use = "iterators are lazy and do nothing unless consumed"]
26712673
pub struct RChunksMut<'a, T: 'a> {
2672-
// This slice pointer must point at a valid region of T with at least length v.len(). Normally,
2673-
// those requirements would mean that we could instead use a &mut [T] here, but we cannot
2674-
// because __iterator_get_unchecked needs to return &mut [T], which guarantees certain aliasing
2675-
// properties that we cannot uphold if we hold on to the full original &mut [T]. Wrapping a raw
2676-
// slice instead lets us hand out non-overlapping &mut [T] subslices of the slice we wrap.
2674+
/// # Safety
2675+
/// This slice pointer must point at a valid region of `T` with at least length `v.len()`. Normally,
2676+
/// those requirements would mean that we could instead use a `&mut [T]` here, but we cannot
2677+
/// because `__iterator_get_unchecked` needs to return `&mut [T]`, which guarantees certain aliasing
2678+
/// properties that we cannot uphold if we hold on to the full original `&mut [T]`. Wrapping a raw
2679+
/// slice instead lets us hand out non-overlapping `&mut [T]` subslices of the slice we wrap.
26772680
v: *mut [T],
26782681
chunk_size: usize,
26792682
_marker: PhantomData<&'a mut T>,
@@ -2770,7 +2773,7 @@ impl<'a, T> Iterator for RChunksMut<'a, T> {
27702773
Some(start) => start,
27712774
};
27722775
// SAFETY: see comments for `RChunks::__iterator_get_unchecked` and
2773-
// `ChunksMut::__iterator_get_unchecked`
2776+
// `ChunksMut::__iterator_get_unchecked`, `self.v`.
27742777
unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), end - start) }
27752778
}
27762779
}
@@ -2803,9 +2806,9 @@ impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T> {
28032806
let offset_from_end = (len - 1 - n) * self.chunk_size;
28042807
let end = self.v.len() - offset_from_end;
28052808
let start = end.saturating_sub(self.chunk_size);
2806-
// SAFETY: This type ensures that any split_at_mut on self.v is valid.
2809+
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
28072810
let (tmp, tail) = unsafe { self.v.split_at_mut(end) };
2808-
// SAFETY: This type ensures that any split_at_mut on self.v is valid.
2811+
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
28092812
let (_, nth_back) = unsafe { tmp.split_at_mut(start) };
28102813
self.v = tail;
28112814
// SAFETY: Nothing else points to or will point to the contents of this slice.
@@ -3018,11 +3021,12 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksExact<'a, T> {
30183021
#[stable(feature = "rchunks", since = "1.31.0")]
30193022
#[must_use = "iterators are lazy and do nothing unless consumed"]
30203023
pub struct RChunksExactMut<'a, T: 'a> {
3021-
// This slice pointer must point at a valid region of T with at least length v.len(). Normally,
3022-
// those requirements would mean that we could instead use a &mut [T] here, but we cannot
3023-
// because __iterator_get_unchecked needs to return &mut [T], which guarantees certain aliasing
3024-
// properties that we cannot uphold if we hold on to the full original &mut [T]. Wrapping a raw
3025-
// slice instead lets us hand out non-overlapping &mut [T] subslices of the slice we wrap.
3024+
/// # Safety
3025+
/// This slice pointer must point at a valid region of `T` with at least length `v.len()`. Normally,
3026+
/// those requirements would mean that we could instead use a `&mut [T]` here, but we cannot
3027+
/// because `__iterator_get_unchecked` needs to return `&mut [T]`, which guarantees certain aliasing
3028+
/// properties that we cannot uphold if we hold on to the full original `&mut [T]`. Wrapping a raw
3029+
/// slice instead lets us hand out non-overlapping `&mut [T]` subslices of the slice we wrap.
30263030
v: *mut [T],
30273031
rem: &'a mut [T],
30283032
chunk_size: usize,
@@ -3057,7 +3061,7 @@ impl<'a, T> Iterator for RChunksExactMut<'a, T> {
30573061
None
30583062
} else {
30593063
let len = self.v.len();
3060-
// SAFETY: This type ensures that any split_at_mut on self.v is valid.
3064+
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
30613065
let (head, tail) = unsafe { self.v.split_at_mut(len - self.chunk_size) };
30623066
self.v = head;
30633067
// SAFETY: Nothing else points to or will point to the contents of this slice.
@@ -3084,7 +3088,7 @@ impl<'a, T> Iterator for RChunksExactMut<'a, T> {
30843088
None
30853089
} else {
30863090
let len = self.v.len();
3087-
// SAFETY: This type ensures that any split_at_mut on self.v is valid.
3091+
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
30883092
let (fst, _) = unsafe { self.v.split_at_mut(len - end) };
30893093
self.v = fst;
30903094
self.next()
@@ -3099,7 +3103,7 @@ impl<'a, T> Iterator for RChunksExactMut<'a, T> {
30993103
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
31003104
let end = self.v.len() - idx * self.chunk_size;
31013105
let start = end - self.chunk_size;
3102-
// SAFETY: see comments for `RChunksMut::__iterator_get_unchecked`.
3106+
// SAFETY: see comments for `RChunksMut::__iterator_get_unchecked` and `self.v`.
31033107
unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), self.chunk_size) }
31043108
}
31053109
}
@@ -3111,7 +3115,7 @@ impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T> {
31113115
if self.v.len() < self.chunk_size {
31123116
None
31133117
} else {
3114-
// SAFETY: This type ensures that any split_at_mut on self.v is valid.
3118+
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
31153119
let (head, tail) = unsafe { self.v.split_at_mut(self.chunk_size) };
31163120
self.v = tail;
31173121
// SAFETY: Nothing else points to or will point to the contents of this slice.
@@ -3131,9 +3135,9 @@ impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T> {
31313135
let offset = (len - n) * self.chunk_size;
31323136
let start = self.v.len() - offset;
31333137
let end = start + self.chunk_size;
3134-
// SAFETY: This type ensures that any split_at_mut on self.v is valid.
3138+
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
31353139
let (tmp, tail) = unsafe { self.v.split_at_mut(end) };
3136-
// SAFETY: This type ensures that any split_at_mut on self.v is valid.
3140+
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
31373141
let (_, nth_back) = unsafe { tmp.split_at_mut(start) };
31383142
self.v = tail;
31393143
// SAFETY: Nothing else points to or will point to the contents of this slice.
@@ -3220,11 +3224,7 @@ where
32203224
let mut len = 1;
32213225
let mut iter = self.slice.windows(2);
32223226
while let Some([l, r]) = iter.next() {
3223-
if (self.predicate)(l, r) {
3224-
len += 1
3225-
} else {
3226-
break;
3227-
}
3227+
if (self.predicate)(l, r) { len += 1 } else { break }
32283228
}
32293229
let (head, tail) = self.slice.split_at(len);
32303230
self.slice = tail;
@@ -3256,11 +3256,7 @@ where
32563256
let mut len = 1;
32573257
let mut iter = self.slice.windows(2);
32583258
while let Some([l, r]) = iter.next_back() {
3259-
if (self.predicate)(l, r) {
3260-
len += 1
3261-
} else {
3262-
break;
3263-
}
3259+
if (self.predicate)(l, r) { len += 1 } else { break }
32643260
}
32653261
let (head, tail) = self.slice.split_at(self.slice.len() - len);
32663262
self.slice = head;
@@ -3315,11 +3311,7 @@ where
33153311
let mut len = 1;
33163312
let mut iter = self.slice.windows(2);
33173313
while let Some([l, r]) = iter.next() {
3318-
if (self.predicate)(l, r) {
3319-
len += 1
3320-
} else {
3321-
break;
3322-
}
3314+
if (self.predicate)(l, r) { len += 1 } else { break }
33233315
}
33243316
let slice = mem::take(&mut self.slice);
33253317
let (head, tail) = slice.split_at_mut(len);
@@ -3352,11 +3344,7 @@ where
33523344
let mut len = 1;
33533345
let mut iter = self.slice.windows(2);
33543346
while let Some([l, r]) = iter.next_back() {
3355-
if (self.predicate)(l, r) {
3356-
len += 1
3357-
} else {
3358-
break;
3359-
}
3347+
if (self.predicate)(l, r) { len += 1 } else { break }
33603348
}
33613349
let slice = mem::take(&mut self.slice);
33623350
let (head, tail) = slice.split_at_mut(slice.len() - len);

0 commit comments

Comments
 (0)