diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index b89b03683baef..75895569c2349 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -306,6 +306,7 @@ struct RcBox { #[cfg_attr(not(test), rustc_diagnostic_item = "Rc")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_insignificant_dtor] +#[repr(transparent)] pub struct Rc { ptr: NonNull>, phantom: PhantomData>, @@ -933,6 +934,31 @@ impl Rc { Weak { ptr: this.ptr } } + /// Convert a reference to an [`Rc`] into a reference to a [`Weak`] of the same type, + /// without modifying the inner reference counts. + /// + /// # Examples + /// + /// ``` + /// #![feature(rc_as_weak)] + /// + /// use std::rc::{Rc, Weak}; + /// + /// let five: &Rc = &Rc::new(5); + /// + /// let weak_five: &Rc = Rc::as_weak(five); + /// + /// ``` + #[inline] + #[unstable(feature = "rc_as_weak", issue = "none")] + #[must_use] + pub fn as_weak<'a>(this: &'a Self) -> &'a Weak + where + T: Sized, + { + unsafe { mem::transmute::<&'a Rc, &'a Weak>(this) } + } + /// Gets the number of [`Weak`] pointers to this allocation. /// /// # Examples @@ -2143,6 +2169,7 @@ impl> ToRcSlice for I { /// /// [`upgrade`]: Weak::upgrade #[stable(feature = "rc_weak", since = "1.4.0")] +#[repr(transparent)] pub struct Weak { // This is a `NonNull` to allow optimizing the size of this type in enums, // but it is not necessarily a valid pointer. diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 4c03cc3ed158a..c9b4aad10d72d 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -232,6 +232,7 @@ macro_rules! acquire { /// [rc_examples]: crate::rc#examples #[cfg_attr(not(test), rustc_diagnostic_item = "Arc")] #[stable(feature = "rust1", since = "1.0.0")] +#[repr(transparent)] pub struct Arc { ptr: NonNull>, phantom: PhantomData>, @@ -282,6 +283,7 @@ impl Arc { /// /// [`upgrade`]: Weak::upgrade #[stable(feature = "arc_weak", since = "1.4.0")] +#[repr(transparent)] pub struct Weak { // This is a `NonNull` to allow optimizing the size of this type in enums, // but it is not necessarily a valid pointer. @@ -959,6 +961,31 @@ impl Arc { } } + /// Convert a reference to an [`Arc`] into a reference to a [`Weak`] of the same type, + /// without modifying the inner reference counts. + /// + /// # Examples + /// + /// ``` + /// #![feature(arc_as_weak)] + /// + /// use std::sync::{Arc, Weak}; + /// + /// let five: &Arc = &Arc::new(5); + /// + /// let weak_five: &Weak = Arc::as_weak(five); + /// + /// ``` + #[inline] + #[unstable(feature = "arc_as_weak", issue = "none")] + #[must_use] + pub fn as_weak<'a>(this: &'a Self) -> &'a Weak + where + T: Sized, + { + unsafe { mem::transmute::<&'a Arc, &'a Weak>(this) } + } + /// Gets the number of [`Weak`] pointers to this allocation. /// /// # Safety