Implement unsize of adt's (cc #14)

This commit is contained in:
bjorn3 2018-09-16 11:57:27 +02:00
parent b9b0fc59f9
commit 73248114ea
3 changed files with 22 additions and 3 deletions

View file

@ -12,6 +12,7 @@ pub trait Unsize<T: ?Sized> {}
pub trait CoerceUnsized<T> {}
impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
#[lang = "copy"]
pub unsafe trait Copy {}
@ -203,7 +204,9 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
}
#[lang = "owned_box"]
pub struct Box<T>(*mut T);
pub struct Box<T: ?Sized>(*mut T);
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}
static mut MY_TINY_HEAP: [u8; 16] = [0; 16];

View file

@ -111,8 +111,9 @@ fn main() {
// TODO remove when jit supports linking rlibs
#[cfg(not(jit))]
{
let world = box "World!\0";
let world: Box<&str> = box "World!\0";
puts(*world as *const str as *const u8);
world as Box<SomeTrait>;
}
assert_eq!(intrinsics::size_of_val(hello) as u8, 6);

View file

@ -252,7 +252,22 @@ impl<'tcx> CValue<'tcx> {
};
dest.write_cvalue(fx, CValue::ByValPair(ptr, extra, dest.layout()));
}
ty => unimpl!("unsize of non ptr {:?}", ty),
_ => {
assert!(!self.layout().ty.is_enum(), "Tried to unsize enum");
let field_count = self.layout().fields.count();
let mut found_unsize_field = false;
for idx in 0..field_count {
let field_dest = dest.place_field(fx, mir::Field::new(idx));
let field_src = self.value_field(fx, mir::Field::new(idx));
if field_src.layout().ty != field_dest.layout().ty {
assert!(!found_unsize_field);
found_unsize_field = true;
field_src.unsize_value(fx, field_dest);
} else {
field_dest.write_cvalue(fx, field_src);
}
}
}
}
}