Skip to content

Commit 64dab6d

Browse files
authored
Comments on, and hopefully an increase of CopyCell soundness (#7)
* Comments on, and hopefully an increase of `CopyCell` soundness * Remove `get_mut` altogether
1 parent 7b1c67f commit 64dab6d

File tree

1 file changed

+14
-11
lines changed

1 file changed

+14
-11
lines changed

src/cell.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::marker::PhantomData;
77
/// library, but always require that the internal type implements `Copy`
88
/// and implements `Copy` itself.
99
#[derive(PartialEq, Eq)]
10+
#[repr(transparent)]
1011
pub struct CopyCell<T> {
1112
/// Internal value
1213
value: T,
@@ -32,27 +33,22 @@ impl<T> CopyCell<T> {
3233
}
3334

3435
impl<T: Copy> CopyCell<T> {
35-
#[inline]
36-
fn mut_ptr(&self) -> *mut T {
37-
&self.value as *const T as *mut T
38-
}
39-
4036
/// Returns a copy of the contained value.
4137
#[inline]
4238
pub fn get(&self) -> T {
43-
unsafe {
44-
*self.mut_ptr()
45-
}
39+
self.value
4640
}
4741

4842
/// Returns a mutable reference to the underlying data.
4943
///
5044
/// This call borrows `CopyCell` mutably, which gives us a compile time
5145
/// memory safety guarantee.
5246
#[inline]
53-
pub fn get_mut(&mut self) -> &mut T {
47+
pub fn get_mut<'a>(&'a mut self) -> &'a mut T {
48+
// We can just cast the pointer from `CopyCell<T>` to `T` because of
49+
// #[repr(transparent)]
5450
unsafe {
55-
&mut *self.mut_ptr()
51+
&mut *(self as *mut CopyCell<T> as *mut T)
5652
}
5753
}
5854

@@ -64,7 +60,14 @@ impl<T: Copy> CopyCell<T> {
6460
// Regular write produces abnormal behavior when running tests in
6561
// `--release` mode. Reordering writes when the compiler assumes
6662
// things are immutable is dangerous.
67-
unsafe { write_volatile(self.mut_ptr(), value) };
63+
//
64+
// We can just cast the pointer from `CopyCell<T>` to `T` because of
65+
// #[repr(transparent)]
66+
//
67+
// This behavior is copied over from the std implementation of
68+
// the `UnsafeCell`, and it's the best we can do right now in terms
69+
// of soundness till we get a stable `UnsafeCell` that implements `Copy`.
70+
unsafe { write_volatile(self as *const CopyCell<T> as *const T as *mut T, value) };
6871
}
6972
}
7073

0 commit comments

Comments
 (0)