-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
Fix vec_deque::Drain FIXME
#106276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix vec_deque::Drain FIXME
#106276
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1147,7 +1147,7 @@ impl<T, A: Allocator> VecDeque<T, A> { | |
| #[inline] | ||
| #[stable(feature = "deque_extras_15", since = "1.5.0")] | ||
| pub fn as_slices(&self) -> (&[T], &[T]) { | ||
| let (a_range, b_range) = self.slice_ranges(..); | ||
| let (a_range, b_range) = self.slice_ranges(.., self.len); | ||
| // SAFETY: `slice_ranges` always returns valid ranges into | ||
| // the physical buffer. | ||
| unsafe { (&*self.buffer_range(a_range), &*self.buffer_range(b_range)) } | ||
|
|
@@ -1181,7 +1181,7 @@ impl<T, A: Allocator> VecDeque<T, A> { | |
| #[inline] | ||
| #[stable(feature = "deque_extras_15", since = "1.5.0")] | ||
| pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]) { | ||
| let (a_range, b_range) = self.slice_ranges(..); | ||
| let (a_range, b_range) = self.slice_ranges(.., self.len); | ||
| // SAFETY: `slice_ranges` always returns valid ranges into | ||
| // the physical buffer. | ||
| unsafe { (&mut *self.buffer_range(a_range), &mut *self.buffer_range(b_range)) } | ||
|
|
@@ -1223,19 +1223,29 @@ impl<T, A: Allocator> VecDeque<T, A> { | |
|
|
||
| /// Given a range into the logical buffer of the deque, this function | ||
| /// return two ranges into the physical buffer that correspond to | ||
| /// the given range. | ||
| fn slice_ranges<R>(&self, range: R) -> (Range<usize>, Range<usize>) | ||
| /// the given range. The `len` parameter should usually just be `self.len`; | ||
| /// the reason it's passed explicitly is that if the deque is wrapped in | ||
| /// a `Drain`, then `self.len` is not actually the length of the deque. | ||
| /// | ||
| /// # Safety | ||
| /// | ||
| /// This function is always safe to call. For the resulting ranges to be valid | ||
| /// ranges into the physical buffer, the caller must ensure that for all possible | ||
| /// values of `range` and `len`, the result of calling `slice::range(range, ..len)` | ||
| /// represents a valid range into the logical buffer, and that all elements | ||
|
||
| /// in that range are initialized. | ||
| fn slice_ranges<R>(&self, range: R, len: usize) -> (Range<usize>, Range<usize>) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe it would be a bit clearer if this were a free function that takes
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure that'd actually simplify things. It would always be incorrect to call |
||
| where | ||
| R: RangeBounds<usize>, | ||
| { | ||
| let Range { start, end } = slice::range(range, ..self.len); | ||
| let Range { start, end } = slice::range(range, ..len); | ||
| let len = end - start; | ||
|
|
||
| if len == 0 { | ||
| (0..0, 0..0) | ||
| } else { | ||
| // `slice::range` guarantees that `start <= end <= self.len`. | ||
| // because `len != 0`, we know that `start < end`, so `start < self.len` | ||
| // because `len != 0`, we know that `start < end`, so `start < len` | ||
| // and the indexing is valid. | ||
| let wrapped_start = self.to_physical_idx(start); | ||
|
|
||
|
|
@@ -1281,7 +1291,7 @@ impl<T, A: Allocator> VecDeque<T, A> { | |
| where | ||
| R: RangeBounds<usize>, | ||
| { | ||
| let (a_range, b_range) = self.slice_ranges(range); | ||
| let (a_range, b_range) = self.slice_ranges(range, self.len); | ||
| // SAFETY: The ranges returned by `slice_ranges` | ||
| // are valid ranges into the physical buffer, so | ||
| // it's ok to pass them to `buffer_range` and | ||
|
|
@@ -1321,7 +1331,7 @@ impl<T, A: Allocator> VecDeque<T, A> { | |
| where | ||
| R: RangeBounds<usize>, | ||
| { | ||
| let (a_range, b_range) = self.slice_ranges(range); | ||
| let (a_range, b_range) = self.slice_ranges(range, self.len); | ||
| // SAFETY: The ranges returned by `slice_ranges` | ||
| // are valid ranges into the physical buffer, so | ||
| // it's ok to pass them to `buffer_range` and | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable names here could be clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you propose? Maybe something like
let remaining_range = self.idx..self.idx+self.remaining;?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe. and also that it's a logical index, not offsets into the allocation.