about summary refs log tree commit diff
path: root/src/liballoc/sync.rs
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-03-22 15:48:28 +0100
committerGitHub <noreply@github.com>2020-03-22 15:48:28 +0100
commit0bc5fc99d3e009a51aa2daa1373b1774252fb443 (patch)
treeb7d3980392c41e54b0365014241c798417106f9b /src/liballoc/sync.rs
parent94d43d656665e59abc10c7c22a3194685e7cc605 (diff)
parent586c7e3907738938db7a6730fd70d7125f5925fa (diff)
downloadrust-0bc5fc99d3e009a51aa2daa1373b1774252fb443.tar.gz
rust-0bc5fc99d3e009a51aa2daa1373b1774252fb443.zip
Rollup merge of #68099 - lukaslueg:into_raw_unsafe, r=LukasKalbertodt
Amend Rc/Arc::from_raw() docs regarding unsafety

[This](https://stackoverflow.com/questions/59671647/is-it-safe-to-clone-a-type-erased-arc-via-raw-pointer) question on SO boils down to "is it safe to `::from_raw()` a `Rc<T>`/`Arc<T>` using a dummy `T` even if `T` is never dereferenced via the new `Rc`/`Arc`?". It almost never is.

This PR amends the docs of `from_raw()` regarding this point.
Diffstat (limited to 'src/liballoc/sync.rs')
-rw-r--r--src/liballoc/sync.rs23
1 files changed, 18 insertions, 5 deletions
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index d9b54fb0b17..e8985e20256 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -287,6 +287,10 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for Weak<T> {
     }
 }
 
+// This is repr(C) to future-proof against possible field-reordering, which
+// would interfere with otherwise safe [into|from]_raw() of transmutable
+// inner types.
+#[repr(C)]
 struct ArcInner<T: ?Sized> {
     strong: atomic::AtomicUsize,
 
@@ -577,15 +581,24 @@ impl<T: ?Sized> Arc<T> {
         }
     }
 
-    /// Constructs an `Arc` from a raw pointer.
+    /// Constructs an `Arc<T>` from a raw pointer.
     ///
-    /// The raw pointer must have been previously returned by a call to a
-    /// [`Arc::into_raw`][into_raw].
+    /// The raw pointer must have been previously returned by a call to
+    /// [`Arc<U>::into_raw`][into_raw] where `U` must have the same size and
+    /// alignment as `T`. This is trivially true if `U` is `T`.
+    /// Note that if `U` is not `T` but has the same size and alignment, this is
+    /// basically like transmuting references of different types. See
+    /// [`mem::transmute`][transmute] for more information on what
+    /// restrictions apply in this case.
     ///
-    /// This function is unsafe because improper use may lead to memory problems. For example, a
-    /// double-free may occur if the function is called twice on the same raw pointer.
+    /// The user of `from_raw` has to make sure a specific value of `T` is only
+    /// dropped once.
+    ///
+    /// This function is unsafe because improper use may lead to memory unsafety,
+    /// even if the returned `Arc<T>` is never accessed.
     ///
     /// [into_raw]: struct.Arc.html#method.into_raw
+    /// [transmute]: ../../std/mem/fn.transmute.html
     ///
     /// # Examples
     ///