Skip to content

Commit 1d33db3

Browse files
committed
Only exhaust the slice iterator in vec::Drain if the items need dropping
Otherwise this simply causes advancing of the iterator with no other effects, which is unnecessary work.
1 parent b3fcb75 commit 1d33db3

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

library/alloc/src/vec/drain.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,11 @@ impl<T, A: Allocator> Drop for Drain<'_, T, A> {
121121

122122
impl<'r, 'a, T, A: Allocator> Drop for DropGuard<'r, 'a, T, A> {
123123
fn drop(&mut self) {
124-
// Continue the same loop we have below. If the loop already finished, this does
125-
// nothing.
126-
self.0.for_each(drop);
124+
if mem::needs_drop::<T>() {
125+
// Continue the same loop we have below. If the loop already finished, this does
126+
// nothing.
127+
self.0.for_each(drop);
128+
}
127129

128130
if self.0.tail_len > 0 {
129131
unsafe {
@@ -142,11 +144,13 @@ impl<T, A: Allocator> Drop for Drain<'_, T, A> {
142144
}
143145
}
144146

145-
// exhaust self first
146-
while let Some(item) = self.next() {
147-
let guard = DropGuard(self);
148-
drop(item);
149-
mem::forget(guard);
147+
// exhaust self first if dropping of the items is required
148+
if mem::needs_drop::<T>() {
149+
while let Some(item) = self.next() {
150+
let guard = DropGuard(self);
151+
drop(item);
152+
mem::forget(guard);
153+
}
150154
}
151155

152156
// Drop a `DropGuard` to move back the non-drained tail of `self`.

0 commit comments

Comments
 (0)