Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 6 additions & 12 deletions library/core/src/slice/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2495,19 +2495,13 @@ impl<'a, T> Iterator for RChunksMut<'a, T> {
&& end < self.v.len()
{
let end = self.v.len() - end;
let start = match end.checked_sub(self.chunk_size) {
Some(sum) => sum,
None => 0,
};
// SAFETY: This type ensures that self.v is a valid pointer with a correct len.
// Therefore the bounds check in split_at_mut guarantees the split point is inbounds.
let (head, tail) = unsafe { self.v.split_at_mut(start) };
// SAFETY: This type ensures that self.v is a valid pointer with a correct len.
// Therefore the bounds check in split_at_mut guarantees the split point is inbounds.
let (nth, _) = unsafe { tail.split_at_mut(end - start) };
self.v = head;
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you change this line? It's not "cleanup" and it's also now wrong, because the contract is on self, not self.v.

(It makes it seem like you did this with AI without actually looking at the diff.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No AI was involved.

I'm not sure I agree that this is wrong (or that it would be correct with self instead of self.v). The call to split_at_mut only puts a requirement on self.v; if self.v.len() is correct, then any split_at_mut call is safe. This could even become split_at_mut_unchecked since it is always in bounds due to let end = self.v.len() - end;

I do think the safety comment for the second call to split_at_mut is suboptimal, since the receiver is not self.v, but rest, but this problem is pre-existing.

let (rest, _) = unsafe { self.v.split_at_mut(end) };
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
let (rest, chunk) = unsafe { rest.split_at_mut(end.saturating_sub(self.chunk_size)) };
self.v = rest;
// SAFETY: Nothing else points to or will point to the contents of this slice.
Some(unsafe { &mut *nth })
Some(unsafe { &mut *chunk })
} else {
self.v = &mut [];
None
Expand Down
Loading