@@ -13,7 +13,7 @@ use core::borrow;
1313use core:: fmt;
1414use core:: cmp:: { self , Ordering } ;
1515use core:: intrinsics:: abort;
16- use core:: mem:: { self , align_of_val, size_of_val} ;
16+ use core:: mem:: { self , align_of , align_of_val, size_of_val} ;
1717use core:: ops:: { Deref , Receiver , CoerceUnsized , DispatchFromDyn } ;
1818use core:: pin:: Pin ;
1919use core:: ptr:: { self , NonNull } ;
@@ -397,11 +397,7 @@ impl<T: ?Sized> Arc<T> {
397397 /// ```
398398 #[ stable( feature = "rc_raw" , since = "1.17.0" ) ]
399399 pub unsafe fn from_raw ( ptr : * const T ) -> Self {
400- // Align the unsized value to the end of the ArcInner.
401- // Because it is ?Sized, it will always be the last field in memory.
402- let align = align_of_val ( & * ptr) ;
403- let layout = Layout :: new :: < ArcInner < ( ) > > ( ) ;
404- let offset = ( layout. size ( ) + layout. padding_needed_for ( align) ) as isize ;
400+ let offset = data_offset ( ptr) ;
405401
406402 // Reverse the offset to find the original ArcInner.
407403 let fake_ptr = ptr as * mut ArcInner < T > ;
@@ -1071,6 +1067,144 @@ impl<T> Weak<T> {
10711067 ptr : NonNull :: new ( usize:: MAX as * mut ArcInner < T > ) . expect ( "MAX is not 0" ) ,
10721068 }
10731069 }
1070+
1071+ /// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
1072+ ///
1073+ /// It is up to the caller to ensure that the object is still alive when accessing it through
1074+ /// the pointer.
1075+ ///
1076+ /// The pointer may be [`null`] or be dangling in case the object has already been destroyed.
1077+ ///
1078+ /// # Examples
1079+ ///
1080+ /// ```
1081+ /// #![feature(weak_into_raw)]
1082+ ///
1083+ /// use std::sync::{Arc, Weak};
1084+ /// use std::ptr;
1085+ ///
1086+ /// let strong = Arc::new(42);
1087+ /// let weak = Arc::downgrade(&strong);
1088+ /// // Both point to the same object
1089+ /// assert!(ptr::eq(&*strong, Weak::as_raw(&weak)));
1090+ /// // The strong here keeps it alive, so we can still access the object.
1091+ /// assert_eq!(42, unsafe { *Weak::as_raw(&weak) });
1092+ ///
1093+ /// drop(strong);
1094+ /// // But not any more. We can do Weak::as_raw(&weak), but accessing the pointer would lead to
1095+ /// // undefined behaviour.
1096+ /// // assert_eq!(42, unsafe { *Weak::as_raw(&weak) });
1097+ /// ```
1098+ ///
1099+ /// [`null`]: ../../std/ptr/fn.null.html
1100+ #[ unstable( feature = "weak_into_raw" , issue = "60728" ) ]
1101+ pub fn as_raw ( this : & Self ) -> * const T {
1102+ match this. inner ( ) {
1103+ None => ptr:: null ( ) ,
1104+ Some ( inner) => {
1105+ let offset = data_offset_sized :: < T > ( ) ;
1106+ let ptr = inner as * const ArcInner < T > ;
1107+ // Note: while the pointer we create may already point to dropped value, the
1108+ // allocation still lives (it must hold the weak point as long as we are alive).
1109+ // Therefore, the offset is OK to do, it won't get out of the allocation.
1110+ let ptr = unsafe { ( ptr as * const u8 ) . offset ( offset) } ;
1111+ ptr as * const T
1112+ }
1113+ }
1114+ }
1115+
1116+ /// Consumes the `Weak<T>` and turns it into a raw pointer.
1117+ ///
1118+ /// This converts the weak pointer into a raw pointer, preserving the original weak count. It
1119+ /// can be turned back into the `Weak<T>` with [`from_raw`].
1120+ ///
1121+ /// The same restrictions of accessing the target of the pointer as with
1122+ /// [`as_raw`] apply.
1123+ ///
1124+ /// # Examples
1125+ ///
1126+ /// ```
1127+ /// #![feature(weak_into_raw)]
1128+ ///
1129+ /// use std::sync::{Arc, Weak};
1130+ ///
1131+ /// let strong = Arc::new(42);
1132+ /// let weak = Arc::downgrade(&strong);
1133+ /// let raw = Weak::into_raw(weak);
1134+ ///
1135+ /// assert_eq!(1, Arc::weak_count(&strong));
1136+ /// assert_eq!(42, unsafe { *raw });
1137+ ///
1138+ /// drop(unsafe { Weak::from_raw(raw) });
1139+ /// assert_eq!(0, Arc::weak_count(&strong));
1140+ /// ```
1141+ ///
1142+ /// [`from_raw`]: struct.Weak.html#method.from_raw
1143+ /// [`as_raw`]: struct.Weak.html#method.as_raw
1144+ #[ unstable( feature = "weak_into_raw" , issue = "60728" ) ]
1145+ pub fn into_raw ( this : Self ) -> * const T {
1146+ let result = Self :: as_raw ( & this) ;
1147+ mem:: forget ( this) ;
1148+ result
1149+ }
1150+
1151+ /// Converts a raw pointer previously created by [`into_raw`] back into
1152+ /// `Weak<T>`.
1153+ ///
1154+ /// This can be used to safely get a strong reference (by calling [`upgrade`]
1155+ /// later) or to deallocate the weak count by dropping the `Weak<T>`.
1156+ ///
1157+ /// It takes ownership of one weak count. In case a [`null`] is passed, a dangling [`Weak`] is
1158+ /// returned.
1159+ ///
1160+ /// # Safety
1161+ ///
1162+ /// The pointer must represent one valid weak count. In other words, it must point to `T` which
1163+ /// is or *was* managed by an [`Arc`] and the weak count of that [`Arc`] must not have reached
1164+ /// 0. It is allowed for the strong count to be 0.
1165+ ///
1166+ /// # Examples
1167+ ///
1168+ /// ```
1169+ /// #![feature(weak_into_raw)]
1170+ ///
1171+ /// use std::sync::{Arc, Weak};
1172+ ///
1173+ /// let strong = Arc::new(42);
1174+ ///
1175+ /// let raw_1 = Weak::into_raw(Arc::downgrade(&strong));
1176+ /// let raw_2 = Weak::into_raw(Arc::downgrade(&strong));
1177+ ///
1178+ /// assert_eq!(2, Arc::weak_count(&strong));
1179+ ///
1180+ /// assert_eq!(42, *Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap());
1181+ /// assert_eq!(1, Arc::weak_count(&strong));
1182+ ///
1183+ /// drop(strong);
1184+ ///
1185+ /// // Decrement the last weak count.
1186+ /// assert!(Weak::upgrade(&unsafe { Weak::from_raw(raw_2) }).is_none());
1187+ /// ```
1188+ ///
1189+ /// [`null`]: ../../std/ptr/fn.null.html
1190+ /// [`into_raw`]: struct.Weak.html#method.into_raw
1191+ /// [`upgrade`]: struct.Weak.html#method.upgrade
1192+ /// [`Weak`]: struct.Weak.html
1193+ /// [`Arc`]: struct.Arc.html
1194+ #[ unstable( feature = "weak_into_raw" , issue = "60728" ) ]
1195+ pub unsafe fn from_raw ( ptr : * const T ) -> Self {
1196+ if ptr. is_null ( ) {
1197+ Self :: new ( )
1198+ } else {
1199+ // See Arc::from_raw for details
1200+ let offset = data_offset ( ptr) ;
1201+ let fake_ptr = ptr as * mut ArcInner < T > ;
1202+ let ptr = set_data_ptr ( fake_ptr, ( ptr as * mut u8 ) . offset ( -offset) ) ;
1203+ Weak {
1204+ ptr : NonNull :: new ( ptr) . expect ( "Invalid pointer passed to from_raw" ) ,
1205+ }
1206+ }
1207+ }
10741208}
10751209
10761210impl < T : ?Sized > Weak < T > {
@@ -2150,3 +2284,21 @@ impl<T: ?Sized> AsRef<T> for Arc<T> {
21502284
21512285#[ stable( feature = "pin" , since = "1.33.0" ) ]
21522286impl < T : ?Sized > Unpin for Arc < T > { }
2287+
2288+ /// Computes the offset of the data field within ArcInner.
2289+ unsafe fn data_offset < T : ?Sized > ( ptr : * const T ) -> isize {
2290+ // Align the unsized value to the end of the ArcInner.
2291+ // Because it is ?Sized, it will always be the last field in memory.
2292+ let align = align_of_val ( & * ptr) ;
2293+ let layout = Layout :: new :: < ArcInner < ( ) > > ( ) ;
2294+ ( layout. size ( ) + layout. padding_needed_for ( align) ) as isize
2295+ }
2296+
2297+ /// Computes the offset of the data field within ArcInner.
2298+ ///
2299+ /// Unlike [`data_offset`], this doesn't need the pointer, but it works only on `T: Sized`.
2300+ fn data_offset_sized < T > ( ) -> isize {
2301+ let align = align_of :: < T > ( ) ;
2302+ let layout = Layout :: new :: < ArcInner < ( ) > > ( ) ;
2303+ ( layout. size ( ) + layout. padding_needed_for ( align) ) as isize
2304+ }
0 commit comments