Skip to content

Commit fd92a87

Browse files
author
The Miri Cronjob Bot
committed
Merge ref 'b3cfb8faf84c' from rust-lang/rust
Pull recent changes from https://github.com/rust-lang/rust via Josh. Upstream ref: b3cfb8f Filtered ref: 8995aa7743caf019203bc853f27af6006705ae30 Upstream diff: rust-lang/rust@9385c64...b3cfb8f This merge was created using https://github.com/rust-lang/josh-sync.
2 parents 7b027ce + 0d0263e commit fd92a87

File tree

27 files changed

+780
-58
lines changed

27 files changed

+780
-58
lines changed

alloc/src/raw_vec/mod.rs

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -468,10 +468,6 @@ impl<A: Allocator> RawVecInner<A> {
468468
return Ok(Self::new_in(alloc, elem_layout.alignment()));
469469
}
470470

471-
if let Err(err) = alloc_guard(layout.size()) {
472-
return Err(err);
473-
}
474-
475471
let result = match init {
476472
AllocInit::Uninitialized => alloc.allocate(layout),
477473
#[cfg(not(no_global_oom_handling))]
@@ -662,7 +658,7 @@ impl<A: Allocator> RawVecInner<A> {
662658
let new_layout = layout_array(cap, elem_layout)?;
663659

664660
let ptr = finish_grow(new_layout, self.current_memory(elem_layout), &mut self.alloc)?;
665-
// SAFETY: finish_grow would have resulted in a capacity overflow if we tried to allocate more than `isize::MAX` items
661+
// SAFETY: layout_array would have resulted in a capacity overflow if we tried to allocate more than `isize::MAX` items
666662

667663
unsafe { self.set_ptr_and_cap(ptr, cap) };
668664
Ok(())
@@ -684,7 +680,7 @@ impl<A: Allocator> RawVecInner<A> {
684680
let new_layout = layout_array(cap, elem_layout)?;
685681

686682
let ptr = finish_grow(new_layout, self.current_memory(elem_layout), &mut self.alloc)?;
687-
// SAFETY: finish_grow would have resulted in a capacity overflow if we tried to allocate more than `isize::MAX` items
683+
// SAFETY: layout_array would have resulted in a capacity overflow if we tried to allocate more than `isize::MAX` items
688684
unsafe {
689685
self.set_ptr_and_cap(ptr, cap);
690686
}
@@ -771,8 +767,6 @@ fn finish_grow<A>(
771767
where
772768
A: Allocator,
773769
{
774-
alloc_guard(new_layout.size())?;
775-
776770
let memory = if let Some((ptr, old_layout)) = current_memory {
777771
debug_assert_eq!(old_layout.align(), new_layout.align());
778772
unsafe {
@@ -799,23 +793,6 @@ fn handle_error(e: TryReserveError) -> ! {
799793
}
800794
}
801795

802-
// We need to guarantee the following:
803-
// * We don't ever allocate `> isize::MAX` byte-size objects.
804-
// * We don't overflow `usize::MAX` and actually allocate too little.
805-
//
806-
// On 64-bit we just need to check for overflow since trying to allocate
807-
// `> isize::MAX` bytes will surely fail. On 32-bit and 16-bit we need to add
808-
// an extra guard for this in case we're running on a platform which can use
809-
// all 4GB in user-space, e.g., PAE or x32.
810-
#[inline]
811-
fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> {
812-
if usize::BITS < 64 && alloc_size > isize::MAX as usize {
813-
Err(CapacityOverflow.into())
814-
} else {
815-
Ok(())
816-
}
817-
}
818-
819796
#[inline]
820797
fn layout_array(cap: usize, elem_layout: Layout) -> Result<Layout, TryReserveError> {
821798
elem_layout.repeat(cap).map(|(layout, _pad)| layout).map_err(|_| CapacityOverflow.into())

core/src/array/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub use iter::IntoIter;
4848
/// assert_eq!(strings, ["Hello there!", "Hello there!"]);
4949
/// ```
5050
#[inline]
51+
#[must_use = "cloning is often expensive and is not expected to have side effects"]
5152
#[stable(feature = "array_repeat", since = "CURRENT_RUSTC_VERSION")]
5253
pub fn repeat<T: Clone, const N: usize>(val: T) -> [T; N] {
5354
from_trusted_iterator(repeat_n(val, N))

core/src/intrinsics/fallback.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,3 +148,76 @@ impl_disjoint_bitor! {
148148
u8, u16, u32, u64, u128, usize,
149149
i8, i16, i32, i64, i128, isize,
150150
}
151+
152+
#[const_trait]
153+
#[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")]
154+
pub trait FunnelShift: Copy + 'static {
155+
/// See [`super::unchecked_funnel_shl`]; we just need the trait indirection to handle
156+
/// different types since calling intrinsics with generics doesn't work.
157+
unsafe fn unchecked_funnel_shl(self, rhs: Self, shift: u32) -> Self;
158+
159+
/// See [`super::unchecked_funnel_shr`]; we just need the trait indirection to handle
160+
/// different types since calling intrinsics with generics doesn't work.
161+
unsafe fn unchecked_funnel_shr(self, rhs: Self, shift: u32) -> Self;
162+
}
163+
164+
macro_rules! impl_funnel_shifts {
165+
($($type:ident),*) => {$(
166+
#[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")]
167+
impl const FunnelShift for $type {
168+
#[cfg_attr(miri, track_caller)]
169+
#[inline]
170+
unsafe fn unchecked_funnel_shl(self, rhs: Self, shift: u32) -> Self {
171+
// This implementation is also used by Miri so we have to check the precondition.
172+
// SAFETY: this is guaranteed by the caller
173+
unsafe { super::assume(shift < $type::BITS) };
174+
if shift == 0 {
175+
self
176+
} else {
177+
// SAFETY:
178+
// - `shift < T::BITS`, which satisfies `unchecked_shl`
179+
// - this also ensures that `T::BITS - shift < T::BITS` (shift = 0 is checked
180+
// above), which satisfies `unchecked_shr`
181+
// - because the types are unsigned, the combination are disjoint bits (this is
182+
// not true if they're signed, since SHR will fill in the empty space with a
183+
// sign bit, not zero)
184+
unsafe {
185+
super::disjoint_bitor(
186+
super::unchecked_shl(self, shift),
187+
super::unchecked_shr(rhs, $type::BITS - shift),
188+
)
189+
}
190+
}
191+
}
192+
193+
#[cfg_attr(miri, track_caller)]
194+
#[inline]
195+
unsafe fn unchecked_funnel_shr(self, rhs: Self, shift: u32) -> Self {
196+
// This implementation is also used by Miri so we have to check the precondition.
197+
// SAFETY: this is guaranteed by the caller
198+
unsafe { super::assume(shift < $type::BITS) };
199+
if shift == 0 {
200+
rhs
201+
} else {
202+
// SAFETY:
203+
// - `shift < T::BITS`, which satisfies `unchecked_shr`
204+
// - this also ensures that `T::BITS - shift < T::BITS` (shift = 0 is checked
205+
// above), which satisfies `unchecked_shl`
206+
// - because the types are unsigned, the combination are disjoint bits (this is
207+
// not true if they're signed, since SHR will fill in the empty space with a
208+
// sign bit, not zero)
209+
unsafe {
210+
super::disjoint_bitor(
211+
super::unchecked_shl(self, $type::BITS - shift),
212+
super::unchecked_shr(rhs, shift),
213+
)
214+
}
215+
}
216+
}
217+
}
218+
)*};
219+
}
220+
221+
impl_funnel_shifts! {
222+
u8, u16, u32, u64, u128, usize
223+
}

core/src/intrinsics/mod.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2102,6 +2102,61 @@ pub const fn saturating_add<T: Copy>(a: T, b: T) -> T;
21022102
#[rustc_intrinsic]
21032103
pub const fn saturating_sub<T: Copy>(a: T, b: T) -> T;
21042104

2105+
/// Funnel Shift left.
2106+
///
2107+
/// Concatenates `a` and `b` (with `a` in the most significant half),
2108+
/// creating an integer twice as wide. Then shift this integer left
2109+
/// by `shift`), and extract the most significant half. If `a` and `b`
2110+
/// are the same, this is equivalent to a rotate left operation.
2111+
///
2112+
/// It is undefined behavior if `shift` is greater than or equal to the
2113+
/// bit size of `T`.
2114+
///
2115+
/// Safe versions of this intrinsic are available on the integer primitives
2116+
/// via the `funnel_shl` method. For example, [`u32::funnel_shl`].
2117+
#[rustc_intrinsic]
2118+
#[rustc_nounwind]
2119+
#[rustc_const_unstable(feature = "funnel_shifts", issue = "145686")]
2120+
#[unstable(feature = "funnel_shifts", issue = "145686")]
2121+
#[track_caller]
2122+
#[miri::intrinsic_fallback_is_spec]
2123+
pub const unsafe fn unchecked_funnel_shl<T: [const] fallback::FunnelShift>(
2124+
a: T,
2125+
b: T,
2126+
shift: u32,
2127+
) -> T {
2128+
// SAFETY: caller ensures that `shift` is in-range
2129+
unsafe { a.unchecked_funnel_shl(b, shift) }
2130+
}
2131+
2132+
/// Funnel Shift right.
2133+
///
2134+
/// Concatenates `a` and `b` (with `a` in the most significant half),
2135+
/// creating an integer twice as wide. Then shift this integer right
2136+
/// by `shift` (taken modulo the bit size of `T`), and extract the
2137+
/// least significant half. If `a` and `b` are the same, this is equivalent
2138+
/// to a rotate right operation.
2139+
///
2140+
/// It is undefined behavior if `shift` is greater than or equal to the
2141+
/// bit size of `T`.
2142+
///
2143+
/// Safer versions of this intrinsic are available on the integer primitives
2144+
/// via the `funnel_shr` method. For example, [`u32::funnel_shr`]
2145+
#[rustc_intrinsic]
2146+
#[rustc_nounwind]
2147+
#[rustc_const_unstable(feature = "funnel_shifts", issue = "145686")]
2148+
#[unstable(feature = "funnel_shifts", issue = "145686")]
2149+
#[track_caller]
2150+
#[miri::intrinsic_fallback_is_spec]
2151+
pub const unsafe fn unchecked_funnel_shr<T: [const] fallback::FunnelShift>(
2152+
a: T,
2153+
b: T,
2154+
shift: u32,
2155+
) -> T {
2156+
// SAFETY: caller ensures that `shift` is in-range
2157+
unsafe { a.unchecked_funnel_shr(b, shift) }
2158+
}
2159+
21052160
/// This is an implementation detail of [`crate::ptr::read`] and should
21062161
/// not be used anywhere else. See its comments for why this exists.
21072162
///

core/src/iter/adapters/chain.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ impl<A: Default, B: Default> Default for Chain<A, B> {
321321
///
322322
/// // take requires `Default`
323323
/// let _: Chain<_, _> = mem::take(&mut foo.0);
324+
/// ```
324325
fn default() -> Self {
325326
Chain::new(Default::default(), Default::default())
326327
}

core/src/iter/adapters/peekable.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,108 @@ impl<I: Iterator> Peekable<I> {
317317
{
318318
self.next_if(|next| next == expected)
319319
}
320+
321+
/// Consumes the next value of this iterator and applies a function `f` on it,
322+
/// returning the result if the closure returns `Ok`.
323+
///
324+
/// Otherwise if the closure returns `Err` the value is put back for the next iteration.
325+
///
326+
/// The content of the `Err` variant is typically the original value of the closure,
327+
/// but this is not required. If a different value is returned,
328+
/// the next `peek()` or `next()` call will result in this new value.
329+
/// This is similar to modifying the output of `peek_mut()`.
330+
///
331+
/// If the closure panics, the next value will always be consumed and dropped
332+
/// even if the panic is caught, because the closure never returned an `Err` value to put back.
333+
///
334+
/// # Examples
335+
///
336+
/// Parse the leading decimal number from an iterator of characters.
337+
/// ```
338+
/// #![feature(peekable_next_if_map)]
339+
/// let mut iter = "125 GOTO 10".chars().peekable();
340+
/// let mut line_num = 0_u32;
341+
/// while let Some(digit) = iter.next_if_map(|c| c.to_digit(10).ok_or(c)) {
342+
/// line_num = line_num * 10 + digit;
343+
/// }
344+
/// assert_eq!(line_num, 125);
345+
/// assert_eq!(iter.collect::<String>(), " GOTO 10");
346+
/// ```
347+
///
348+
/// Matching custom types.
349+
/// ```
350+
/// #![feature(peekable_next_if_map)]
351+
///
352+
/// #[derive(Debug, PartialEq, Eq)]
353+
/// enum Node {
354+
/// Comment(String),
355+
/// Red(String),
356+
/// Green(String),
357+
/// Blue(String),
358+
/// }
359+
///
360+
/// /// Combines all consecutive `Comment` nodes into a single one.
361+
/// fn combine_comments(nodes: Vec<Node>) -> Vec<Node> {
362+
/// let mut result = Vec::with_capacity(nodes.len());
363+
/// let mut iter = nodes.into_iter().peekable();
364+
/// let mut comment_text = None::<String>;
365+
/// loop {
366+
/// // Typically the closure in .next_if_map() matches on the input,
367+
/// // extracts the desired pattern into an `Ok`,
368+
/// // and puts the rest into an `Err`.
369+
/// while let Some(text) = iter.next_if_map(|node| match node {
370+
/// Node::Comment(text) => Ok(text),
371+
/// other => Err(other),
372+
/// }) {
373+
/// comment_text.get_or_insert_default().push_str(&text);
374+
/// }
375+
///
376+
/// if let Some(text) = comment_text.take() {
377+
/// result.push(Node::Comment(text));
378+
/// }
379+
/// if let Some(node) = iter.next() {
380+
/// result.push(node);
381+
/// } else {
382+
/// break;
383+
/// }
384+
/// }
385+
/// result
386+
/// }
387+
///# assert_eq!( // hiding the test to avoid cluttering the documentation.
388+
///# combine_comments(vec![
389+
///# Node::Comment("The".to_owned()),
390+
///# Node::Comment("Quick".to_owned()),
391+
///# Node::Comment("Brown".to_owned()),
392+
///# Node::Red("Fox".to_owned()),
393+
///# Node::Green("Jumped".to_owned()),
394+
///# Node::Comment("Over".to_owned()),
395+
///# Node::Blue("The".to_owned()),
396+
///# Node::Comment("Lazy".to_owned()),
397+
///# Node::Comment("Dog".to_owned()),
398+
///# ]),
399+
///# vec![
400+
///# Node::Comment("TheQuickBrown".to_owned()),
401+
///# Node::Red("Fox".to_owned()),
402+
///# Node::Green("Jumped".to_owned()),
403+
///# Node::Comment("Over".to_owned()),
404+
///# Node::Blue("The".to_owned()),
405+
///# Node::Comment("LazyDog".to_owned()),
406+
///# ],
407+
///# )
408+
/// ```
409+
#[unstable(feature = "peekable_next_if_map", issue = "143702")]
410+
pub fn next_if_map<R>(&mut self, f: impl FnOnce(I::Item) -> Result<R, I::Item>) -> Option<R> {
411+
let unpeek = if let Some(item) = self.next() {
412+
match f(item) {
413+
Ok(result) => return Some(result),
414+
Err(item) => Some(item),
415+
}
416+
} else {
417+
None
418+
};
419+
self.peeked = Some(unpeek);
420+
None
421+
}
320422
}
321423

322424
#[unstable(feature = "trusted_len", issue = "37572")]

core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@
156156
#![feature(f128)]
157157
#![feature(freeze_impls)]
158158
#![feature(fundamental)]
159+
#![feature(funnel_shifts)]
159160
#![feature(if_let_guard)]
160161
#![feature(intra_doc_pointers)]
161162
#![feature(intrinsics)]

core/src/num/int_macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1285,7 +1285,7 @@ macro_rules! int_impl {
12851285
///
12861286
/// ```should_panic
12871287
#[doc = concat!("let _ = ", stringify!($SelfT), "::MIN.strict_neg();")]
1288-
///
1288+
/// ```
12891289
#[stable(feature = "strict_overflow_ops", since = "CURRENT_RUSTC_VERSION")]
12901290
#[rustc_const_stable(feature = "strict_overflow_ops", since = "CURRENT_RUSTC_VERSION")]
12911291
#[must_use = "this returns the result of the operation, \

0 commit comments

Comments
 (0)