@@ -1333,12 +1333,19 @@ impl<T: ?Sized> Arc<T> {
13331333 /// Constructs an `Arc<T>` from a raw pointer.
13341334 ///
13351335 /// The raw pointer must have been previously returned by a call to
1336- /// [`Arc<U>::into_raw`][into_raw] where `U` must have the same size and
1337- /// alignment as `T`. This is trivially true if `U` is `T`.
1338- /// Note that if `U` is not `T` but has the same size and alignment, this is
1339- /// basically like transmuting references of different types. See
1340- /// [`mem::transmute`][transmute] for more information on what
1341- /// restrictions apply in this case.
1336+ /// [`Arc<U>::into_raw`][into_raw] with the following requirements:
1337+ ///
1338+ /// * If `U` is sized, it must have the same size and alignment as `T`. This
1339+ /// is trivially true if `U` is `T`.
1340+ /// * If `U` is unsized, its data pointer must have the same size and
1341+ /// alignment as `T`. This is trivially true if `Arc<U>` was constructed
1342+ /// through `Arc<T>` and then converted to `Arc<U>` through an [unsized
1343+ /// coercion].
1344+ ///
1345+ /// Note that if `U` or `U`'s data pointer is not `T` but has the same size
1346+ /// and alignment, this is basically like transmuting references of
1347+ /// different types. See [`mem::transmute`][transmute] for more information
1348+ /// on what restrictions apply in this case.
13421349 ///
13431350 /// The user of `from_raw` has to make sure a specific value of `T` is only
13441351 /// dropped once.
@@ -1348,6 +1355,7 @@ impl<T: ?Sized> Arc<T> {
13481355 ///
13491356 /// [into_raw]: Arc::into_raw
13501357 /// [transmute]: core::mem::transmute
1358+ /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions
13511359 ///
13521360 /// # Examples
13531361 ///
@@ -1367,6 +1375,20 @@ impl<T: ?Sized> Arc<T> {
13671375 ///
13681376 /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
13691377 /// ```
1378+ ///
1379+ /// Convert a slice back into its original array:
1380+ ///
1381+ /// ```
1382+ /// use std::sync::Arc;
1383+ ///
1384+ /// let x: Arc<[u32]> = Arc::new([1, 2, 3]);
1385+ /// let x_ptr: *const [u32] = Arc::into_raw(x);
1386+ ///
1387+ /// unsafe {
1388+ /// let x: Arc<[u32; 3]> = Arc::from_raw(x_ptr.cast::<[u32; 3]>());
1389+ /// assert_eq!(&*x, &[1, 2, 3]);
1390+ /// }
1391+ /// ```
13701392 #[ inline]
13711393 #[ stable( feature = "rc_raw" , since = "1.17.0" ) ]
13721394 pub unsafe fn from_raw ( ptr : * const T ) -> Self {
@@ -1496,13 +1518,20 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
14961518
14971519 /// Constructs an `Arc<T, A>` from a raw pointer.
14981520 ///
1499- /// The raw pointer must have been previously returned by a call to
1500- /// [`Arc<U, A>::into_raw`][into_raw] where `U` must have the same size and
1501- /// alignment as `T`. This is trivially true if `U` is `T`.
1502- /// Note that if `U` is not `T` but has the same size and alignment, this is
1503- /// basically like transmuting references of different types. See
1504- /// [`mem::transmute`] for more information on what
1505- /// restrictions apply in this case.
1521+ /// The raw pointer must have been previously returned by a call to [`Arc<U,
1522+ /// A>::into_raw`][into_raw] with the following requirements:
1523+ ///
1524+ /// * If `U` is sized, it must have the same size and alignment as `T`. This
1525+ /// is trivially true if `U` is `T`.
1526+ /// * If `U` is unsized, its data pointer must have the same size and
1527+ /// alignment as `T`. This is trivially true if `Arc<U>` was constructed
1528+ /// through `Arc<T>` and then converted to `Arc<U>` through an [unsized
1529+ /// coercion].
1530+ ///
1531+ /// Note that if `U` or `U`'s data pointer is not `T` but has the same size
1532+ /// and alignment, this is basically like transmuting references of
1533+ /// different types. See [`mem::transmute`][transmute] for more information
1534+ /// on what restrictions apply in this case.
15061535 ///
15071536 /// The raw pointer must point to a block of memory allocated by `alloc`
15081537 ///
@@ -1513,6 +1542,8 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
15131542 /// even if the returned `Arc<T>` is never accessed.
15141543 ///
15151544 /// [into_raw]: Arc::into_raw
1545+ /// [transmute]: core::mem::transmute
1546+ /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions
15161547 ///
15171548 /// # Examples
15181549 ///
@@ -1535,6 +1566,23 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
15351566 ///
15361567 /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
15371568 /// ```
1569+ ///
1570+ /// Convert a slice back into its original array:
1571+ ///
1572+ /// ```
1573+ /// #![feature(allocator_api)]
1574+ ///
1575+ /// use std::sync::Arc;
1576+ /// use std::alloc::System;
1577+ ///
1578+ /// let x: Arc<[u32], _> = Arc::new_in([1, 2, 3], System);
1579+ /// let x_ptr: *const [u32] = Arc::into_raw(x);
1580+ ///
1581+ /// unsafe {
1582+ /// let x: Arc<[u32; 3], _> = Arc::from_raw_in(x_ptr.cast::<[u32; 3]>(), System);
1583+ /// assert_eq!(&*x, &[1, 2, 3]);
1584+ /// }
1585+ /// ```
15381586 #[ inline]
15391587 #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
15401588 pub unsafe fn from_raw_in ( ptr : * const T , alloc : A ) -> Self {
0 commit comments