@@ -270,6 +270,68 @@ impl<T> Arc<T> {
270270 Ok ( elem)
271271 }
272272 }
273+
274+ /// Consumes the `Arc`, returning the wrapped pointer.
275+ ///
276+ /// To avoid a memory leak the pointer must be converted back to an `Arc` using
277+ /// [`Arc::from_raw`][from_raw].
278+ ///
279+ /// [from_raw]: struct.Arc.html#method.from_raw
280+ ///
281+ /// # Examples
282+ ///
283+ /// ```
284+ /// #![feature(rc_raw)]
285+ ///
286+ /// use std::sync::Arc;
287+ ///
288+ /// let x = Arc::new(10);
289+ /// let x_ptr = Arc::into_raw(x);
290+ /// assert_eq!(unsafe { *x_ptr }, 10);
291+ /// ```
292+ #[ unstable( feature = "rc_raw" , issue = "37197" ) ]
293+ pub fn into_raw ( this : Self ) -> * mut T {
294+ let ptr = unsafe { & mut ( * * this. ptr ) . data as * mut _ } ;
295+ mem:: forget ( this) ;
296+ ptr
297+ }
298+
299+ /// Constructs an `Arc` from a raw pointer.
300+ ///
301+ /// The raw pointer must have been previously returned by a call to a
302+ /// [`Arc::into_raw`][into_raw].
303+ ///
304+ /// This function is unsafe because improper use may lead to memory problems. For example, a
305+ /// double-free may occur if the function is called twice on the same raw pointer.
306+ ///
307+ /// [into_raw]: struct.Arc.html#method.into_raw
308+ ///
309+ /// # Examples
310+ ///
311+ /// ```
312+ /// #![feature(rc_raw)]
313+ ///
314+ /// use std::sync::Arc;
315+ ///
316+ /// let x = Arc::new(10);
317+ /// let x_ptr = Arc::into_raw(x);
318+ ///
319+ /// unsafe {
320+ /// // Convert back to an `Arc` to prevent leak.
321+ /// let x = Arc::from_raw(x_ptr);
322+ /// assert_eq!(*x, 10);
323+ ///
324+ /// // Further calls to `Arc::from_raw(x_ptr)` would be memory unsafe.
325+ /// }
326+ ///
327+ /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
328+ /// ```
329+ #[ unstable( feature = "rc_raw" , issue = "37197" ) ]
330+ pub unsafe fn from_raw ( ptr : * mut T ) -> Self {
331+ // To find the corresponding pointer to the `ArcInner` we need to subtract the offset of the
332+ // `data` field from the pointer.
333+ Arc { ptr : Shared :: new ( ( ptr as * mut u8 ) . offset ( -offset_of ! ( ArcInner <T >, data) ) as * mut _ ) }
334+ }
273335}
274336
275337impl < T : ?Sized > Arc < T > {
@@ -1179,6 +1241,23 @@ mod tests {
11791241 assert_eq ! ( Arc :: try_unwrap( x) , Ok ( 5 ) ) ;
11801242 }
11811243
1244+ #[ test]
1245+ fn into_from_raw ( ) {
1246+ let x = Arc :: new ( box "hello" ) ;
1247+ let y = x. clone ( ) ;
1248+
1249+ let x_ptr = Arc :: into_raw ( x) ;
1250+ drop ( y) ;
1251+ unsafe {
1252+ assert_eq ! ( * * x_ptr, "hello" ) ;
1253+
1254+ let x = Arc :: from_raw ( x_ptr) ;
1255+ assert_eq ! ( * * x, "hello" ) ;
1256+
1257+ assert_eq ! ( Arc :: try_unwrap( x) . map( |x| * x) , Ok ( "hello" ) ) ;
1258+ }
1259+ }
1260+
11821261 #[ test]
11831262 fn test_cowarc_clone_make_mut ( ) {
11841263 let mut cow0 = Arc :: new ( 75 ) ;
0 commit comments