Skip to content

Commit 578a23c

Browse files
author
The Miri Conjob Bot
committed
Merge from rustc
2 parents 915514f + b838035 commit 578a23c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+2305
-356
lines changed

alloc/src/rc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1924,7 +1924,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
19241924

19251925
// Free the allocation without dropping its contents
19261926
let (bptr, alloc) = Box::into_raw_with_allocator(src);
1927-
let src = Box::from_raw(bptr as *mut mem::ManuallyDrop<T>);
1927+
let src = Box::from_raw_in(bptr as *mut mem::ManuallyDrop<T>, alloc.by_ref());
19281928
drop(src);
19291929

19301930
Self::from_ptr_in(ptr, alloc)

alloc/src/sync.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1869,7 +1869,7 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
18691869

18701870
// Free the allocation without dropping its contents
18711871
let (bptr, alloc) = Box::into_raw_with_allocator(src);
1872-
let src = Box::from_raw(bptr as *mut mem::ManuallyDrop<T>);
1872+
let src = Box::from_raw_in(bptr as *mut mem::ManuallyDrop<T>, alloc.by_ref());
18731873
drop(src);
18741874

18751875
Self::from_ptr_in(ptr, alloc)

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`.

alloc/tests/vec.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,10 +1166,14 @@ fn test_from_iter_partially_drained_in_place_specialization() {
11661166
#[test]
11671167
fn test_from_iter_specialization_with_iterator_adapters() {
11681168
fn assert_in_place_trait<T: InPlaceIterable>(_: &T) {}
1169-
let src: Vec<usize> = vec![0usize; 256];
1169+
let owned: Vec<usize> = vec![0usize; 256];
1170+
let refd: Vec<&usize> = owned.iter().collect();
1171+
let src: Vec<&&usize> = refd.iter().collect();
11701172
let srcptr = src.as_ptr();
11711173
let iter = src
11721174
.into_iter()
1175+
.copied()
1176+
.cloned()
11731177
.enumerate()
11741178
.map(|i| i.0 + i.1)
11751179
.zip(std::iter::repeat(1usize))
@@ -1180,7 +1184,7 @@ fn test_from_iter_specialization_with_iterator_adapters() {
11801184
assert_in_place_trait(&iter);
11811185
let sink = iter.collect::<Result<Vec<_>, _>>().unwrap();
11821186
let sinkptr = sink.as_ptr();
1183-
assert_eq!(srcptr, sinkptr as *const usize);
1187+
assert_eq!(srcptr as *const usize, sinkptr as *const usize);
11841188
}
11851189

11861190
#[test]

core/benches/iter.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,19 @@ fn bench_skip_then_zip(b: &mut Bencher) {
391391
});
392392
}
393393

394+
#[bench]
395+
fn bench_skip_trusted_random_access(b: &mut Bencher) {
396+
let v: Vec<u64> = black_box(vec![42; 10000]);
397+
let mut sink = [0; 10000];
398+
399+
b.iter(|| {
400+
for (val, idx) in v.iter().skip(8).zip(0..10000) {
401+
sink[idx] += val;
402+
}
403+
sink
404+
});
405+
}
406+
394407
#[bench]
395408
fn bench_filter_count(b: &mut Bencher) {
396409
b.iter(|| (0i64..1000000).map(black_box).filter(|x| x % 3 == 0).count())

core/src/cmp.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,8 @@ impl<T: Clone> Clone for Reverse<T> {
710710
/// [lexicographic](https://en.wikipedia.org/wiki/Lexicographic_order) ordering
711711
/// based on the top-to-bottom declaration order of the struct's members.
712712
///
713-
/// When `derive`d on enums, variants are ordered by their discriminants.
713+
/// When `derive`d on enums, variants are ordered primarily by their discriminants.
714+
/// Secondarily, they are ordered by their fields.
714715
/// By default, the discriminant is smallest for variants at the top, and
715716
/// largest for variants at the bottom. Here's an example:
716717
///
@@ -963,7 +964,8 @@ pub macro Ord($item:item) {
963964
/// [lexicographic](https://en.wikipedia.org/wiki/Lexicographic_order) ordering
964965
/// based on the top-to-bottom declaration order of the struct's members.
965966
///
966-
/// When `derive`d on enums, variants are ordered by their discriminants.
967+
/// When `derive`d on enums, variants are primarily ordered by their discriminants.
968+
/// Secondarily, they are ordered by their fields.
967969
/// By default, the discriminant is smallest for variants at the top, and
968970
/// largest for variants at the bottom. Here's an example:
969971
///

core/src/iter/adapters/cloned.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use crate::iter::adapters::{
2-
zip::try_get_unchecked, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
2+
zip::try_get_unchecked, SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
33
};
4-
use crate::iter::{FusedIterator, TrustedLen, UncheckedIterator};
4+
use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen, UncheckedIterator};
55
use crate::ops::Try;
6+
use core::num::NonZeroUsize;
67

78
/// An iterator that clones the elements of an underlying iterator.
89
///
@@ -167,3 +168,23 @@ impl<I: Default> Default for Cloned<I> {
167168
Self::new(Default::default())
168169
}
169170
}
171+
172+
#[unstable(issue = "none", feature = "inplace_iteration")]
173+
unsafe impl<I> SourceIter for Cloned<I>
174+
where
175+
I: SourceIter,
176+
{
177+
type Source = I::Source;
178+
179+
#[inline]
180+
unsafe fn as_inner(&mut self) -> &mut I::Source {
181+
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
182+
unsafe { SourceIter::as_inner(&mut self.it) }
183+
}
184+
}
185+
186+
#[unstable(issue = "none", feature = "inplace_iteration")]
187+
unsafe impl<I: InPlaceIterable> InPlaceIterable for Cloned<I> {
188+
const EXPAND_BY: Option<NonZeroUsize> = I::EXPAND_BY;
189+
const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
190+
}

core/src/iter/adapters/copied.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::iter::adapters::{
2-
zip::try_get_unchecked, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
2+
zip::try_get_unchecked, SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
33
};
4-
use crate::iter::{FusedIterator, TrustedLen};
4+
use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
55
use crate::mem::MaybeUninit;
66
use crate::mem::SizedTypeProperties;
77
use crate::num::NonZeroUsize;
@@ -255,3 +255,23 @@ impl<I: Default> Default for Copied<I> {
255255
Self::new(Default::default())
256256
}
257257
}
258+
259+
#[unstable(issue = "none", feature = "inplace_iteration")]
260+
unsafe impl<I> SourceIter for Copied<I>
261+
where
262+
I: SourceIter,
263+
{
264+
type Source = I::Source;
265+
266+
#[inline]
267+
unsafe fn as_inner(&mut self) -> &mut I::Source {
268+
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
269+
unsafe { SourceIter::as_inner(&mut self.it) }
270+
}
271+
}
272+
273+
#[unstable(issue = "none", feature = "inplace_iteration")]
274+
unsafe impl<I: InPlaceIterable> InPlaceIterable for Copied<I> {
275+
const EXPAND_BY: Option<NonZeroUsize> = I::EXPAND_BY;
276+
const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
277+
}

0 commit comments

Comments
 (0)