From 77f8779ba34e7819ed3bb86a63a1580116dc180e Mon Sep 17 00:00:00 2001 From: Xiangfei Ding Date: Mon, 13 May 2024 03:16:31 +0800 Subject: [PATCH] StableDeref trait into core --- compiler/rustc_span/src/symbol.rs | 1 + library/alloc/src/boxed.rs | 6 +++++- library/alloc/src/ffi/c_str.rs | 3 +++ library/alloc/src/lib.rs | 1 + library/alloc/src/rc.rs | 10 +++++++++- library/alloc/src/string.rs | 3 +++ library/alloc/src/sync.rs | 5 ++++- library/alloc/src/vec/mod.rs | 3 +++ library/core/src/ops/deref.rs | 21 +++++++++++++++++++++ library/core/src/ops/mod.rs | 3 +++ library/core/src/pin.rs | 27 ++++++++++++++++++++++++--- 11 files changed, 77 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index d41059e8c24a4..be018cc51adc9 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -302,6 +302,7 @@ symbols! { SliceIter, Some, SpanCtxt, + StableDeref, String, StructuralPartialEq, SubdiagMessage, diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index e5d62447eb20e..baaf698252b10 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -161,7 +161,8 @@ use core::marker::Unsize; use core::mem::{self, SizedTypeProperties}; use core::ops::{AsyncFn, AsyncFnMut, AsyncFnOnce}; use core::ops::{ - CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut, DerefPure, DispatchFromDyn, Receiver, + CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut, DerefPure, DispatchFromDyn, + Receiver, StableDeref, }; use core::pin::Pin; use core::ptr::{self, addr_of_mut, NonNull, Unique}; @@ -2505,3 +2506,6 @@ impl core::error::Error for Box { core::error::Error::provide(&**self, request); } } + +#[unstable(feature = "stable_deref_trait", issue = "123430")] +unsafe impl StableDeref for Box {} diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index f143e5578717f..841faeb60e1d5 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -718,6 +718,9 @@ impl ops::Deref for CString { } } +#[unstable(feature = "stable_deref_trait", issue = "123430")] +unsafe impl ops::StableDeref for CString {} + #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for CString { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 91b83cfe011f2..6ede610b1c930 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -149,6 +149,7 @@ #![feature(slice_index_methods)] #![feature(slice_ptr_get)] #![feature(slice_range)] +#![feature(stable_deref_trait)] #![feature(std_internals)] #![feature(str_internals)] #![feature(strict_provenance)] diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 45b205356758f..2381ab88f5abe 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -260,7 +260,9 @@ use core::marker::{PhantomData, Unsize}; #[cfg(not(no_global_oom_handling))] use core::mem::size_of_val; use core::mem::{self, align_of_val_raw, forget, ManuallyDrop}; -use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, Receiver}; +use core::ops::{ + CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, Receiver, StableDeref, +}; use core::panic::{RefUnwindSafe, UnwindSafe}; #[cfg(not(no_global_oom_handling))] use core::pin::Pin; @@ -2127,6 +2129,9 @@ impl Deref for Rc { } } +#[unstable(feature = "stable_deref_trait", issue = "123430")] +unsafe impl StableDeref for Rc {} + #[unstable(feature = "deref_pure_trait", issue = "87121")] unsafe impl DerefPure for Rc {} @@ -3572,6 +3577,9 @@ impl Deref for UniqueRc { } } +#[unstable(feature = "stable_deref_trait", issue = "123430")] +unsafe impl StableDeref for UniqueRc {} + #[unstable(feature = "unique_rc_arc", issue = "112566")] impl DerefMut for UniqueRc { fn deref_mut(&mut self) -> &mut T { diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 2a859ad55eed2..1d712477a15e3 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -2481,6 +2481,9 @@ impl ops::Deref for String { } } +#[unstable(feature = "stable_deref_trait", issue = "123430")] +unsafe impl ops::StableDeref for String {} + #[unstable(feature = "deref_pure_trait", issue = "87121")] unsafe impl ops::DerefPure for String {} diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index a35c99849b343..dbd226dfa77c8 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -21,7 +21,7 @@ use core::marker::{PhantomData, Unsize}; #[cfg(not(no_global_oom_handling))] use core::mem::size_of_val; use core::mem::{self, align_of_val_raw}; -use core::ops::{CoerceUnsized, Deref, DerefPure, DispatchFromDyn, Receiver}; +use core::ops::{CoerceUnsized, Deref, DerefPure, DispatchFromDyn, Receiver, StableDeref}; use core::panic::{RefUnwindSafe, UnwindSafe}; use core::pin::Pin; use core::ptr::{self, NonNull}; @@ -2115,6 +2115,9 @@ impl Deref for Arc { } } +#[unstable(feature = "stable_deref_trait", issue = "123430")] +unsafe impl StableDeref for Arc {} + #[unstable(feature = "deref_pure_trait", issue = "87121")] unsafe impl DerefPure for Arc {} diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index b2e22d8715a8b..d9aa1e39f824c 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2818,6 +2818,9 @@ impl ops::Deref for Vec { } } +#[unstable(feature = "stable_deref_trait", issue = "123430")] +unsafe impl ops::StableDeref for Vec {} + #[stable(feature = "rust1", since = "1.0.0")] impl ops::DerefMut for Vec { #[inline] diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs index 9849410d484ca..d4eb4d4c062be 100644 --- a/library/core/src/ops/deref.rs +++ b/library/core/src/ops/deref.rs @@ -309,3 +309,24 @@ impl Receiver for &T {} #[unstable(feature = "receiver_trait", issue = "none")] impl Receiver for &mut T {} + +#[unstable(feature = "stable_deref_trait", issue = "123430")] +/// # Safety +/// +/// Any two calls to `deref` must return the same value at the same address unless +/// `self` has been modified in the meantime. Moves and unsizing coercions of `self` +/// are not considered modifications. +/// +/// Here, "same value" means that if `deref` returns a trait object, then the actual +/// type behind that trait object must not change. Additionally, when you unsize +/// coerce from `Self` to `Unsized`, then if you call `deref` on `Unsized` and get a +/// trait object, then the underlying type of that trait object must be `::Target`. +/// +/// Analogous requirements apply to other unsized types. E.g., if `deref` returns +/// `[T]`, then the length must not change. In other words, the underlying type +/// must not change from `[T; N]` to `[T; M]`. +/// +/// If this type implements `DerefMut`, then the same restrictions apply to calls +/// to `deref_mut`. +pub unsafe trait StableDeref: Deref {} diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs index 7bcfaadbe372b..a3e5412b2310f 100644 --- a/library/core/src/ops/mod.rs +++ b/library/core/src/ops/mod.rs @@ -171,6 +171,9 @@ pub use self::deref::DerefPure; #[unstable(feature = "receiver_trait", issue = "none")] pub use self::deref::Receiver; +#[unstable(feature = "stable_deref_trait", issue = "123430")] +pub use self::deref::StableDeref; + #[stable(feature = "rust1", since = "1.0.0")] pub use self::drop::Drop; diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index d8fc3b7177f38..af0fa80326694 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -923,7 +923,9 @@ use crate::cmp; use crate::fmt; use crate::hash::{Hash, Hasher}; -use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, Receiver}; +use crate::ops::{ + CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, Receiver, StableDeref, +}; #[allow(unused_imports)] use crate::{ @@ -1717,10 +1719,29 @@ impl fmt::Pointer for Pin { // for other reasons, though, so we just need to take care not to allow such // impls to land in std. #[stable(feature = "pin", since = "1.33.0")] -impl CoerceUnsized> for Pin where Ptr: CoerceUnsized {} +impl CoerceUnsized> for Pin +where + Ptr: CoerceUnsized + StableDeref, + U: StableDeref, +{ +} + +#[stable(feature = "pin", since = "1.33.0")] +impl DispatchFromDyn> for Pin +where + Ptr: DispatchFromDyn + StableDeref, + U: StableDeref, +{ +} + +#[stable(feature = "pin", since = "1.33.0")] +unsafe impl<'a, T: ?Sized> StableDeref for &'a T {} + +#[stable(feature = "pin", since = "1.33.0")] +unsafe impl<'a, T: ?Sized> StableDeref for &'a mut T {} #[stable(feature = "pin", since = "1.33.0")] -impl DispatchFromDyn> for Pin where Ptr: DispatchFromDyn {} +unsafe impl StableDeref for Pin {} /// Constructs a [Pin]<[&mut] T>, by pinning a `value: T` locally. ///