Skip to content

Commit 269eff8

Browse files
StableDeref trait into core
1 parent dde8cfa commit 269eff8

File tree

4 files changed

+48
-0
lines changed

4 files changed

+48
-0
lines changed

compiler/rustc_hir/src/lang_items.rs

+1
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ language_item_table! {
220220
DerefPure, sym::deref_pure, deref_pure_trait, Target::Trait, GenericRequirement::Exact(0);
221221
DerefTarget, sym::deref_target, deref_target, Target::AssocTy, GenericRequirement::None;
222222
Receiver, sym::receiver, receiver_trait, Target::Trait, GenericRequirement::None;
223+
StableDeref, sym::stable_deref, stable_deref_trait, Target::Trait, GenericRequirement::Exact(0);
223224

224225
Fn, kw::Fn, fn_trait, Target::Trait, GenericRequirement::Exact(1);
225226
FnMut, sym::fn_mut, fn_mut_trait, Target::Trait, GenericRequirement::Exact(1);

compiler/rustc_span/src/symbol.rs

+2
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ symbols! {
302302
SliceIter,
303303
Some,
304304
SpanCtxt,
305+
StableDeref,
305306
String,
306307
StructuralPartialEq,
307308
SubdiagMessage,
@@ -1767,6 +1768,7 @@ symbols! {
17671768
sse,
17681769
sse4a_target_feature,
17691770
stable,
1771+
stable_deref,
17701772
staged_api,
17711773
start,
17721774
state,

library/core/src/ops/deref.rs

+23
Original file line numberDiff line numberDiff line change
@@ -309,3 +309,26 @@ impl<T: ?Sized> Receiver for &T {}
309309

310310
#[unstable(feature = "receiver_trait", issue = "none")]
311311
impl<T: ?Sized> Receiver for &mut T {}
312+
313+
#[cfg(not(bootstrap))]
314+
#[lang = "stable_deref"]
315+
#[unstable(feature = "stable_deref_trait", issue = "123430")]
316+
/// # Safety
317+
///
318+
/// Any two calls to `deref` must return the same value at the same address unless
319+
/// `self` has been modified in the meantime. Moves and unsizing coercions of `self`
320+
/// are not considered modifications.
321+
///
322+
/// Here, "same value" means that if `deref` returns a trait object, then the actual
323+
/// type behind that trait object must not change. Additionally, when you unsize
324+
/// coerce from `Self` to `Unsized`, then if you call `deref` on `Unsized` and get a
325+
/// trait object, then the underlying type of that trait object must be `<Self as
326+
/// Deref>::Target`.
327+
///
328+
/// Analogous requirements apply to other unsized types. E.g., if `deref` returns
329+
/// `[T]`, then the length must not change. In other words, the underlying type
330+
/// must not change from `[T; N]` to `[T; M]`.
331+
///
332+
/// If this type implements `DerefMut`, then the same restrictions apply to calls
333+
/// to `deref_mut`.
334+
pub unsafe trait StableDeref: Deref {}

library/core/src/pin.rs

+22
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,8 @@
923923
use crate::cmp;
924924
use crate::fmt;
925925
use crate::hash::{Hash, Hasher};
926+
#[cfg(not(bootstrap))]
927+
use crate::ops::StableDeref;
926928
use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, Receiver};
927929

928930
#[allow(unused_imports)]
@@ -1716,12 +1718,32 @@ impl<Ptr: fmt::Pointer> fmt::Pointer for Pin<Ptr> {
17161718
// `Deref<Target=Unpin>` is unsound. Any such impl would probably be unsound
17171719
// for other reasons, though, so we just need to take care not to allow such
17181720
// impls to land in std.
1721+
#[cfg(bootstrap)]
17191722
#[stable(feature = "pin", since = "1.33.0")]
17201723
impl<Ptr, U> CoerceUnsized<Pin<U>> for Pin<Ptr> where Ptr: CoerceUnsized<U> {}
17211724

1725+
#[cfg(bootstrap)]
17221726
#[stable(feature = "pin", since = "1.33.0")]
17231727
impl<Ptr, U> DispatchFromDyn<Pin<U>> for Pin<Ptr> where Ptr: DispatchFromDyn<U> {}
17241728

1729+
#[cfg(not(bootstrap))]
1730+
#[stable(feature = "pin", since = "1.33.0")]
1731+
impl<Ptr, U> CoerceUnsized<Pin<U>> for Pin<Ptr>
1732+
where
1733+
Ptr: CoerceUnsized<U> + StableDeref,
1734+
U: StableDeref,
1735+
{
1736+
}
1737+
1738+
#[cfg(not(bootstrap))]
1739+
#[stable(feature = "pin", since = "1.33.0")]
1740+
impl<Ptr, U> DispatchFromDyn<Pin<U>> for Pin<Ptr>
1741+
where
1742+
Ptr: DispatchFromDyn<U> + StableDeref,
1743+
U: StableDeref,
1744+
{
1745+
}
1746+
17251747
/// Constructs a <code>[Pin]<[&mut] T></code>, by pinning a `value: T` locally.
17261748
///
17271749
/// Unlike [`Box::pin`], this does not create a new heap allocation. As explained

0 commit comments

Comments
 (0)