]> git.lizzy.rs Git - rust.git/commitdiff
invoke drop glue with a ptr to (data, meta)
authorNiko Matsakis <niko@alum.mit.edu>
Tue, 13 Sep 2016 20:04:27 +0000 (16:04 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Tue, 13 Sep 2016 20:05:12 +0000 (16:05 -0400)
This is done by creating a little space on the stack. Hokey, but it's
the simplest fix I can see.

src/librustc_trans/glue.rs
src/librustc_trans/intrinsic.rs
src/librustc_trans/mir/block.rs

index 6b48c6ae26dac0df36c2afc11e650fd48b83167c..3073b1dbfaeebcd09d90d2daff23dd6816149a95 100644 (file)
@@ -296,6 +296,7 @@ fn trans_custom_dtor<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         sized_args = [v0];
         &sized_args
     } else {
+        // FIXME(#36457) -- we should pass unsized values to drop glue as two arguments
         unsized_args = [
             Load(bcx, get_dataptr(bcx, v0)),
             Load(bcx, get_meta(bcx, v0))
@@ -440,7 +441,9 @@ fn local_prefix_bytes(variant: &ty::layout::Struct) -> u64 {
     }
 }
 
-fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, g: DropGlueKind<'tcx>)
+fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
+                              v0: ValueRef,
+                              g: DropGlueKind<'tcx>)
                               -> Block<'blk, 'tcx> {
     let t = g.ty();
 
@@ -463,6 +466,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, g: DropGlueK
                 let llval = get_dataptr(bcx, v0);
                 let llbox = Load(bcx, llval);
                 let bcx = drop_ty(bcx, v0, content_ty, DebugLoc::None);
+                // FIXME(#36457) -- we should pass unsized values to drop glue as two arguments
                 let info = get_meta(bcx, v0);
                 let info = Load(bcx, info);
                 let (llsize, llalign) =
@@ -488,6 +492,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, g: DropGlueK
             // No support in vtable for distinguishing destroying with
             // versus without calling Drop::drop. Assert caller is
             // okay with always calling the Drop impl, if any.
+            // FIXME(#36457) -- we should pass unsized values to drop glue as two arguments
             assert!(!skip_dtor);
             let data_ptr = get_dataptr(bcx, v0);
             let vtable_ptr = Load(bcx, get_meta(bcx, v0));
@@ -543,6 +548,7 @@ fn iter_variant<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
     let value = if type_is_sized(cx.tcx(), t) {
         adt::MaybeSizedValue::sized(av)
     } else {
+        // FIXME(#36457) -- we should pass unsized values as two arguments
         let data = Load(cx, get_dataptr(cx, av));
         let info = Load(cx, get_meta(cx, av));
         adt::MaybeSizedValue::unsized_(data, info)
@@ -586,6 +592,7 @@ fn iter_variant<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                     let val = if type_is_sized(cx.tcx(), field_ty) {
                         llfld_a
                     } else {
+                        // FIXME(#36457) -- we should pass unsized values as two arguments
                         let scratch = alloc_ty(cx, field_ty, "__fat_ptr_iter");
                         Store(cx, llfld_a, get_dataptr(cx, scratch));
                         Store(cx, value.meta, get_meta(cx, scratch));
index 2049696ee4f717ba704210c6aa4ed123c77022a8..fbade107ecfda24bf6c05885b9808d03fe9fe170 100644 (file)
@@ -186,6 +186,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             let ptr = if is_sized {
                 llargs[0]
             } else {
+                // FIXME(#36457) -- we should pass unsized values as two arguments
                 let scratch = alloc_ty(bcx, tp_ty, "drop");
                 call_lifetime_start(bcx, scratch);
                 Store(bcx, llargs[0], get_dataptr(bcx, scratch));
index fbd04d7b380293e343578cc12101bdeb953d6d1e..baeafbe3e346f221462bac0a0bea64538fa06f5a 100644 (file)
@@ -242,10 +242,28 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock) {
                 let lvalue = self.trans_lvalue(&bcx, location);
                 let drop_fn = glue::get_drop_glue(bcx.ccx(), ty);
                 let drop_ty = glue::get_drop_glue_type(bcx.tcx(), ty);
-                let llvalue = if drop_ty != ty {
-                    bcx.pointercast(lvalue.llval, type_of::type_of(bcx.ccx(), drop_ty).ptr_to())
+                let is_sized = common::type_is_sized(bcx.tcx(), ty);
+                let llvalue = if is_sized {
+                    if drop_ty != ty {
+                        bcx.pointercast(lvalue.llval, type_of::type_of(bcx.ccx(), drop_ty).ptr_to())
+                    } else {
+                        lvalue.llval
+                    }
                 } else {
-                    lvalue.llval
+                    // FIXME(#36457) Currently drop glue takes sized
+                    // values as a `*(data, meta)`, but elsewhere in
+                    // MIR we pass `(data, meta)` as two separate
+                    // arguments. It would be better to fix drop glue,
+                    // but I am shooting for a quick fix to #35546
+                    // here that can be cleanly backported to beta, so
+                    // I want to avoid touching all of trans.
+                    bcx.with_block(|bcx| {
+                        let scratch = base::alloc_ty(bcx, ty, "drop");
+                        base::call_lifetime_start(bcx, scratch);
+                        build::Store(bcx, lvalue.llval, base::get_dataptr(bcx, scratch));
+                        build::Store(bcx, lvalue.llextra, base::get_meta(bcx, scratch));
+                        scratch
+                    })
                 };
                 if let Some(unwind) = unwind {
                     bcx.invoke(drop_fn,