Implement unsize array -> slice and trait object -> trait object

This commit is contained in:
bjorn3 2018-08-22 15:38:56 +02:00
parent b5082f7da8
commit 12282a8ebc
4 changed files with 45 additions and 2 deletions

View File

@ -153,6 +153,10 @@ fn repeat_array() -> [u8; 3] {
[0; 3]
}
fn array_as_slice(arr: &[u8; 3]) -> &[u8] {
arr
}
/*unsafe fn use_ctlz_nonzero(a: u16) -> u16 {
intrinsics::ctlz_nonzero(a)
}*/

View File

@ -43,7 +43,8 @@ static NUM_REF: &'static u8 = unsafe { &NUM };
fn main() {
unsafe {
let (ptr, _): (*const u8, usize) = intrinsics::transmute("Hello!\0");
let slice: &[u8] = b"Hello!\0" as &[u8; 7];
let ptr: *const u8 = slice as *const [u8] as *const u8;
puts(ptr);
}

View File

@ -458,7 +458,8 @@ fn trans_stmt<'a, 'tcx: 'a>(
unimplemented!("rval closure_fn_ptr {:?} {:?}", operand, ty)
}
Rvalue::Cast(CastKind::Unsize, operand, ty) => {
unimpl!("rval unsize {:?} {:?}", operand, ty);
let operand = trans_operand(fx, operand);
operand.unsize_value(fx, lval);
}
Rvalue::Discriminant(place) => {
let place = trans_place(fx, place).to_cvalue(fx);

View File

@ -216,6 +216,43 @@ impl<'tcx> CValue<'tcx> {
CValue::ByRef(field_ptr, field_layout)
}
pub fn unsize_value<'a>(self, fx: &mut FunctionCx<'a, 'tcx, impl Backend>, dest: CPlace<'tcx>) {
if self.layout().ty == dest.layout().ty {
dest.write_cvalue(fx, self); // FIXME this shouldn't happen (rust-lang/rust#53602)
return;
}
match &self.layout().ty.sty {
ty::Ref(_, ty, _) | ty::RawPtr(TypeAndMut { ty, mutbl: _ }) => {
let (ptr, extra) = match ptr_referee(dest.layout().ty).sty {
ty::Slice(slice_elem_ty) => match ty.sty {
ty::Array(array_elem_ty, size) => {
assert_eq!(slice_elem_ty, array_elem_ty);
let ptr = self.load_value(fx);
let extra = fx
.bcx
.ins()
.iconst(fx.module.pointer_type(), size.unwrap_usize(fx.tcx) as i64);
(ptr, extra)
}
_ => bug!("unsize non array {:?} to slice", ty),
},
ty::Dynamic(_, _) => match ty.sty {
ty::Dynamic(_, _) => self.load_value_pair(fx),
_ => unimpl!("unsize of type ... to {:?}", dest.layout().ty),
},
_ => bug!(
"unsize of type {:?} to {:?}",
self.layout().ty,
dest.layout().ty
),
};
println!("ty {:?}", self.layout().ty);
dest.write_cvalue(fx, CValue::ByValPair(ptr, extra, dest.layout()));
}
ty => unimpl!("unsize of non ptr {:?}", ty),
}
}
pub fn const_val<'a>(
fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
ty: Ty<'tcx>,