Skip to content

Commit

Permalink
Implement unsize of adt's (cc rust-lang#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorn3 committed Sep 16, 2018
1 parent b9b0fc5 commit 7324811
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 3 deletions.
5 changes: 4 additions & 1 deletion examples/mini_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
Expand Down Expand Up @@ -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];

Expand Down
3 changes: 2 additions & 1 deletion examples/mini_core_hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
17 changes: 16 additions & 1 deletion src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
}
}

Expand Down

0 comments on commit 7324811

Please sign in to comment.