Skip to content

Commit 59844f2

Browse files
author
The Miri Cronjob Bot
committed
Merge ref '4fd31815524b' from rust-lang/rust
Pull recent changes from https://github.com/rust-lang/rust via Josh. Upstream ref: 4fd3181 Filtered ref: ee72bb093dfd84655bc02a8ee4b65327b14cecb3 Upstream diff: rust-lang/rust@3b8665c...4fd3181 This merge was created using https://github.com/rust-lang/josh-sync.
2 parents acdd130 + 5aede39 commit 59844f2

File tree

39 files changed

+1192
-706
lines changed

39 files changed

+1192
-706
lines changed

alloc/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
#![feature(bstr)]
9797
#![feature(bstr_internals)]
9898
#![feature(cast_maybe_uninit)]
99+
#![feature(cell_get_cloned)]
99100
#![feature(char_internals)]
100101
#![feature(char_max_len)]
101102
#![feature(clone_to_uninit)]

alloc/src/rc.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@
242242
#![stable(feature = "rust1", since = "1.0.0")]
243243

244244
use core::any::Any;
245-
use core::cell::Cell;
245+
use core::cell::{Cell, CloneFromCell};
246246
#[cfg(not(no_global_oom_handling))]
247247
use core::clone::CloneToUninit;
248248
use core::clone::UseCloned;
@@ -340,6 +340,10 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Rc<U, A>> for
340340
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
341341
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Rc<U>> for Rc<T> {}
342342

