File tree Expand file tree Collapse file tree 1 file changed +14
-1
lines changed
library/core/src/slice/iter Expand file tree Collapse file tree 1 file changed +14
-1
lines changed Original file line number Diff line number Diff 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 }
You can’t perform that action at this time.
0 commit comments