Skip to content

Commit

Permalink
fn mem::transmute: Replace with sound `Arc::from_raw(Arc::into_raw(…
Browse files Browse the repository at this point in the history
……) as *const _)` (#1361)

As @Darksonn [pointed
out](#1360 (comment)),
using `mem::transmute` on an `Arc` is unsound since it's not
`#[repr(transparent)]`, and we need to go through `Arc::into_raw` and
`Arc::from_raw` with a ptr cast instead.
  • Loading branch information
kkysen authored Sep 25, 2024
2 parents b417059 + e063c90 commit acd57b1
Showing 1 changed file with 6 additions and 4 deletions.
10 changes: 6 additions & 4 deletions src/disjoint_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1195,13 +1195,15 @@ impl<T> FromIterator<T> for DisjointMutArcSlice<T> {
let arc_slice = iter.into_iter().collect::<Arc<[_]>>();

// Do our best to check that `DisjointMut` is in fact `#[repr(transparent)]`.
type A = Vec<u8>; // Some concrete sized type.
const _: () = assert!(mem::size_of::<DisjointMut<A>>() == mem::size_of::<A>());
const _: () = assert!(mem::align_of::<DisjointMut<A>>() == mem::align_of::<A>());
const {
type A = Vec<u8>; // Some concrete sized type.
assert!(mem::size_of::<DisjointMut<A>>() == mem::size_of::<A>());
assert!(mem::align_of::<DisjointMut<A>>() == mem::align_of::<A>());
}

// SAFETY: When `#[cfg(not(debug_assertions))]`, `DisjointMut` is `#[repr(transparent)]`,
// containing only an `UnsafeCell`, which is also `#[repr(transparent)]`.
unsafe { mem::transmute::<Arc<[_]>, Arc<DisjointMut<[_]>>>(arc_slice) }
unsafe { Arc::from_raw(Arc::into_raw(arc_slice) as *const DisjointMut<[_]>) }
};
Self { inner }
}
Expand Down

0 comments on commit acd57b1

Please sign in to comment.