Skip to content

Commit f05f805

Browse files
committed
Auto merge of rust-lang#120196 - matthiaskrgr:rollup-id2zocf, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#120005 (Update Readme) - rust-lang#120045 (Un-hide `iter::repeat_n`) - rust-lang#120128 (Make stable_mir::with_tables sound) - rust-lang#120145 (fix: Drop guard was deallocating with the incorrect size) - rust-lang#120158 (`rustc_mir_dataflow`: Restore removed exports) - rust-lang#120167 (Capture the rationale for `-Zallow-features=` in bootstrap.py) - rust-lang#120174 (Warn users about limited review for tier 2 and 3 code) - rust-lang#120180 (Document some alternatives to `Vec::split_off`) Failed merges: - rust-lang#120171 (Fix assume and assert in jump threading) r? `@ghost` `@rustbot` modify labels: rollup
2 parents e5e916a + d47da09 commit f05f805

File tree

4 files changed

+31
-15
lines changed

4 files changed

+31
-15
lines changed

alloc/src/vec/in_place_collect.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
//! This is handled by the [`InPlaceDrop`] guard for sink items (`U`) and by
7373
//! [`vec::IntoIter::forget_allocation_drop_remaining()`] for remaining source items (`T`).
7474
//!
75-
//! If dropping any remaining source item (`T`) panics then [`InPlaceDstBufDrop`] will handle dropping
75+
//! If dropping any remaining source item (`T`) panics then [`InPlaceDstDataSrcBufDrop`] will handle dropping
7676
//! the already collected sink items (`U`) and freeing the allocation.
7777
//!
7878
//! [`vec::IntoIter::forget_allocation_drop_remaining()`]: super::IntoIter::forget_allocation_drop_remaining()
@@ -158,11 +158,12 @@ use crate::alloc::{handle_alloc_error, Global};
158158
use core::alloc::Allocator;
159159
use core::alloc::Layout;
160160
use core::iter::{InPlaceIterable, SourceIter, TrustedRandomAccessNoCoerce};
161+
use core::marker::PhantomData;
161162
use core::mem::{self, ManuallyDrop, SizedTypeProperties};
162163
use core::num::NonZeroUsize;
163164
use core::ptr::{self, NonNull};
164165

165-
use super::{InPlaceDrop, InPlaceDstBufDrop, SpecFromIter, SpecFromIterNested, Vec};
166+
use super::{InPlaceDrop, InPlaceDstDataSrcBufDrop, SpecFromIter, SpecFromIterNested, Vec};
166167

167168
const fn in_place_collectible<DEST, SRC>(
168169
step_merge: Option<NonZeroUsize>,
@@ -265,7 +266,7 @@ where
265266
);
266267
}
267268

268-
// The ownership of the allocation and the new `T` values is temporarily moved into `dst_guard`.
269+
// The ownership of the source allocation and the new `T` values is temporarily moved into `dst_guard`.
269270
// This is safe because
270271
// * `forget_allocation_drop_remaining` immediately forgets the allocation
271272
// before any panic can occur in order to avoid any double free, and then proceeds to drop
@@ -276,7 +277,8 @@ where
276277
// Note: This access to the source wouldn't be allowed by the TrustedRandomIteratorNoCoerce
277278
// contract (used by SpecInPlaceCollect below). But see the "O(1) collect" section in the
278279
// module documentation why this is ok anyway.
279-
let dst_guard = InPlaceDstBufDrop { ptr: dst_buf, len, cap: dst_cap };
280+
let dst_guard =
281+
InPlaceDstDataSrcBufDrop { ptr: dst_buf, len, src_cap, src: PhantomData::<I::Src> };
280282
src.forget_allocation_drop_remaining();
281283

282284
// Adjust the allocation if the source had a capacity in bytes that wasn't a multiple

alloc/src/vec/in_place_drop.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
use core::ptr::{self};
1+
use core::marker::PhantomData;
2+
use core::ptr::{self, drop_in_place};
23
use core::slice::{self};
34

