From 12282a8ebc2404add07224a74b872cecf6d602da Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 22 Aug 2018 15:38:56 +0200 Subject: [PATCH] Implement unsize array -> slice and trait object -> trait object --- examples/example.rs | 4 ++++ examples/mini_core_hello_world.rs | 3 ++- src/base.rs | 3 ++- src/common.rs | 37 +++++++++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/examples/example.rs b/examples/example.rs index efe07ca2ecc..dfca3142301 100644 --- a/examples/example.rs +++ b/examples/example.rs @@ -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) }*/ diff --git a/examples/mini_core_hello_world.rs b/examples/mini_core_hello_world.rs index 19cc727fb55..c775beef2f0 100644 --- a/examples/mini_core_hello_world.rs +++ b/examples/mini_core_hello_world.rs @@ -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); } diff --git a/src/base.rs b/src/base.rs index 8cbdf6db855..9b44cd2e4b7 100644 --- a/src/base.rs +++ b/src/base.rs @@ -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); diff --git a/src/common.rs b/src/common.rs index 768c8cd25e1..b785177251f 100644 --- a/src/common.rs +++ b/src/common.rs @@ -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>,