343+
// SAFETY: `Rc::clone` doesn't access any `Cell`s which could contain the `Rc` being cloned.
344+
#[unstable(feature = "cell_get_cloned", issue = "145329")]
345+
unsafe impl<T: ?Sized> CloneFromCell for Rc<T> {}
346+
343347
impl<T: ?Sized> Rc<T> {
344348
#[inline]
345349
unsafe fn from_inner(ptr: NonNull<RcInner<T>>) -> Self {
@@ -3013,6 +3017,10 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Weak<U, A>> f
30133017
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
30143018
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Weak<U>> for Weak<T> {}
30153019

3020+
// SAFETY: `Weak::clone` doesn't access any `Cell`s which could contain the `Weak` being cloned.
3021+
#[unstable(feature = "cell_get_cloned", issue = "145329")]
3022+
unsafe impl<T: ?Sized> CloneFromCell for Weak<T> {}
3023+
30163024
impl<T> Weak<T> {
30173025
/// Constructs a new `Weak<T>`, without allocating any memory.
30183026
/// Calling [`upgrade`] on the return value always gives [`None`].

alloc/src/sync.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
//! `#[cfg(target_has_atomic = "ptr")]`.
1010
1111
use core::any::Any;
12+
use core::cell::CloneFromCell;
1213
#[cfg(not(no_global_oom_handling))]
1314
use core::clone::CloneToUninit;
1415
use core::clone::UseCloned;
@@ -281,6 +282,10 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Arc<U, A>> fo
281282
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
282283
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Arc<U>> for Arc<T> {}
283284

285+
// SAFETY: `Arc::clone` doesn't access any `Cell`s which could contain the `Arc` being cloned.
286+
#[unstable(feature = "cell_get_cloned", issue = "145329")]
287+
unsafe impl<T: ?Sized> CloneFromCell for Arc<T> {}
288+
284289
impl<T: ?Sized> Arc<T> {
285290
unsafe fn from_inner(ptr: NonNull<ArcInner<T>>) -> Self {
286291
unsafe { Self::from_inner_in(ptr, Global) }
@@ -356,6 +361,10 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Weak<U, A>> f
356361
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
357362
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Weak<U>> for Weak<T> {}
358363

364+
// SAFETY: `Weak::clone` doesn't access any `Cell`s which could contain the `Weak` being cloned.
365+
#[unstable(feature = "cell_get_cloned", issue = "145329")]
366+
unsafe impl<T: ?Sized> CloneFromCell for Weak<T> {}
367+
359368
#[stable(feature = "arc_weak", since = "1.4.0")]
360369
impl<T: ?Sized, A: Allocator> fmt::Debug for Weak<T, A> {
361370
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

core/src/cell.rs

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,11 +253,12 @@
253253
use crate::cmp::Ordering;
254254
use crate::fmt::{self, Debug, Display};
255255
use crate::marker::{PhantomData, Unsize};
256-
use crate::mem;
257-
use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn};
256+
use crate::mem::{self, ManuallyDrop};
257+
use crate::ops::{self, CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn};
258258
use crate::panic::const_panic;
259259
use crate::pin::PinCoerceUnsized;
260260
use crate::ptr::{self, NonNull};
261+
use crate::range;
261262

262263
mod lazy;
263264
mod once;
@@ -713,6 +714,93 @@ impl<T, const N: usize> Cell<[T; N]> {
713714
}
714715
}
715716

717+
/// Types for which cloning `Cell<Self>` is sound.
718+
///
719+
/// # Safety
720+
///
721+
/// Implementing this trait for a type is sound if and only if the following code is sound for T =
722+
/// that type.
723+
///
724+
/// ```
725+
/// #![feature(cell_get_cloned)]
726+
/// # use std::cell::{CloneFromCell, Cell};
727+
/// fn clone_from_cell<T: CloneFromCell>(cell: &Cell<T>) -> T {
728+
/// unsafe { T::clone(&*cell.as_ptr()) }
729+
/// }
730+
/// ```
731+
///
732+
/// Importantly, you can't just implement `CloneFromCell` for any arbitrary `Copy` type, e.g. the
733+
/// following is unsound:
734+
///
735+
/// ```rust
736+
/// #![feature(cell_get_cloned)]
737+
/// # use std::cell::Cell;
738+
///
739+
/// #[derive(Copy, Debug)]
740+
/// pub struct Bad<'a>(Option<&'a Cell<Bad<'a>>>, u8);
741+
///
742+
/// impl Clone for Bad<'_> {
743+
/// fn clone(&self) -> Self {
744+
/// let a: &u8 = &self.1;
745+
/// // when self.0 points to self, we write to self.1 while we have a live `&u8` pointing to
746+
/// // it -- this is UB
747+
/// self.0.unwrap().set(Self(None, 1));
748+
/// dbg!((a, self));
749+
/// Self(None, 0)
750+
/// }
751+
/// }
752+
///
753+
/// // this is not sound
754+
/// // unsafe impl CloneFromCell for Bad<'_> {}
755+
/// ```
756+
#[unstable(feature = "cell_get_cloned", issue = "145329")]
757+
// Allow potential overlapping implementations in user code
758+
#[marker]
759+
pub unsafe trait CloneFromCell: Clone {}
760+
761+
// `CloneFromCell` can be implemented for types that don't have indirection and which don't access
762+
// `Cell`s in their `Clone` implementation. A commonly-used subset is covered here.
763+
#[unstable(feature = "cell_get_cloned", issue = "145329")]
764+
unsafe impl<T: CloneFromCell, const N: usize> CloneFromCell for [T; N] {}
765+
#[unstable(feature = "cell_get_cloned", issue = "145329")]
766+
unsafe impl<T: CloneFromCell> CloneFromCell for Option<T> {}
767+
#[unstable(feature = "cell_get_cloned", issue = "145329")]
768+
unsafe impl<T: CloneFromCell, E: CloneFromCell> CloneFromCell for Result<T, E> {}
769+
#[unstable(feature = "cell_get_cloned", issue = "145329")]
770+
unsafe impl<T: ?Sized> CloneFromCell for PhantomData<T> {}
771+
#[unstable(feature = "cell_get_cloned", issue = "145329")]
772+
unsafe impl<T: CloneFromCell> CloneFromCell for ManuallyDrop<T> {}
773+
#[unstable(feature = "cell_get_cloned", issue = "145329")]
774+
unsafe impl<T: CloneFromCell> CloneFromCell for ops::Range<T> {}
775+
#[unstable(feature = "cell_get_cloned", issue = "145329")]
776+
unsafe impl<T: CloneFromCell> CloneFromCell for range::Range<T> {}
777+
778+
#[unstable(feature = "cell_get_cloned", issue = "145329")]
779+
impl<T: CloneFromCell> Cell<T> {
780+
/// Get a clone of the `Cell` that contains a copy of the original value.
781+
///
782+
/// This allows a cheaply `Clone`-able type like an `Rc` to be stored in a `Cell`, exposing the
783+
/// cheaper `clone()` method.
784+
///
785+
/// # Examples
786+
///
787+
/// ```
788+
/// #![feature(cell_get_cloned)]
789+
///
790+
/// use core::cell::Cell;
791+
/// use std::rc::Rc;
792+
///
793+
/// let rc = Rc::new(1usize);
794+
/// let c1 = Cell::new(rc);
795+
/// let c2 = c1.get_cloned();
796+
/// assert_eq!(*c2.into_inner(), 1);
797+
/// ```
798+
pub fn get_cloned(&self) -> Self {
799+
// SAFETY: T is CloneFromCell, which guarantees that this is sound.
800+
Cell::new(T::clone(unsafe { &*self.as_ptr() }))
801+
}
802+
}
803+
716804
/// A mutable memory location with dynamically checked borrow rules
717805
///
718806
/// See the [module-level documentation](self) for more.

core/src/fmt/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ pub struct Error;
115115
/// [`std::io::Write`]: ../../std/io/trait.Write.html
116116
/// [flushable]: ../../std/io/trait.Write.html#tymethod.flush
117117
#[stable(feature = "rust1", since = "1.0.0")]
118+
#[rustc_diagnostic_item = "FmtWrite"]
118119
pub trait Write {
119120
/// Writes a string slice into this writer, returning whether the write
120121
/// succeeded.

core/src/macros/mod.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -951,8 +951,9 @@ pub(crate) mod builtin {
951951
/// format string in `format_args!`.
952952
///
953953
/// ```rust
954-
/// let debug = format!("{:?}", format_args!("{} foo {:?}", 1, 2));
955-
/// let display = format!("{}", format_args!("{} foo {:?}", 1, 2));
954+
/// let args = format_args!("{} foo {:?}", 1, 2);
955+
/// let debug = format!("{args:?}");
956+
/// let display = format!("{args}");
956957
/// assert_eq!("1 foo 2", display);
957958
/// assert_eq!(display, debug);
958959
/// ```
@@ -976,13 +977,17 @@ pub(crate) mod builtin {
976977
/// assert_eq!(s, format!("hello {}", "world"));
977978
/// ```
978979
///
979-
/// # Lifetime limitation
980+
/// # Argument lifetimes
980981
///
981982
/// Except when no formatting arguments are used,
982-
/// the produced `fmt::Arguments` value borrows temporary values,
983-
/// which means it can only be used within the same expression
984-
/// and cannot be stored for later use.
985-
/// This is a known limitation, see [#92698](https://github.com/rust-lang/rust/issues/92698).
983+
/// the produced `fmt::Arguments` value borrows temporary values.
984+
/// To allow it to be stored for later use, the arguments' lifetimes, as well as those of
985+
/// temporaries they borrow, may be [extended] when `format_args!` appears in the initializer
986+
/// expression of a `let` statement. The syntactic rules used to determine when temporaries'
987+
/// lifetimes are extended are documented in the [Reference].
988+
///
989+
/// [extended]: ../reference/destructors.html#temporary-lifetime-extension
990+
/// [Reference]: ../reference/destructors.html#extending-based-on-expressions
986991
#[stable(feature = "rust1", since = "1.0.0")]
987992
#[rustc_diagnostic_item = "format_args_macro"]
988993
#[allow_internal_unsafe]

core/src/mem/mod.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
use crate::alloc::Layout;
99
use crate::marker::DiscriminantKind;
10+
use crate::panic::const_assert;
1011
use crate::{clone, cmp, fmt, hash, intrinsics, ptr};
1112

1213
mod manually_drop;
@@ -1407,3 +1408,60 @@ pub macro offset_of($Container:ty, $($fields:expr)+ $(,)?) {
14071408
// The `{}` is for better error messages
14081409
{builtin # offset_of($Container, $($fields)+)}
14091410
}
1411+
1412+
/// Create a fresh instance of the inhabited ZST type `T`.
1413+
///
1414+
/// Prefer this to [`zeroed`] or [`uninitialized`] or [`transmute_copy`]
1415+
/// in places where you know that `T` is zero-sized, but don't have a bound
1416+
/// (such as [`Default`]) that would allow you to instantiate it using safe code.
1417+
///
1418+
/// If you're not sure whether `T` is an inhabited ZST, then you should be
1419+
/// using [`MaybeUninit`], not this function.
1420+
///
1421+
/// # Panics
1422+
///
1423+
/// If `size_of::<T>() != 0`.
1424+
///
1425+
/// # Safety
1426+
///
1427+
/// - `T` must be *[inhabited]*, i.e. possible to construct. This means that types
1428+
/// like zero-variant enums and [`!`] are unsound to conjure.
1429+
/// - You must use the value only in ways which do not violate any *safety*
1430+
/// invariants of the type.
1431+
///
1432+
/// While it's easy to create a *valid* instance of an inhabited ZST, since having
1433+
/// no bits in its representation means there's only one possible value, that
1434+
/// doesn't mean that it's always *sound* to do so.
1435+
///
1436+
/// For example, a library could design zero-sized tokens that are `!Default + !Clone`, limiting
1437+
/// their creation to functions that initialize some state or establish a scope. Conjuring such a
1438+
/// token could break invariants and lead to unsoundness.
1439+
///
1440+
/// # Examples
1441+
///
1442+
/// ```
1443+
/// #![feature(mem_conjure_zst)]
1444+
/// use std::mem::conjure_zst;
1445+
///
1446+
/// assert_eq!(unsafe { conjure_zst::<()>() }, ());
1447+
/// assert_eq!(unsafe { conjure_zst::<[i32; 0]>() }, []);
1448+
/// ```
1449+
///
1450+
/// [inhabited]: https://doc.rust-lang.org/reference/glossary.html#inhabited
1451+
#[unstable(feature = "mem_conjure_zst", issue = "95383")]
1452+
pub const unsafe fn conjure_zst<T>() -> T {
1453+
const_assert!(
1454+
size_of::<T>() == 0,
1455+
"mem::conjure_zst invoked on a nonzero-sized type",
1456+
"mem::conjure_zst invoked on type {t}, which is not zero-sized",
1457+
t: &str = stringify!(T)
1458+
);
1459+
1460+
// SAFETY: because the caller must guarantee that it's inhabited and zero-sized,
1461+
// there's nothing in the representation that needs to be set.
1462+
// `assume_init` calls `assert_inhabited`, so we don't need to here.
1463+
unsafe {
1464+
#[allow(clippy::uninit_assumed_init)]
1465+
MaybeUninit::uninit().assume_init()
1466+
}
1467+
}

core/src/panicking.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ use crate::panic::{Location, PanicInfo};
3535
#[cfg(feature = "panic_immediate_abort")]
3636
compile_error!(
3737
"panic_immediate_abort is now a real panic strategy! \
38-
Enable it with the compiler flags `-Zunstable-options -Cpanic=immediate-abort`"
38+
Enable it with `panic = \"immediate-abort\"` in Cargo.toml, \
39+
or with the compiler flags `-Zunstable-options -Cpanic=immediate-abort`"
3940
);
4041

4142
// First we define the two main entry points that all panics go through.

core/src/pin.rs

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1689,9 +1689,89 @@ impl<Ptr: [const] Deref> const Deref for Pin<Ptr> {
16891689
}
16901690
}
16911691

1692+
mod helper {
1693+
/// Helper that prevents downstream crates from implementing `DerefMut` for `Pin`.
1694+
///
1695+
/// The `Pin` type implements the unsafe trait `PinCoerceUnsized`, which essentially requires
1696+
/// that the type does not have a malicious `Deref` or `DerefMut` impl. However, without this
1697+
/// helper module, downstream crates are able to write `impl DerefMut for Pin<LocalType>` as
1698+
/// long as it does not overlap with the impl provided by stdlib. This is because `Pin` is
1699+
/// `#[fundamental]`, so stdlib promises to never implement traits for `Pin` that it does not
1700+
/// implement today.
1701+
///
1702+
/// However, this is problematic. Downstream crates could implement `DerefMut` for
1703+
/// `Pin<&LocalType>`, and they could do so maliciously. To prevent this, the implementation for
1704+
/// `Pin` delegates to this helper module. Since `helper::Pin` is not `#[fundamental]`, the
1705+
/// orphan rules assume that stdlib might implement `helper::DerefMut` for `helper::Pin<&_>` in
1706+
/// the future. Because of this, downstream crates can no longer provide an implementation of
1707+
/// `DerefMut` for `Pin<&_>`, as it might overlap with a trait impl that, according to the
1708+
/// orphan rules, the stdlib could introduce without a breaking change in a future release.
1709+
///
1710+
/// See <https://github.com/rust-lang/rust/issues/85099> for the issue this fixes.
1711+
#[repr(transparent)]
1712+
#[unstable(feature = "pin_derefmut_internals", issue = "none")]
1713+
#[allow(missing_debug_implementations)]
1714+
pub struct PinHelper<Ptr> {
1715+
pointer: Ptr,
1716+
}
1717+
1718+
#[unstable(feature = "pin_derefmut_internals", issue = "none")]
1719+
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
1720+
#[rustc_diagnostic_item = "PinDerefMutHelper"]
1721+
pub const trait PinDerefMutHelper {
1722+
type Target: ?Sized;
1723+
fn deref_mut(&mut self) -> &mut Self::Target;
1724+
}
1725+
1726+
#[unstable(feature = "pin_derefmut_internals", issue = "none")]
1727+
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
1728+
impl<Ptr: [const] super::DerefMut> const PinDerefMutHelper for PinHelper<Ptr>
1729+
where
1730+
Ptr::Target: crate::marker::Unpin,
1731+
{
1732+
type Target = Ptr::Target;
1733+
1734+
#[inline(always)]
1735+
fn deref_mut(&mut self) -> &mut Ptr::Target {
1736+
&mut self.pointer
1737+
}
1738+
}
1739+
}
1740+
16921741
#[stable(feature = "pin", since = "1.33.0")]
16931742
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
1694-
impl<Ptr: [const] DerefMut<Target: Unpin>> const DerefMut for Pin<Ptr> {
1743+
#[cfg(not(doc))]
1744+
impl<Ptr> const DerefMut for Pin<Ptr>
1745+
where
1746+
Ptr: [const] Deref,
1747+
helper::PinHelper<Ptr>: [const] helper::PinDerefMutHelper<Target = Self::Target>,
1748+
{
1749+
#[inline]
1750+
fn deref_mut(&mut self) -> &mut Ptr::Target {
1751+
// SAFETY: Pin and PinHelper have the same layout, so this is equivalent to
1752+
// `&mut self.pointer` which is safe because `Target: Unpin`.
1753+
helper::PinDerefMutHelper::deref_mut(unsafe {
1754+
&mut *(self as *mut Pin<Ptr> as *mut helper::PinHelper<Ptr>)
1755+
})
1756+
}
1757+
}
1758+
1759+
/// The `Target` type is restricted to `Unpin` types as it's not safe to obtain a mutable reference
1760+
/// to a pinned value.
1761+
///
1762+
/// For soundness reasons, implementations of `DerefMut` for `Pin<T>` are rejected even when `T` is
1763+
/// a local type not covered by this impl block. (Since `Pin` is [fundamental], such implementations
1764+
/// would normally be possible.)
1765+
///
1766+
/// [fundamental]: ../../reference/items/implementations.html#r-items.impl.trait.fundamental
1767+
#[stable(feature = "pin", since = "1.33.0")]
1768+
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
1769+
#[cfg(doc)]
1770+
impl<Ptr> const DerefMut for Pin<Ptr>
1771+
where
1772+
Ptr: [const] DerefMut,
1773+
<Ptr as Deref>::Target: Unpin,
1774+
{
16951775
fn deref_mut(&mut self) -> &mut Ptr::Target {
16961776
Pin::get_mut(Pin::as_mut(self))
16971777
}

0 commit comments

Comments
 (0)