From 89d9674390d366f9b8a4bdec6ed871a41aec8bb4 Mon Sep 17 00:00:00 2001 From: Khashayar Fereidani Date: Thu, 20 Aug 2026 23:30:37 +0330 Subject: [PATCH 1/3] Rename drop guard to PanicGuard to match other definition of `retain_mut` --- library/alloc/src/vec/mod.rs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 94b21334c120c..81760f6d9721f 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2702,7 +2702,7 @@ impl Vec { } /* INVARIANT: vec.len() > read > write > write-1 >= 0 */ - struct FillGapOnDrop<'a, T, A: core::alloc::Allocator> { + struct PanicGuard<'a, T, A: core::alloc::Allocator> { /* Offset of the element we want to check if it is duplicate */ read: usize, @@ -2750,31 +2750,31 @@ impl Vec { /* Drop items while going through Vec, it should be more efficient than * doing slice partition_dedup + truncate */ - // Construct gap first and then drop item to avoid memory corruption if `T::drop` panics. - let mut gap = - FillGapOnDrop { read: first_duplicate_idx + 1, write: first_duplicate_idx, vec: self }; + // Construct guard first and then drop item to avoid memory corruption if `T::drop` panics. + let mut g = + PanicGuard { read: first_duplicate_idx + 1, write: first_duplicate_idx, vec: self }; unsafe { // SAFETY: we checked that first_duplicate_idx in bounds before. - // If drop panics, `gap` would remove this item without drop. + // If drop panics, `g` would remove this item without drop. ptr::drop_in_place(start.add(first_duplicate_idx)); } /* SAFETY: Because of the invariant, read_ptr, prev_ptr and write_ptr * are always in-bounds and read_ptr never aliases prev_ptr */ unsafe { - while gap.read < len { - let read_ptr = start.add(gap.read); - let prev_ptr = start.add(gap.write.wrapping_sub(1)); + while g.read < len { + let read_ptr = start.add(g.read); + let prev_ptr = start.add(g.write.wrapping_sub(1)); // We explicitly say in docs that references are reversed. let found_duplicate = same_bucket(&mut *read_ptr, &mut *prev_ptr); if found_duplicate { - // Increase `gap.read` now since the drop may panic. - gap.read += 1; + // Increase `g.read` now since the drop may panic. + g.read += 1; /* We have found duplicate, drop it in-place */ ptr::drop_in_place(read_ptr); } else { - let write_ptr = start.add(gap.write); + let write_ptr = start.add(g.write); /* read_ptr cannot be equal to write_ptr because at this point * we guaranteed to skip at least one element (before loop starts). @@ -2782,16 +2782,16 @@ impl Vec { ptr::copy_nonoverlapping(read_ptr, write_ptr, 1); /* We have filled that place, so go further */ - gap.write += 1; - gap.read += 1; + g.write += 1; + g.read += 1; } } - /* Technically we could let `gap` clean up with its Drop, but + /* Technically we could let `g` clean up with its Drop, but * when `same_bucket` is guaranteed to not panic, this bloats a little * the codegen, so we just do it manually */ - gap.vec.set_len(gap.write); - mem::forget(gap); + g.vec.set_len(g.write); + mem::forget(g); } } From 274f2df783138721ee8948b1a46ae89623da59db Mon Sep 17 00:00:00 2001 From: Khashayar Fereidani Date: Thu, 20 Aug 2026 23:31:21 +0330 Subject: [PATCH 2/3] Add inline(never) for drop of PanicGuard of retain_mut --- library/alloc/src/vec/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 81760f6d9721f..fc26c5e86cae2 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2534,6 +2534,7 @@ impl Vec { impl Drop for PanicGuard<'_, T, A> { #[cold] + #[inline(never)] fn drop(&mut self) { let remaining = self.original_len - self.read; // SAFETY: Trailing unchecked items must be valid since we never touch them. From 441902821cc0445e47aacdc671a7e73d40855fdc Mon Sep 17 00:00:00 2001 From: Khashayar Fereidani Date: Thu, 20 Aug 2026 23:32:01 +0330 Subject: [PATCH 3/3] Add cold and inline(never) for drop of PanicGuard of dedup_by --- library/alloc/src/vec/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index fc26c5e86cae2..3ea3310577d07 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2715,7 +2715,9 @@ impl Vec { vec: &'a mut Vec, } - impl<'a, T, A: core::alloc::Allocator> Drop for FillGapOnDrop<'a, T, A> { + impl<'a, T, A: core::alloc::Allocator> Drop for PanicGuard<'a, T, A> { + #[cold] + #[inline(never)] fn drop(&mut self) { /* This code gets executed when `same_bucket` panics */