Skip to content

Commit f0d0915

Browse files
author
The Miri Cronjob Bot
committed
Merge ref '27050c0d15af' from rust-lang/rust
Pull recent changes from https://github.com/rust-lang/rust via Josh. Upstream ref: 27050c0 Filtered ref: 2bccf110c70c6f6ec349ede9fbf0b4cdcf77eac6 Upstream diff: rust-lang/rust@6244eff...27050c0 This merge was created using https://github.com/rust-lang/josh-sync.
2 parents 0e04ae4 + 93cf9fe commit f0d0915

File tree

10 files changed

+230
-94
lines changed

10 files changed

+230
-94
lines changed

alloc/src/borrow.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ use crate::fmt;
1616
#[cfg(not(no_global_oom_handling))]
1717
use crate::string::String;
1818

19+
// FIXME(inference): const bounds removed due to inference regressions found by crater;
20+
// see https://github.com/rust-lang/rust/issues/147964
21+
// #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
1922
#[stable(feature = "rust1", since = "1.0.0")]
20-
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
21-
impl<'a, B: ?Sized> const Borrow<B> for Cow<'a, B>
22-
where
23-
B: ToOwned,
24-
B::Owned: [const] Borrow<B>,
23+
impl<'a, B: ?Sized + ToOwned> Borrow<B> for Cow<'a, B>
24+
// where
25+
// B::Owned: [const] Borrow<B>,
2526
{
2627
fn borrow(&self) -> &B {
2728
&**self
@@ -327,11 +328,13 @@ impl<B: ?Sized + ToOwned> Cow<'_, B> {
327328
}
328329
}
329330

331+
// FIXME(inference): const bounds removed due to inference regressions found by crater;
332+
// see https://github.com/rust-lang/rust/issues/147964
333+
// #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
330334
#[stable(feature = "rust1", since = "1.0.0")]
331-
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
332-
impl<B: ?Sized + ToOwned> const Deref for Cow<'_, B>
333-
where
334-
B::Owned: [const] Borrow<B>,
335+
impl<B: ?Sized + ToOwned> Deref for Cow<'_, B>
336+
// where
337+
// B::Owned: [const] Borrow<B>,
335338
{
336339
type Target = B;
337340

@@ -441,11 +444,13 @@ where
441444
}
442445
}
443446

