]> git.lizzy.rs Git - rust.git/commitdiff
Implement unsize array -> slice and trait object -> trait object
authorbjorn3 <bjorn3@users.noreply.github.com>
Wed, 22 Aug 2018 13:38:56 +0000 (15:38 +0200)
committerbjorn3 <bjorn3@users.noreply.github.com>
Thu, 30 Aug 2018 18:21:58 +0000 (20:21 +0200)
examples/example.rs
examples/mini_core_hello_world.rs
src/base.rs
src/common.rs

index efe07ca2eccbf7dc352153e3019c51401924ec04..dfca3142301dc190a21ac360dff2e19ba4d95436 100644 (file)
@@ -153,6 +153,10 @@ unsafe fn deref_str_ptr(s: *const str) -> &'static str {
     [0; 3]
 }
 
+fn array_as_slice(arr: &[u8; 3]) -> &[u8] {
+    arr
+}
+
 /*unsafe fn use_ctlz_nonzero(a: u16) -> u16 {
     intrinsics::ctlz_nonzero(a)
 }*/
index 19cc727fb55eebcb0aa8800a01d90dc29f3be826..c775beef2f09ea5a9b6e90a57f11864af5ba3c59 100644 (file)
@@ -43,7 +43,8 @@ fn start<T: Termination + 'static>(
 
 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);
     }
 
index 8cbdf6db855a08972b1727360baad60dac6ab2fb..9b44cd2e4b73db449d17619b6c418604aff86d4b 100644 (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);
index 768c8cd25e1ab7b66ef21a8de4964156d93b9d52..b785177251fa4cb90783f5947c74be6c035a68c1 100644 (file)
@@ -216,6 +216,43 @@ pub fn value_field<'a>(
         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>,