Skip to content

Commit 0562ec7

Browse files
scottmcmgitbot
authored and
gitbot
committed
Add real safety comments
1 parent b1882aa commit 0562ec7

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

core/src/slice/iter/macros.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -159,20 +159,33 @@ macro_rules! iterator {
159159

160160
let ptr = self.ptr;
161161
let end_or_len = self.end_or_len;
162-
// SAFETY: Type invariants.
162+
// SAFETY: See inner comments. (For some reason having multiple
163+
// block breaks inlining this -- if you can fix that please do!)
163164
unsafe {
164165
if T::IS_ZST {
165166
let len = end_or_len.addr();
166167
if len == 0 {
167168
return None;
168169
}
170+
// SAFETY: just checked that it's not zero, so subtracting one
171+
// cannot wrap. (Ideally this would be `checked_sub`, which
172+
// does the same thing internally, but as of 2025-02 that
173+
// doesn't optimize quite as small in MIR.)
169174
self.end_or_len = without_provenance_mut(len.unchecked_sub(1));
170175
} else {
176+
// SAFETY: by type invariant, the `end_or_len` field is always
177+
// non-null for a non-ZST pointee. (This transmute ensures we
178+
// get `!nonnull` metadata on the load of the field.)
171179
if ptr == crate::intrinsics::transmute::<$ptr, NonNull<T>>(end_or_len) {
172180
return None;
173181
}
182+
// SAFETY: since it's not empty, per the check above, moving
183+
// forward one keeps us inside the slice, and this is valid.
174184
self.ptr = ptr.add(1);
175185
}
186+
// SAFETY: Now that we know it wasn't empty and we've moved past
187+
// the first one (to avoid giving a duplicate `&mut` next time),
188+
// we can give out a reference to it.
176189
Some({ptr}.$into_ref())
177190
}
178191
}

0 commit comments

Comments
 (0)