Skip to content

Commit

Permalink
Fix Box deref for non-ZST allocators
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorn3 committed Mar 8, 2022
1 parent 5841caa commit 401b034
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 11 deletions.
15 changes: 12 additions & 3 deletions example/mini_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -483,8 +483,17 @@ pub trait Deref {
fn deref(&self) -> &Self::Target;
}

pub struct Unique<T: ?Sized> {
pub pointer: *const T,
pub _marker: PhantomData<T>,
}

impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {}

impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {}

#[lang = "owned_box"]
pub struct Box<T: ?Sized>(*mut T);
pub struct Box<T: ?Sized>(Unique<T>, ());

impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}

Expand All @@ -508,8 +517,8 @@ unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
}

#[lang = "box_free"]
unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
libc::free(ptr as *mut u8);
unsafe fn box_free<T: ?Sized>(ptr: Unique<T>, alloc: ()) {
libc::free(ptr.pointer as *mut u8);
}

#[lang = "drop"]
Expand Down
6 changes: 0 additions & 6 deletions example/mini_core_hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,6 @@ fn start<T: Termination + 'static>(
static mut NUM: u8 = 6 * 7;
static NUM_REF: &'static u8 = unsafe { &NUM };

struct Unique<T: ?Sized> {
pointer: *const T,
_marker: PhantomData<T>,
}

impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {}

unsafe fn zeroed<T>() -> T {
let mut uninit = MaybeUninit { uninit: () };
Expand Down
11 changes: 9 additions & 2 deletions src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub(crate) fn codegen_fn<'tcx>(
let mir = tcx.instance_mir(instance.def);
let _mir_guard = crate::PrintOnPanic(|| {
let mut buf = Vec::new();
rustc_middle::mir::write_mir_pretty(tcx, Some(instance.def_id()), &mut buf).unwrap();
rustc_middle::mir::pretty::write_mir_fn(tcx, mir, &mut |_, _| Ok(()), &mut buf).unwrap();
String::from_utf8_lossy(&buf).into_owned()
});

Expand Down Expand Up @@ -813,7 +813,14 @@ pub(crate) fn codegen_place<'tcx>(
for elem in place.projection {
match elem {
PlaceElem::Deref => {
cplace = cplace.place_deref(fx);
if cplace.layout().ty.is_box() {
cplace = cplace
.place_field(fx, Field::new(0)) // Box<T> -> Unique<T>
.place_field(fx, Field::new(0)) // Unique<T> -> *const T
.place_deref(fx);
} else {
cplace = cplace.place_deref(fx);
}
}
PlaceElem::Field(field, _ty) => {
cplace = cplace.place_field(fx, field);
Expand Down

0 comments on commit 401b034

Please sign in to comment.