In the implementation of Arc, we find:
|
|
|
struct ArcInner<T: ?Sized> { |
|
strong: atomic::AtomicUsize, |
|
|
|
// the value usize::MAX acts as a sentinel for temporarily "locking" the |
|
// ability to upgrade weak pointers or downgrade strong ones; this is used |
|
// to avoid races in `make_mut` and `get_mut`. |
|
weak: atomic::AtomicUsize, |
|
|
|
data: T, |
|
} |
|
|
|
/// Computes the offset of the data field within ArcInner. |
|
unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> isize { |
|
// Align the unsized value to the end of the ArcInner. |
|
// Because it is ?Sized, it will always be the last field in memory. |
|
let align = align_of_val(&*ptr); |
|
let layout = Layout::new::<ArcInner<()>>(); |
|
(layout.size() + layout.padding_needed_for(align)) as isize |
|
} |
|
|
|
/// Computes the offset of the data field within ArcInner. |
|
/// |
|
/// Unlike [`data_offset`], this doesn't need the pointer, but it works only on `T: Sized`. |
|
fn data_offset_sized<T>() -> isize { |
|
let align = align_of::<T>(); |
|
let layout = Layout::new::<ArcInner<()>>(); |
|
(layout.size() + layout.padding_needed_for(align)) as isize |
|
} |
(And similarly in rc.rs with struct RcBox.)
Note the comment: Because it is ?Sized, it will always be the last field in memory.
Is this actually true, even for instantiations where T happens to be Sized? Does the language guarantee that there exist no type Foo such that the fields of ArcInner<Foo> would be re-ordered?
Or do we need to add #[repr(C)] to ArcInner and RcBox?
CC @rust-lang/wg-unsafe-code-guidelines
In the implementation of
Arc, we find:rust/src/liballoc/sync.rs
Lines 258 to 269 in 09ab31b
rust/src/liballoc/sync.rs
Lines 2288 to 2304 in 09ab31b
(And similarly in
rc.rswithstruct RcBox.)Note the comment:
Because it is ?Sized, it will always be the last field in memory.Is this actually true, even for instantiations where
Thappens to beSized? Does the language guarantee that there exist no typeFoosuch that the fields ofArcInner<Foo>would be re-ordered?Or do we need to add
#[repr(C)]toArcInnerandRcBox?CC @rust-lang/wg-unsafe-code-guidelines