Skip to content
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

Bail out early from truncate if the new length is equal to the old #74172

Closed
Closed
Show file tree
Hide file tree
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
6 changes: 3 additions & 3 deletions src/liballoc/collections/vec_deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -913,12 +913,12 @@ impl<T> VecDeque<T> {
// Safe because:
//
// * Any slice passed to `drop_in_place` is valid; the second case has
// `len <= front.len()` and returning on `len > self.len()` ensures
// `begin <= back.len()` in the first case
// `len <= front.len()` and returning on `len >= self.len()` ensures
// `begin < back.len()` in the first case
// * The head of the VecDeque is moved before calling `drop_in_place`,
// so no value is dropped twice if `drop_in_place` panics
unsafe {
if len > self.len() {
if len >= self.len() {
return;
}
let num_dropped = self.len() - len;
Expand Down
8 changes: 5 additions & 3 deletions src/liballoc/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1149,10 +1149,12 @@ impl String {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn truncate(&mut self, new_len: usize) {
if new_len <= self.len() {
assert!(self.is_char_boundary(new_len));
self.vec.truncate(new_len)
if new_len >= self.len() {
return;
}

assert!(self.is_char_boundary(new_len));
self.vec.truncate(new_len)
}

/// Removes the last character from the string buffer and returns it.
Expand Down
18 changes: 15 additions & 3 deletions src/liballoc/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -736,13 +736,13 @@ impl<T> Vec<T> {
pub fn truncate(&mut self, len: usize) {
// This is safe because:
//
// * the slice passed to `drop_in_place` is valid; the `len > self.len`
// * the slice passed to `drop_in_place` is valid; the `len >= self.len`
// case avoids creating an invalid slice, and
// * the `len` of the vector is shrunk before calling `drop_in_place`,
// such that no value will be dropped twice in case `drop_in_place`
// were to panic once (if it panics twice, the program aborts).
unsafe {
if len > self.len {
if len >= self.len {
Copy link
Contributor

Choose a reason for hiding this comment

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

@ecstatic-morse Can you please check on this? I think this also impacts resize where it runs truncate even though the length is the same. CC @lzutao

pub fn resize(&mut self, new_len: usize, value: T) {
    let len = self.len();

    if new_len > len {
        self.extend_with(new_len - len, ExtendElement(value))
    } else {
        self.truncate(new_len); // truncate run the rest of the code even though the length is same
    }
}

Copy link
Contributor Author

@ecstatic-morse ecstatic-morse Aug 29, 2020

Choose a reason for hiding this comment

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

@pickfire What would you like me to do exactly? This PR was closed because the reviewer wouldn't sign off on it. Talk to them.

Copy link
Contributor

Choose a reason for hiding this comment

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

@ecstatic-morse The reviewer is leaving the team already. See the message on zulip.

Copy link
Contributor Author

@ecstatic-morse ecstatic-morse Aug 30, 2020

Choose a reason for hiding this comment

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

That's too bad. Still, I don't see what you want from me. While I think this PR was fine as-is and was held to an unusually high standard during the review process, stepping away from the project does not invalidate one's opinion. If you can find someone with r+ rights who feels strongly that some version of these changes should be merged, then I guess we can reopen this, but I'm not going to try to cherry pick a reviewer.

return;
}
let remaining_len = self.len - len;
Expand Down Expand Up @@ -1375,7 +1375,19 @@ impl<T> Vec<T> {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn clear(&mut self) {
self.truncate(0)
let elems: *mut [T] = self.as_mut_slice();

// SAFETY:
//
// * `elems` comes directly from `as_mut_slice` and is therefore valid.
//
// * Setting `self.len = 0` before calling `drop_in_place` means that, if an element's
// `Drop` impl panics, the vector's `Drop` impl will do nothing (leaking the rest of
// the elements) instead of dropping some twice.
unsafe {
self.len = 0;
ptr::drop_in_place(elems);
}
}

/// Returns the number of elements in the vector, also referred to
Expand Down