Skip to content

Commit 55680e4

Browse files
authored
Rollup merge of #70766 - tspiteri:forget-to-ManuallyDrop, r=Mark-Simulacrum,RalfJung
use ManuallyDrop instead of forget inside collections This PR changes some usage of `mem::forget` into `mem::ManuallyDrop` in some `Vec`, `VecDeque`, `BTreeMap` and `Box` methods. Before the commit, the generated IR for some of the methods was longer, and even after optimization, some unwinding artifacts were still present.
2 parents d0e10c7 + 2b718e8 commit 55680e4

File tree

5 files changed

+34
-38
lines changed

5 files changed

+34
-38
lines changed

src/liballoc/boxed.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -469,8 +469,8 @@ impl<T: ?Sized> Box<T> {
469469
#[inline]
470470
#[doc(hidden)]
471471
pub fn into_unique(b: Box<T>) -> Unique<T> {
472+
let b = mem::ManuallyDrop::new(b);
472473
let mut unique = b.0;
473-
mem::forget(b);
474474
// Box is kind-of a library type, but recognized as a "unique pointer" by
475475
// Stacked Borrows. This function here corresponds to "reborrowing to
476476
// a raw pointer", but there is no actual reborrow here -- so

src/liballoc/collections/btree/map.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ use core::fmt::Debug;
44
use core::hash::{Hash, Hasher};
55
use core::iter::{FromIterator, FusedIterator, Peekable};
66
use core::marker::PhantomData;
7+
use core::mem::{self, ManuallyDrop};
78
use core::ops::Bound::{Excluded, Included, Unbounded};
89
use core::ops::{Index, RangeBounds};
9-
use core::{fmt, mem, ptr};
10+
use core::{fmt, ptr};
1011

1112
use super::node::{self, marker, ForceResult::*, Handle, InsertResult::*, NodeRef};
1213
use super::search::{self, SearchResult::*};
@@ -190,9 +191,9 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
190191
// We can't destructure subtree directly
191192
// because BTreeMap implements Drop
192193
let (subroot, sublength) = unsafe {
194+
let subtree = ManuallyDrop::new(subtree);
193195
let root = ptr::read(&subtree.root);
194196
let length = subtree.length;
195-
mem::forget(subtree);
196197
(root, length)
197198
};
198199

@@ -1515,15 +1516,14 @@ impl<K, V> IntoIterator for BTreeMap<K, V> {
15151516
type IntoIter = IntoIter<K, V>;
15161517

15171518
fn into_iter(self) -> IntoIter<K, V> {
1518-
if self.root.is_none() {
1519-
mem::forget(self);
1519+
let me = ManuallyDrop::new(self);
1520+
if me.root.is_none() {
15201521
return IntoIter { front: None, back: None, length: 0 };
15211522
}
15221523

1523-
let root1 = unsafe { unwrap_unchecked(ptr::read(&self.root)).into_ref() };
1524-
let root2 = unsafe { unwrap_unchecked(ptr::read(&self.root)).into_ref() };
1525-
let len = self.length;
1526-
mem::forget(self);
1524+
let root1 = unsafe { unwrap_unchecked(ptr::read(&me.root)).into_ref() };
1525+
let root2 = unsafe { unwrap_unchecked(ptr::read(&me.root)).into_ref() };
1526+
let len = me.length;
15271527

15281528
IntoIter {
15291529
front: Some(root1.first_leaf_edge()),

src/liballoc/collections/vec_deque.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use core::cmp::{self, Ordering};
1212
use core::fmt;
1313
use core::hash::{Hash, Hasher};
1414
use core::iter::{once, repeat_with, FromIterator, FusedIterator};
15-
use core::mem::{self, replace};
15+
use core::mem::{self, replace, ManuallyDrop};
1616
use core::ops::Bound::{Excluded, Included, Unbounded};
1717
use core::ops::{Index, IndexMut, RangeBounds, Try};
1818
use core::ptr::{self, NonNull};
@@ -2898,12 +2898,12 @@ impl<T> From<Vec<T>> for VecDeque<T> {
28982898
/// This avoids reallocating where possible, but the conditions for that are
28992899
/// strict, and subject to change, and so shouldn't be relied upon unless the
29002900
/// `Vec<T>` came from `From<VecDeque<T>>` and hasn't been reallocated.
2901-
fn from(mut other: Vec<T>) -> Self {
2901+
fn from(other: Vec<T>) -> Self {
29022902
unsafe {
2903+
let mut other = ManuallyDrop::new(other);
29032904
let other_buf = other.as_mut_ptr();
29042905
let mut buf = RawVec::from_raw_parts(other_buf, other.capacity());
29052906
let len = other.len();
2906-
mem::forget(other);
29072907

29082908
// We need to extend the buf if it's not a power of two, too small
29092909
// or doesn't have at least one free space
@@ -2955,16 +2955,15 @@ impl<T> From<VecDeque<T>> for Vec<T> {
29552955
other.make_contiguous();
29562956

29572957
unsafe {
2958+
let other = ManuallyDrop::new(other);
29582959
let buf = other.buf.ptr();
29592960
let len = other.len();
29602961
let cap = other.cap();
29612962

29622963
if other.head != 0 {
29632964
ptr::copy(buf.add(other.tail), buf, len);
29642965
}
2965-
let out = Vec::from_raw_parts(buf, len, cap);
2966-
mem::forget(other);
2967-
out
2966+
Vec::from_raw_parts(buf, len, cap)
29682967
}
29692968
}
29702969
}

src/liballoc/raw_vec.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
use core::alloc::MemoryBlock;
55
use core::cmp;
6-
use core::mem::{self, MaybeUninit};
6+
use core::mem::{self, ManuallyDrop, MaybeUninit};
77
use core::ops::Drop;
88
use core::ptr::{NonNull, Unique};
99
use core::slice;
@@ -112,11 +112,10 @@ impl<T> RawVec<T, Global> {
112112
}
113113

114114
/// Converts a `Box<[T]>` into a `RawVec<T>`.
115-
pub fn from_box(mut slice: Box<[T]>) -> Self {
115+
pub fn from_box(slice: Box<[T]>) -> Self {
116116
unsafe {
117-
let result = RawVec::from_raw_parts(slice.as_mut_ptr(), slice.len());
118-
mem::forget(slice);
119-
result
117+
let mut slice = ManuallyDrop::new(slice);
118+
RawVec::from_raw_parts(slice.as_mut_ptr(), slice.len())
120119
}
121120
}
122121
}
@@ -579,11 +578,10 @@ impl<T> RawVec<T, Global> {
579578
"`len` must be smaller than or equal to `self.capacity()`"
580579
);
581580

581+
let me = ManuallyDrop::new(self);
582582
// NOTE: not calling `capacity()` here; actually using the real `cap` field!
583-
let slice = slice::from_raw_parts_mut(self.ptr() as *mut MaybeUninit<T>, len);
584-
let output = Box::from_raw(slice);
585-
mem::forget(self);
586-
output
583+
let slice = slice::from_raw_parts_mut(me.ptr() as *mut MaybeUninit<T>, len);
584+
Box::from_raw(slice)
587585
}
588586
}
589587

src/liballoc/vec.rs

+13-14
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ use core::hash::{self, Hash};
6666
use core::intrinsics::{arith_offset, assume};
6767
use core::iter::{FromIterator, FusedIterator, TrustedLen};
6868
use core::marker::PhantomData;
69-
use core::mem;
69+
use core::mem::{self, ManuallyDrop};
7070
use core::ops::Bound::{Excluded, Included, Unbounded};
7171
use core::ops::{self, Index, IndexMut, RangeBounds};
7272
use core::ptr::{self, NonNull};
@@ -392,7 +392,7 @@ impl<T> Vec<T> {
392392
/// ```
393393
#[unstable(feature = "vec_into_raw_parts", reason = "new API", issue = "65816")]
394394
pub fn into_raw_parts(self) -> (*mut T, usize, usize) {
395-
let mut me = mem::ManuallyDrop::new(self);
395+
let mut me = ManuallyDrop::new(self);
396396
(me.as_mut_ptr(), me.len(), me.capacity())
397397
}
398398

@@ -678,9 +678,9 @@ impl<T> Vec<T> {
678678
pub fn into_boxed_slice(mut self) -> Box<[T]> {
679679
unsafe {
680680
self.shrink_to_fit();
681-
let buf = ptr::read(&self.buf);
682-
let len = self.len();
683-
mem::forget(self);
681+
let me = ManuallyDrop::new(self);
682+
let buf = ptr::read(&me.buf);
683+
let len = me.len();
684684
buf.into_box(len).assume_init()
685685
}
686686
}
@@ -1949,16 +1949,16 @@ impl<T> IntoIterator for Vec<T> {
19491949
/// }
19501950
/// ```
19511951
#[inline]
1952-
fn into_iter(mut self) -> IntoIter<T> {
1952+
fn into_iter(self) -> IntoIter<T> {
19531953
unsafe {
1954-
let begin = self.as_mut_ptr();
1954+
let mut me = ManuallyDrop::new(self);
1955+
let begin = me.as_mut_ptr();
19551956
let end = if mem::size_of::<T>() == 0 {
1956-
arith_offset(begin as *const i8, self.len() as isize) as *const T
1957+
arith_offset(begin as *const i8, me.len() as isize) as *const T
19571958
} else {
1958-
begin.add(self.len()) as *const T
1959+
begin.add(me.len()) as *const T
19591960
};
1960-
let cap = self.buf.capacity();
1961-
mem::forget(self);
1961+
let cap = me.buf.capacity();
19621962
IntoIter {
19631963
buf: NonNull::new_unchecked(begin),
19641964
phantom: PhantomData,
@@ -2081,9 +2081,8 @@ impl<T> SpecExtend<T, IntoIter<T>> for Vec<T> {
20812081
// has not been advanced at all.
20822082
if iterator.buf.as_ptr() as *const _ == iterator.ptr {
20832083
unsafe {
2084-
let vec = Vec::from_raw_parts(iterator.buf.as_ptr(), iterator.len(), iterator.cap);
2085-
mem::forget(iterator);
2086-
vec
2084+
let it = ManuallyDrop::new(iterator);
2085+
Vec::from_raw_parts(it.buf.as_ptr(), it.len(), it.cap)
20872086
}
20882087
} else {
20892088
let mut vector = Vec::new();

0 commit comments

Comments
 (0)