Skip to content

Commit

Permalink
Use cast instead of transmute
Browse files Browse the repository at this point in the history
  • Loading branch information
kornelski committed Oct 27, 2023
1 parent 845d036 commit c85ff9d
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 24 deletions.
12 changes: 3 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,9 +370,7 @@ macro_rules! self_cell {

let joined_void_ptr = NonNull::new($crate::alloc::alloc::alloc(layout)).unwrap();

let mut joined_ptr = core::mem::transmute::<NonNull<u8>, NonNull<JoinedCell>>(
joined_void_ptr
);
let mut joined_ptr = joined_void_ptr.cast::<JoinedCell>();

let (owner_ptr, dependent_ptr) = JoinedCell::_field_pointers(joined_ptr.as_ptr());

Expand Down Expand Up @@ -417,9 +415,7 @@ macro_rules! self_cell {

let joined_void_ptr = NonNull::new($crate::alloc::alloc::alloc(layout)).unwrap();

let mut joined_ptr = core::mem::transmute::<NonNull<u8>, NonNull<JoinedCell>>(
joined_void_ptr
);
let mut joined_ptr = joined_void_ptr.cast::<JoinedCell>();

let (owner_ptr, dependent_ptr) = JoinedCell::_field_pointers(joined_ptr.as_ptr());

Expand Down Expand Up @@ -468,9 +464,7 @@ macro_rules! self_cell {

let joined_void_ptr = NonNull::new($crate::alloc::alloc::alloc(layout)).unwrap();

let mut joined_ptr = core::mem::transmute::<NonNull<u8>, NonNull<JoinedCell>>(
joined_void_ptr
);
let mut joined_ptr = joined_void_ptr.cast::<JoinedCell>();

let (owner_ptr, dependent_ptr) = JoinedCell::_field_pointers(joined_ptr.as_ptr());

Expand Down
21 changes: 7 additions & 14 deletions src/unsafe_self_cell.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::marker::PhantomData;
use core::mem::{self, transmute};
use core::mem;
use core::ptr::{drop_in_place, read, NonNull};

extern crate alloc;
Expand Down Expand Up @@ -53,22 +53,19 @@ impl<ContainedIn, Owner, DependentStatic> UnsafeSelfCell<ContainedIn, Owner, Dep
// Calling any of these *unsafe* functions with the wrong Dependent type is UB.

pub unsafe fn borrow_owner<'a, Dependent>(&'a self) -> &'a Owner {
let joined_ptr =
transmute::<NonNull<u8>, NonNull<JoinedCell<Owner, Dependent>>>(self.joined_void_ptr);
let joined_ptr = self.joined_void_ptr.cast::<JoinedCell<Owner, Dependent>>();

&(*joined_ptr.as_ptr()).owner
}

pub unsafe fn borrow_dependent<'a, Dependent>(&'a self) -> &'a Dependent {
let joined_ptr =
transmute::<NonNull<u8>, NonNull<JoinedCell<Owner, Dependent>>>(self.joined_void_ptr);
let joined_ptr = self.joined_void_ptr.cast::<JoinedCell<Owner, Dependent>>();

&(*joined_ptr.as_ptr()).dependent
}

pub unsafe fn borrow_mut<'a, Dependent>(&'a mut self) -> (&'a Owner, &'a mut Dependent) {
let joined_ptr =
transmute::<NonNull<u8>, NonNull<JoinedCell<Owner, Dependent>>>(self.joined_void_ptr);
let joined_ptr = self.joined_void_ptr.cast::<JoinedCell<Owner, Dependent>>();

// This function used to return `&'a mut JoinedCell<Owner, Dependent>`.
// It now creates two references to the fields instead to avoid claiming mutable access
Expand All @@ -81,8 +78,7 @@ impl<ContainedIn, Owner, DependentStatic> UnsafeSelfCell<ContainedIn, Owner, Dep

// Any subsequent use of this struct other than dropping it is UB.
pub unsafe fn drop_joined<Dependent>(&mut self) {
let joined_ptr =
transmute::<NonNull<u8>, NonNull<JoinedCell<Owner, Dependent>>>(self.joined_void_ptr);
let joined_ptr = self.joined_void_ptr.cast::<JoinedCell<Owner, Dependent>>();

// Also used in case drop_in_place(...dependent) fails
let _guard = OwnerAndCellDropGuard { joined_ptr };
Expand All @@ -98,8 +94,7 @@ impl<ContainedIn, Owner, DependentStatic> UnsafeSelfCell<ContainedIn, Owner, Dep
}

pub unsafe fn into_owner<Dependent>(self) -> Owner {
let joined_ptr =
transmute::<NonNull<u8>, NonNull<JoinedCell<Owner, Dependent>>>(self.joined_void_ptr);
let joined_ptr = self.joined_void_ptr.cast::<JoinedCell<Owner, Dependent>>();

// In case drop_in_place(...dependent) fails
let drop_guard = OwnerAndCellDropGuard::new(joined_ptr);
Expand Down Expand Up @@ -170,9 +165,7 @@ impl<Owner, Dependent> Drop for OwnerAndCellDropGuard<Owner, Dependent> {

// Deallocate even when the drop_in_place(...owner) panics
let _guard = DeallocGuard {
ptr: unsafe {
transmute::<*mut JoinedCell<Owner, Dependent>, *mut u8>(self.joined_ptr.as_ptr())
},
ptr: self.joined_ptr.as_ptr().cast(),
layout: Layout::new::<JoinedCell<Owner, Dependent>>(),
};

Expand Down
2 changes: 1 addition & 1 deletion tests/self_cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ fn from_fn() {

let expected_str = "small pink bike";

let fn_cell = FnCell::new(expected_str.clone().into(), |owner| {
let fn_cell = FnCell::new(expected_str.into(), |owner| {
// Make sure it only gets called once.
extra_outside_state = if let Some(x) = extra_outside_state {
Some(x + 5)
Expand Down

0 comments on commit c85ff9d

Please sign in to comment.