Skip to content

Commit 401b034

Browse files
committed
Fix Box deref for non-ZST allocators
1 parent 5841caa commit 401b034

File tree

3 files changed

+21
-11
lines changed

3 files changed

+21
-11
lines changed

example/mini_core.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -483,8 +483,17 @@ pub trait Deref {
483483
fn deref(&self) -> &Self::Target;
484484
}
485485

486+
pub struct Unique<T: ?Sized> {
487+
pub pointer: *const T,
488+
pub _marker: PhantomData<T>,
489+
}
490+
491+
impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {}
492+
493+
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {}
494+
486495
#[lang = "owned_box"]
487-
pub struct Box<T: ?Sized>(*mut T);
496+
pub struct Box<T: ?Sized>(Unique<T>, ());
488497

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

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

510519
#[lang = "box_free"]
511-
unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
512-
libc::free(ptr as *mut u8);
520+
unsafe fn box_free<T: ?Sized>(ptr: Unique<T>, alloc: ()) {
521+
libc::free(ptr.pointer as *mut u8);
513522
}
514523

515524
#[lang = "drop"]

example/mini_core_hello_world.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,6 @@ fn start<T: Termination + 'static>(
105105
static mut NUM: u8 = 6 * 7;
106106
static NUM_REF: &'static u8 = unsafe { &NUM };
107107

108-
struct Unique<T: ?Sized> {
109-
pointer: *const T,
110-
_marker: PhantomData<T>,
111-
}
112-
113-
impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {}
114108

115109
unsafe fn zeroed<T>() -> T {
116110
let mut uninit = MaybeUninit { uninit: () };

src/base.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub(crate) fn codegen_fn<'tcx>(
2525
let mir = tcx.instance_mir(instance.def);
2626
let _mir_guard = crate::PrintOnPanic(|| {
2727
let mut buf = Vec::new();
28-
rustc_middle::mir::write_mir_pretty(tcx, Some(instance.def_id()), &mut buf).unwrap();
28+
rustc_middle::mir::pretty::write_mir_fn(tcx, mir, &mut |_, _| Ok(()), &mut buf).unwrap();
2929
String::from_utf8_lossy(&buf).into_owned()
3030
});
3131

@@ -813,7 +813,14 @@ pub(crate) fn codegen_place<'tcx>(
813813
for elem in place.projection {
814814
match elem {
815815
PlaceElem::Deref => {
816-
cplace = cplace.place_deref(fx);
816+
if cplace.layout().ty.is_box() {
817+
cplace = cplace
818+
.place_field(fx, Field::new(0)) // Box<T> -> Unique<T>
819+
.place_field(fx, Field::new(0)) // Unique<T> -> *const T
820+
.place_deref(fx);
821+
} else {
822+
cplace = cplace.place_deref(fx);
823+
}
817824
}
818825
PlaceElem::Field(field, _ty) => {
819826
cplace = cplace.place_field(fx, field);

0 commit comments

Comments
 (0)