-
Notifications
You must be signed in to change notification settings - Fork 13k
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
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 | ||
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. That is indeed a bit of a mouthful and requires one to look up with 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. Something like "all elements up to ..." wouldn't cover all our use cases, as 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 suppose we could say "all elements in the logical range 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. Also, since there's quite a few types that implement 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. Ok, but even if we keep the
What does the "for all possible values" add? Does that refer to the covered elements? Or does it just say that every time you pass in garbage you get garbage out? 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. Eh, the "for all possible values" can just be left out. I'm not sure why I put it there in the first place so I guess I'll just remove it. |
||
/// in that range are initialized. | ||
fn slice_ranges<R>(&self, range: R, len: usize) -> (Range<usize>, Range<usize>) | ||
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 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.