Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit cf231e8

Browse files
author
The Miri Cronjob Bot
committedJun 27, 2024
Merge from rustc
2 parents 0351c53 + a8b311e commit cf231e8

File tree

23 files changed

+2762
-232
lines changed

23 files changed

+2762
-232
lines changed
 

‎alloc/src/sync/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ fn show_arc() {
396396

397397
// Make sure deriving works with Arc<T>
398398
#[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Debug, Default)]
399-
struct Foo {
399+
struct _Foo {
400400
inner: Arc<i32>,
401401
}
402402

‎core/src/default.rs

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ use crate::ascii::Char as AsciiChar;
103103
/// ```
104104
#[cfg_attr(not(test), rustc_diagnostic_item = "Default")]
105105
#[stable(feature = "rust1", since = "1.0.0")]
106+
#[cfg_attr(not(bootstrap), rustc_trivial_field_reads)]
106107
pub trait Default: Sized {
107108
/// Returns the "default value" for a type.
108109
///

‎core/src/ffi/mod.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ mod sealed_trait {
484484
all supported platforms",
485485
issue = "44930"
486486
)]
487-
pub trait VaArgSafe {}
487+
pub unsafe trait VaArgSafe {}
488488
}
489489

490490
macro_rules! impl_va_arg_safe {
@@ -494,7 +494,7 @@ macro_rules! impl_va_arg_safe {
494494
reason = "the `c_variadic` feature has not been properly tested on \
495495
all supported platforms",
496496
issue = "44930")]
497-
impl sealed_trait::VaArgSafe for $t {}
497+
unsafe impl sealed_trait::VaArgSafe for $t {}
498498
)+
499499
}
500500
}
@@ -509,14 +509,15 @@ impl_va_arg_safe! {f64}
509509
all supported platforms",
510510
issue = "44930"
511511
)]
512-
impl<T> sealed_trait::VaArgSafe for *mut T {}
512+
unsafe impl<T> sealed_trait::VaArgSafe for *mut T {}
513+
513514
#[unstable(
514515
feature = "c_variadic",
515516
reason = "the `c_variadic` feature has not been properly tested on \
516517
all supported platforms",
517518
issue = "44930"
518519
)]
519-
impl<T> sealed_trait::VaArgSafe for *const T {}
520+
unsafe impl<T> sealed_trait::VaArgSafe for *const T {}
520521

521522
#[unstable(
522523
feature = "c_variadic",

‎core/src/intrinsics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2579,7 +2579,7 @@ extern "rust-intrinsic" {
25792579
/// fn runtime() -> i32 { 1 }
25802580
/// const fn compiletime() -> i32 { 2 }
25812581
///
2582-
// // ⚠ This code violates the required equivalence of `compiletime`
2582+
/// // ⚠ This code violates the required equivalence of `compiletime`
25832583
/// // and `runtime`.
25842584
/// const_eval_select((), compiletime, runtime)
25852585
/// }

‎core/src/iter/adapters/filter.rs

+45-45
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedF
33
use crate::num::NonZero;
44
use crate::ops::Try;
55
use core::array;
6-
use core::mem::{ManuallyDrop, MaybeUninit};
6+
use core::mem::MaybeUninit;
77
use core::ops::ControlFlow;
88

99
/// An iterator that filters the elements of `iter` with `predicate`.
@@ -27,6 +27,42 @@ impl<I, P> Filter<I, P> {
2727
}
2828
}
2929

30+
impl<I, P> Filter<I, P>
31+
where
32+
I: Iterator,
33+
P: FnMut(&I::Item) -> bool,
34+
{
35+
#[inline]
36+
fn next_chunk_dropless<const N: usize>(
37+
&mut self,
38+
) -> Result<[I::Item; N], array::IntoIter<I::Item, N>> {
39+
let mut array: [MaybeUninit<I::Item>; N] = [const { MaybeUninit::uninit() }; N];
40+
let mut initialized = 0;
41+
42+
let result = self.iter.try_for_each(|element| {
43+
let idx = initialized;
44+
// branchless index update combined with unconditionally copying the value even when
45+
// it is filtered reduces branching and dependencies in the loop.
46+
initialized = idx + (self.predicate)(&element) as usize;
47+
// SAFETY: Loop conditions ensure the index is in bounds.
48+
unsafe { array.get_unchecked_mut(idx) }.write(element);
49+
50+
if initialized < N { ControlFlow::Continue(()) } else { ControlFlow::Break(()) }
51+
});
52+
53+
match result {
54+
ControlFlow::Break(()) => {
55+
// SAFETY: The loop above is only explicitly broken when the array has been fully initialized
56+
Ok(unsafe { MaybeUninit::array_assume_init(array) })
57+
}
58+
ControlFlow::Continue(()) => {
59+
// SAFETY: The range is in bounds since the loop breaks when reaching N elements.
60+
Err(unsafe { array::IntoIter::new_unchecked(array, 0..initialized) })
61+
}
62+
}
63+
}
64+
}
65+
3066
#[stable(feature = "core_impl_debug", since = "1.9.0")]
3167
impl<I: fmt::Debug, P> fmt::Debug for Filter<I, P> {
3268
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -64,52 +100,16 @@ where
64100
fn next_chunk<const N: usize>(
65101
&mut self,
66102
) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> {
67-
let mut array: [MaybeUninit<Self::Item>; N] = [const { MaybeUninit::uninit() }; N];
68-
69-
struct Guard<'a, T> {
70-
array: &'a mut [MaybeUninit<T>],
71-
initialized: usize,
72-
}
73-
74-
impl<T> Drop for Guard<'_, T> {
75-
#[inline]
76-
fn drop(&mut self) {
77-
if const { crate::mem::needs_drop::<T>() } {
78-
// SAFETY: self.initialized is always <= N, which also is the length of the array.
79-
unsafe {
80-
core::ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(
81-
self.array.get_unchecked_mut(..self.initialized),
82-
));
83-
}
84-
}
103+
// avoid codegen for the dead branch
104+
let fun = const {
105+
if crate::mem::needs_drop::<I::Item>() {
106+
array::iter_next_chunk::<I::Item, N>
107+
} else {
108+
Self::next_chunk_dropless::<N>
85109
}
86-
}
87-
88-
let mut guard = Guard { array: &mut array, initialized: 0 };
89-
90-
let result = self.iter.try_for_each(|element| {
91-
let idx = guard.initialized;
92-
guard.initialized = idx + (self.predicate)(&element) as usize;
93-
94-
// SAFETY: Loop conditions ensure the index is in bounds.
95-
unsafe { guard.array.get_unchecked_mut(idx) }.write(element);
96-
97-
if guard.initialized < N { ControlFlow::Continue(()) } else { ControlFlow::Break(()) }
98-
});
110+
};
99111

100-
let guard = ManuallyDrop::new(guard);
101-
102-
match result {
103-
ControlFlow::Break(()) => {
104-
// SAFETY: The loop above is only explicitly broken when the array has been fully initialized
105-
Ok(unsafe { MaybeUninit::array_assume_init(array) })
106-
}
107-
ControlFlow::Continue(()) => {
108-
let initialized = guard.initialized;
109-
// SAFETY: The range is in bounds since the loop breaks when reaching N elements.
110-
Err(unsafe { array::IntoIter::new_unchecked(array, 0..initialized) })
111-
}
112-
}
112+
fun(self)
113113
}
114114

115115
#[inline]
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.