5+
use crate::alloc::Global;
6+
use crate::raw_vec::RawVec;
7+
48
// A helper struct for in-place iteration that drops the destination slice of iteration,
59
// i.e. the head. The source slice (the tail) is dropped by IntoIter.
610
pub(super) struct InPlaceDrop<T> {
@@ -23,17 +27,23 @@ impl<T> Drop for InPlaceDrop<T> {
2327
}
2428
}
2529

26-
// A helper struct for in-place collection that drops the destination allocation and elements,
27-
// to avoid leaking them if some other destructor panics.
28-
pub(super) struct InPlaceDstBufDrop<T> {
29-
pub(super) ptr: *mut T,
30+
// A helper struct for in-place collection that drops the destination items together with
31+
// the source allocation - i.e. before the reallocation happened - to avoid leaking them
32+
// if some other destructor panics.
33+
pub(super) struct InPlaceDstDataSrcBufDrop<Src, Dest> {
34+
pub(super) ptr: *mut Dest,
3035
pub(super) len: usize,
31-
pub(super) cap: usize,
36+
pub(super) src_cap: usize,
37+
pub(super) src: PhantomData<Src>,
3238
}
3339

34-
impl<T> Drop for InPlaceDstBufDrop<T> {
40+
impl<Src, Dest> Drop for InPlaceDstDataSrcBufDrop<Src, Dest> {
3541
#[inline]
3642
fn drop(&mut self) {
37-
unsafe { super::Vec::from_raw_parts(self.ptr, self.len, self.cap) };
43+
unsafe {
44+
let _drop_allocation =
45+
RawVec::<Src>::from_raw_parts_in(self.ptr.cast::<Src>(), self.src_cap, Global);
46+
drop_in_place(core::ptr::slice_from_raw_parts_mut::<Dest>(self.ptr, self.len));
47+
};
3848
}
3949
}

alloc/src/vec/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ use self::set_len_on_drop::SetLenOnDrop;
123123
mod set_len_on_drop;
124124

125125
#[cfg(not(no_global_oom_handling))]
126-
use self::in_place_drop::{InPlaceDrop, InPlaceDstBufDrop};
126+
use self::in_place_drop::{InPlaceDrop, InPlaceDstDataSrcBufDrop};
127127

128128
#[cfg(not(no_global_oom_handling))]
129129
mod in_place_drop;
@@ -2167,6 +2167,12 @@ impl<T, A: Allocator> Vec<T, A> {
21672167
/// `[at, len)`. After the call, the original vector will be left containing
21682168
/// the elements `[0, at)` with its previous capacity unchanged.
21692169
///
2170+
/// - If you want to take ownership of the entire contents and capacity of
2171+
/// the vector, see [`mem::take`] or [`mem::replace`].
2172+
/// - If you don't need the returned vector at all, see [`Vec::truncate`].
2173+
/// - If you want to take ownership of an arbitrary subslice, or you don't
2174+
/// necessarily want to store the removed items in a vector, see [`Vec::drain`].
2175+
///
21702176
/// # Panics
21712177
///
21722178
/// Panics if `at > len`.

core/src/iter/sources/repeat_n.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ use crate::num::NonZeroUsize;
5959
/// ```
6060
#[inline]
6161
#[unstable(feature = "iter_repeat_n", issue = "104434")]
62-
#[doc(hidden)] // waiting on ACP#120 to decide whether to expose publicly
6362
pub fn repeat_n<T: Clone>(element: T, count: usize) -> RepeatN<T> {
6463
let mut element = ManuallyDrop::new(element);
6564

@@ -79,7 +78,6 @@ pub fn repeat_n<T: Clone>(element: T, count: usize) -> RepeatN<T> {
7978
/// See its documentation for more.
8079
#[derive(Clone, Debug)]
8180
#[unstable(feature = "iter_repeat_n", issue = "104434")]
82-
#[doc(hidden)] // waiting on ACP#120 to decide whether to expose publicly
8381
pub struct RepeatN<A> {
8482
count: usize,
8583
// Invariant: has been dropped iff count == 0.

0 commit comments

Comments
 (0)