447+
// FIXME(inference): const bounds removed due to inference regressions found by crater;
448+
// see https://github.com/rust-lang/rust/issues/147964
449+
// #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
444450
#[stable(feature = "rust1", since = "1.0.0")]
445-
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
446-
impl<T: ?Sized + ToOwned> const AsRef<T> for Cow<'_, T>
447-
where
448-
T::Owned: [const] Borrow<T>,
451+
impl<T: ?Sized + ToOwned> AsRef<T> for Cow<'_, T>
452+
// where
453+
// T::Owned: [const] Borrow<T>,
449454
{
450455
fn as_ref(&self) -> &T {
451456
self

alloc/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
//
8686
// Library features:
8787
// tidy-alphabetical-start
88+
#![cfg_attr(not(no_global_oom_handling), feature(string_replace_in_place))]
8889
#![feature(alloc_layout_extra)]
8990
#![feature(allocator_api)]
9091
#![feature(array_into_iter_constructors)]

alloc/src/string.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2090,6 +2090,67 @@ impl String {
20902090
unsafe { self.as_mut_vec() }.splice((start, end), replace_with.bytes());
20912091
}
20922092

2093+
/// Replaces the leftmost occurrence of a pattern with another string, in-place.
2094+
///
2095+
/// This method can be preferred over [`string = string.replacen(..., 1);`][replacen],
2096+
/// as it can use the `String`'s existing capacity to prevent a reallocation if
2097+
/// sufficient space is available.
2098+
///
2099+
/// # Examples
2100+
///
2101+
/// Basic usage:
2102+
///
2103+
/// ```
2104+
/// #![feature(string_replace_in_place)]
2105+
///
2106+
/// let mut s = String::from("Test Results: ❌❌❌");
2107+
///
2108+
/// // Replace the leftmost ❌ with a ✅
2109+
/// s.replace_first('❌', "✅");
2110+
/// assert_eq!(s, "Test Results: ✅❌❌");
2111+
/// ```
2112+
///
2113+
/// [replacen]: ../../std/primitive.str.html#method.replacen
2114+
#[cfg(not(no_global_oom_handling))]
2115+
#[unstable(feature = "string_replace_in_place", issue = "147949")]
2116+
pub fn replace_first<P: Pattern>(&mut self, from: P, to: &str) {
2117+
let range = match self.match_indices(from).next() {
2118+
Some((start, match_str)) => start..start + match_str.len(),
2119+
None => return,
2120+
};
2121+
2122+
self.replace_range(range, to);
2123+
}
2124+
2125+
/// Replaces the rightmost occurrence of a pattern with another string, in-place.
2126+
///
2127+
/// # Examples
2128+
///
2129+
/// Basic usage:
2130+
///
2131+
/// ```
2132+
/// #![feature(string_replace_in_place)]
2133+
///
2134+
/// let mut s = String::from("Test Results: ❌❌❌");
2135+
///
2136+
/// // Replace the rightmost ❌ with a ✅
2137+
/// s.replace_last('❌', "✅");
2138+
/// assert_eq!(s, "Test Results: ❌❌✅");
2139+
/// ```
2140+
#[cfg(not(no_global_oom_handling))]
2141+
#[unstable(feature = "string_replace_in_place", issue = "147949")]
2142+
pub fn replace_last<P: Pattern>(&mut self, from: P, to: &str)
2143+
where
2144+
for<'a> P::Searcher<'a>: core::str::pattern::ReverseSearcher<'a>,
2145+
{
2146+
let range = match self.rmatch_indices(from).next() {
2147+
Some((start, match_str)) => start..start + match_str.len(),
2148+
None => return,
2149+
};
2150+
2151+
self.replace_range(range, to);
2152+
}
2153+
20932154
/// Converts this `String` into a <code>[Box]<[str]></code>.
20942155
///
20952156
/// Before doing the conversion, this method discards excess capacity like [`shrink_to_fit`].

alloctests/tests/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#![feature(local_waker)]
3737
#![feature(str_as_str)]
3838
#![feature(strict_provenance_lints)]
39+
#![feature(string_replace_in_place)]
3940
#![feature(vec_deque_pop_if)]
4041
#![feature(vec_deque_truncate_front)]
4142
#![feature(unique_rc_arc)]

alloctests/tests/string.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,40 @@ fn test_replace_range_evil_end_bound() {
719719
assert_eq!(Ok(""), str::from_utf8(s.as_bytes()));
720720
}
721721

722+
#[test]
723+
fn test_replace_first() {
724+
let mut s = String::from("~ First ❌ Middle ❌ Last ❌ ~");
725+
s.replace_first("❌", "✅✅");
726+
assert_eq!(s, "~ First ✅✅ Middle ❌ Last ❌ ~");
727+
s.replace_first("🦀", "😳");
728+
assert_eq!(s, "~ First ✅✅ Middle ❌ Last ❌ ~");
729+
730+
let mut s = String::from("❌");
731+
s.replace_first('❌', "✅✅");
732+
assert_eq!(s, "✅✅");
733+
734+
let mut s = String::from("");
735+
s.replace_first('🌌', "❌");
736+
assert_eq!(s, "");
737+
}
738+
739+
#[test]
740+
fn test_replace_last() {
741+
let mut s = String::from("~ First ❌ Middle ❌ Last ❌ ~");
742+
s.replace_last("❌", "✅✅");
743+
assert_eq!(s, "~ First ❌ Middle ❌ Last ✅✅ ~");
744+
s.replace_last("🦀", "😳");
745+
assert_eq!(s, "~ First ❌ Middle ❌ Last ✅✅ ~");
746+
747+
let mut s = String::from("❌");
748+
s.replace_last::<char>('❌', "✅✅");
749+
assert_eq!(s, "✅✅");
750+
751+
let mut s = String::from("");
752+
s.replace_last::<char>('🌌', "❌");
753+
assert_eq!(s, "");
754+
}
755+
722756
#[test]
723757
fn test_extend_ref() {
724758
let mut a = "foo".to_string();

core/src/mem/maybe_uninit.rs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,89 @@ use crate::{fmt, intrinsics, ptr, slice};
253253
/// std::process::exit(*code); // UB! Accessing uninitialized memory.
254254
/// }
255255
/// ```
256+
///
257+
/// # Validity
258+
///
259+
/// `MaybeUninit<T>` has no validity requirements –- any sequence of [bytes] of
260+
/// the appropriate length, initialized or uninitialized, are a valid
261+
/// representation.
262+
///
263+
/// Moving or copying a value of type `MaybeUninit<T>` (i.e., performing a
264+
/// "typed copy") will exactly preserve the contents, including the
265+
/// [provenance], of all non-padding bytes of type `T` in the value's
266+
/// representation.
267+
///
268+
/// Therefore `MaybeUninit` can be used to perform a round trip of a value from
269+
/// type `T` to type `MaybeUninit<U>` then back to type `T`, while preserving
270+
/// the original value, if two conditions are met. One, type `U` must have the
271+
/// same size as type `T`. Two, for all byte offsets where type `U` has padding,
272+
/// the corresponding bytes in the representation of the value must be
273+
/// uninitialized.
274+
///
275+
/// For example, due to the fact that the type `[u8; size_of::<T>]` has no
276+
/// padding, the following is sound for any type `T` and will return the
277+
/// original value:
278+
///
279+
/// ```rust,no_run
280+
/// # use core::mem::{MaybeUninit, transmute};
281+
/// # struct T;
282+
/// fn identity(t: T) -> T {
283+
/// unsafe {
284+
/// let u: MaybeUninit<[u8; size_of::<T>()]> = transmute(t);
285+
/// transmute(u) // OK.
286+
/// }
287+
/// }
288+
/// ```
289+
///
290+
/// Note: Copying a value that contains references may implicitly reborrow them
291+
/// causing the provenance of the returned value to differ from that of the
292+
/// original. This applies equally to the trivial identity function:
293+
///
294+
/// ```rust,no_run
295+
/// fn trivial_identity<T>(t: T) -> T { t }
296+
/// ```
297+
///
298+
/// Note: Moving or copying a value whose representation has initialized bytes
299+
/// at byte offsets where the type has padding may lose the value of those
300+
/// bytes, so while the original value will be preserved, the original
301+
/// *representation* of that value as bytes may not be. Again, this applies
302+
/// equally to `trivial_identity`.
303+
///
304+
/// Note: Performing this round trip when type `U` has padding at byte offsets
305+
/// where the representation of the original value has initialized bytes may
306+
/// produce undefined behavior or a different value. For example, the following
307+
/// is unsound since `T` requires all bytes to be initialized:
308+
///
309+
/// ```rust,no_run
310+
/// # use core::mem::{MaybeUninit, transmute};
311+
/// #[repr(C)] struct T([u8; 4]);
312+
/// #[repr(C)] struct U(u8, u16);
313+
/// fn unsound_identity(t: T) -> T {
314+
/// unsafe {
315+
/// let u: MaybeUninit<U> = transmute(t);
316+
/// transmute(u) // UB.
317+
/// }
318+
/// }
319+
/// ```
320+
///
321+
/// Conversely, the following is sound since `T` allows uninitialized bytes in
322+
/// the representation of a value, but the round trip may alter the value:
323+
///
324+
/// ```rust,no_run
325+
/// # use core::mem::{MaybeUninit, transmute};
326+
/// #[repr(C)] struct T(MaybeUninit<[u8; 4]>);
327+
/// #[repr(C)] struct U(u8, u16);
328+
/// fn non_identity(t: T) -> T {
329+
/// unsafe {
330+
/// // May lose an initialized byte.
331+
/// let u: MaybeUninit<U> = transmute(t);
332+
/// transmute(u)
333+
/// }
334+
/// }
335+
/// ```
336+
///
337+
/// [bytes]: ../../reference/memory-model.html#bytes
338+
/// [provenance]: crate::ptr#provenance
256339
#[stable(feature = "maybe_uninit", since = "1.36.0")]
257340
// Lang item so we can wrap other types in it. This is useful for coroutines.
258341
#[lang = "maybe_uninit"]

core/src/mem/mod.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ pub fn forget_unsized<T: ?Sized>(t: T) {
333333
#[rustc_const_stable(feature = "const_mem_size_of", since = "1.24.0")]
334334
#[rustc_diagnostic_item = "mem_size_of"]
335335
pub const fn size_of<T>() -> usize {
336-
intrinsics::size_of::<T>()
336+
<T as SizedTypeProperties>::SIZE
337337
}
338338

339339
/// Returns the size of the pointed-to value in bytes.
@@ -441,7 +441,7 @@ pub const unsafe fn size_of_val_raw<T: ?Sized>(val: *const T) -> usize {
441441
#[stable(feature = "rust1", since = "1.0.0")]
442442
#[deprecated(note = "use `align_of` instead", since = "1.2.0", suggestion = "align_of")]
443443
pub fn min_align_of<T>() -> usize {
444-
intrinsics::align_of::<T>()
444+
<T as SizedTypeProperties>::ALIGN
445445
}
446446

447447
/// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to in
@@ -488,7 +488,7 @@ pub fn min_align_of_val<T: ?Sized>(val: &T) -> usize {
488488
#[rustc_const_stable(feature = "const_align_of", since = "1.24.0")]
489489
#[rustc_diagnostic_item = "mem_align_of"]
490490
pub const fn align_of<T>() -> usize {
491-
intrinsics::align_of::<T>()
491+
<T as SizedTypeProperties>::ALIGN
492492
}
493493

494494
/// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to in
@@ -1236,6 +1236,16 @@ pub const fn variant_count<T>() -> usize {
12361236
#[doc(hidden)]
12371237
#[unstable(feature = "sized_type_properties", issue = "none")]
12381238
pub trait SizedTypeProperties: Sized {
1239+
#[doc(hidden)]
1240+
#[unstable(feature = "sized_type_properties", issue = "none")]
1241+
#[lang = "mem_size_const"]
1242+
const SIZE: usize = intrinsics::size_of::<Self>();
1243+
1244+
#[doc(hidden)]
1245+
#[unstable(feature = "sized_type_properties", issue = "none")]
1246+
#[lang = "mem_align_const"]
1247+
const ALIGN: usize = intrinsics::align_of::<Self>();
1248+
12391249
/// `true` if this type requires no storage.
12401250
/// `false` if its [size](size_of) is greater than zero.
12411251
///
@@ -1263,7 +1273,7 @@ pub trait SizedTypeProperties: Sized {
12631273
/// ```
12641274
#[doc(hidden)]
12651275
#[unstable(feature = "sized_type_properties", issue = "none")]
1266-
const IS_ZST: bool = size_of::<Self>() == 0;
1276+
const IS_ZST: bool = Self::SIZE == 0;
12671277

12681278
#[doc(hidden)]
12691279
#[unstable(feature = "sized_type_properties", issue = "none")]
@@ -1275,7 +1285,7 @@ pub trait SizedTypeProperties: Sized {
12751285
/// which is never allowed for a single object.
12761286
#[doc(hidden)]
12771287
#[unstable(feature = "sized_type_properties", issue = "none")]
1278-
const MAX_SLICE_LEN: usize = match size_of::<Self>() {
1288+
const MAX_SLICE_LEN: usize = match Self::SIZE {
12791289
0 => usize::MAX,
12801290
n => (isize::MAX as usize) / n,
12811291
};

std/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,6 @@
290290
#![feature(ffi_const)]
291291
#![feature(formatting_options)]
292292
#![feature(funnel_shifts)]
293-
#![feature(hash_map_internals)]
294-
#![feature(hash_map_macro)]
295293
#![feature(if_let_guard)]
296294
#![feature(intra_doc_pointers)]
297295
#![feature(iter_advance_by)]

0 commit comments

Comments
 (0)