Skip to content

Commit 5103841

Browse files
authored
Add comments to the Invariant implementation
1 parent f9d1c17 commit 5103841

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

library/core/src/slice/iter.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,19 @@ impl<T> AsRef<[T]> for Iter<'_, T> {
162162

163163
#[unstable(feature = "ub_checks", issue = "none")]
164164
impl<T> Invariant for Iter<'_, T> {
165+
/// An iterator can be safely used if its pointer can be read for its current length.
166+
///
167+
/// If the type is a ZST or the encoded length is `0`, the only safety requirement is that
168+
/// its pointer is aligned (since zero-size access is always safe for aligned pointers),
169+
/// and that `self.ptr` value is less or equal to `self.end_or_len`.
170+
///
171+
/// For other cases, we need to ensure that it is safe to read the memory between
172+
/// `self.ptr` and `self.end_or_len`.
165173
fn is_safe(&self) -> bool {
166174
let ty_size = crate::mem::size_of::<T>();
167175
let distance = self.ptr.addr().get().abs_diff(self.end_or_len as usize);
168176
if ty_size == 0 || distance == 0 {
169-
self.ptr.is_aligned()
177+
self.ptr.is_aligned() && self.ptr.addr().get() <= self.end_or_len as usize
170178
} else {
171179
let slice_ptr: *const [T] =
172180
crate::ptr::from_raw_parts(self.ptr.as_ptr(), distance / ty_size);
@@ -219,10 +227,14 @@ pub struct IterMut<'a, T: 'a> {
219227

220228
#[unstable(feature = "ub_checks", issue = "none")]
221229
impl<T> Invariant for IterMut<'_, T> {
230+
/// This is similar to [Iter] with an extra write requirement.
231+
///
232+
/// It must be safe to write in the memory interval between `self.ptr`
233+
/// and `self.end_or_len`.
222234
fn is_safe(&self) -> bool {
223235
let size = crate::mem::size_of::<T>();
224236
if size == 0 {
225-
self.ptr.is_aligned()
237+
self.ptr.is_aligned() && self.ptr.addr().get() <= self.end_or_len as usize
226238
} else {
227239
let distance = self.ptr.addr().get().abs_diff(self.end_or_len as usize);
228240
let slice_ptr: *mut [T] =
@@ -3632,6 +3644,7 @@ mod verify {
36323644
};
36333645
}
36343646

3647+
// FIXME: Add harnesses for ZST with alignment > 1.
36353648
check_iter_with_ty!(verify_unit, (), isize::MAX as usize);
36363649
check_iter_with_ty!(verify_u8, u8, u32::MAX as usize);
36373650
check_iter_with_ty!(verify_char, char, 50);

0 commit comments

Comments
 (0)