Skip to content

Commit

Permalink
StableDeref trait into core
Browse files Browse the repository at this point in the history
  • Loading branch information
dingxiangfei2009 committed May 13, 2024
1 parent dde8cfa commit 1795d68
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 3 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ symbols! {
SliceIter,
Some,
SpanCtxt,
StableDeref,
String,
StructuralPartialEq,
SubdiagMessage,
Expand Down
5 changes: 5 additions & 0 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ use core::iter::FusedIterator;
use core::marker::Tuple;
use core::marker::Unsize;
use core::mem::{self, SizedTypeProperties};
#[unstable(feature = "stable_deref_trait", issue = "123430")]
use core::ops::StableDeref;
use core::ops::{AsyncFn, AsyncFnMut, AsyncFnOnce};
use core::ops::{
CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut, DerefPure, DispatchFromDyn, Receiver,
Expand Down Expand Up @@ -2505,3 +2507,6 @@ impl<T: core::error::Error> core::error::Error for Box<T> {
core::error::Error::provide(&**self, request);
}
}

#[unstable(feature = "stable_deref_trait", issue = "123430")]
unsafe impl<T: ?Sized, A: Allocator> StableDeref for Box<T, A> {}
1 change: 1 addition & 0 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
21 changes: 21 additions & 0 deletions library/core/src/ops/deref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,3 +309,24 @@ impl<T: ?Sized> Receiver for &T {}

#[unstable(feature = "receiver_trait", issue = "none")]
impl<T: ?Sized> 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 `<Self as
/// Deref>::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 {}
3 changes: 3 additions & 0 deletions library/core/src/ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
27 changes: 24 additions & 3 deletions library/core/src/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -1717,10 +1719,29 @@ impl<Ptr: fmt::Pointer> fmt::Pointer for Pin<Ptr> {
// 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<Ptr, U> CoerceUnsized<Pin<U>> for Pin<Ptr> where Ptr: CoerceUnsized<U> {}
impl<Ptr, U> CoerceUnsized<Pin<U>> for Pin<Ptr>
where
Ptr: CoerceUnsized<U> + StableDeref,
U: StableDeref,
{
}

#[stable(feature = "pin", since = "1.33.0")]
impl<Ptr, U> DispatchFromDyn<Pin<U>> for Pin<Ptr>
where
Ptr: DispatchFromDyn<U> + 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<Ptr, U> DispatchFromDyn<Pin<U>> for Pin<Ptr> where Ptr: DispatchFromDyn<U> {}
unsafe impl<T: StableDeref> StableDeref for Pin<T> {}

/// Constructs a <code>[Pin]<[&mut] T></code>, by pinning a `value: T` locally.
///
Expand Down

0 comments on commit 1795d68

Please sign in to comment.