]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/middle/trans/glue.rs
auto merge of #15999 : Kimundi/rust/fix_folder, r=nikomatsakis
[rust.git] / src / librustc / middle / trans / glue.rs
index aad7ba95a73a964b7bfda8d3b45ebbde959dfed9..40288a33930e5ebdb96131d92b2d24a9490bd1fd 100644 (file)
@@ -129,7 +129,7 @@ pub fn drop_ty<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
         } else {
             v
         };
-        Call(bcx, glue, [ptr], []);
+        Call(bcx, glue, [ptr], None);
     }
     bcx
 }
@@ -178,35 +178,14 @@ pub fn lazily_emit_visit_glue(ccx: &CrateContext, ti: &tydesc_info) -> ValueRef
 }
 
 // See [Note-arg-mode]
-pub fn call_visit_glue(bcx: &Block, v: ValueRef, tydesc: ValueRef,
-                       static_ti: Option<&tydesc_info>) {
-    let _icx = push_ctxt("call_tydesc_glue_full");
-    let ccx = bcx.ccx();
-    // NB: Don't short-circuit even if this block is unreachable because
-    // GC-based cleanup needs to the see that the roots are live.
-    if bcx.unreachable.get() && !ccx.sess().no_landing_pads() { return; }
-
-    let static_glue_fn = static_ti.map(|sti| lazily_emit_visit_glue(ccx, sti));
+pub fn call_visit_glue(bcx: &Block, v: ValueRef, tydesc: ValueRef) {
+    let _icx = push_ctxt("call_visit_glue");
 
-    // When static type info is available, avoid casting to a generic pointer.
-    let llrawptr = if static_glue_fn.is_none() {
-        PointerCast(bcx, v, Type::i8p(ccx))
-    } else {
-        v
-    };
+    // Select the glue function to call from the tydesc
+    let llfn = Load(bcx, GEPi(bcx, tydesc, [0u, abi::tydesc_field_visit_glue]));
+    let llrawptr = PointerCast(bcx, v, Type::i8p(bcx.ccx()));
 
-    let llfn = {
-        match static_glue_fn {
-            None => {
-                // Select out the glue function to call from the tydesc
-                let llfnptr = GEPi(bcx, tydesc, [0u, abi::tydesc_field_visit_glue]);
-                Load(bcx, llfnptr)
-            }
-            Some(sgf) => sgf
-        }
-    };
-
-    Call(bcx, llfn, [llrawptr], []);
+    Call(bcx, llfn, [llrawptr], None);
 }
 
 fn make_visit_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
@@ -225,7 +204,7 @@ fn make_visit_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
     bcx
 }
 
-fn trans_struct_drop_flag<'a>(bcx: &'a Block<'a>,
+fn trans_struct_drop_flag<'a>(mut bcx: &'a Block<'a>,
                               t: ty::t,
                               v0: ValueRef,
                               dtor_did: ast::DefId,
@@ -233,8 +212,8 @@ fn trans_struct_drop_flag<'a>(bcx: &'a Block<'a>,
                               substs: &subst::Substs)
                               -> &'a Block<'a> {
     let repr = adt::represent_type(bcx.ccx(), t);
-    let drop_flag = adt::trans_drop_flag_ptr(bcx, &*repr, v0);
-    with_cond(bcx, load_ty(bcx, drop_flag, ty::mk_bool()), |cx| {
+    let drop_flag = unpack_datum!(bcx, adt::trans_drop_flag_ptr(bcx, &*repr, v0));
+    with_cond(bcx, load_ty(bcx, drop_flag.val, ty::mk_bool()), |cx| {
         trans_struct_drop(cx, t, v0, dtor_did, class_did, substs)
     })
 }
@@ -258,33 +237,33 @@ fn trans_struct_drop<'a>(bcx: &'a Block<'a>,
         ty.element_type().func_params()
     };
 
-    // Class dtors have no explicit args, so the params should
-    // just consist of the environment (self)
-    assert_eq!(params.len(), 1);
-
-    // Be sure to put all of the fields into a scope so we can use an invoke
-    // instruction to call the user destructor but still call the field
-    // destructors if the user destructor fails.
-    let field_scope = bcx.fcx.push_custom_cleanup_scope();
-
-    let self_arg = PointerCast(bcx, v0, *params.get(0));
-    let args = vec!(self_arg);
-
-    // Add all the fields as a value which needs to be cleaned at the end of
-    // this scope.
-    let field_tys = ty::struct_fields(bcx.tcx(), class_did, substs);
-    for (i, fld) in field_tys.iter().enumerate() {
-        let llfld_a = adt::trans_field_ptr(bcx, &*repr, v0, 0, i);
-        bcx.fcx.schedule_drop_mem(cleanup::CustomScope(field_scope),
-                                  llfld_a,
-                                  fld.mt.ty);
-    }
+    adt::fold_variants(bcx, &*repr, v0, |variant_cx, st, value| {
+        // Be sure to put all of the fields into a scope so we can use an invoke
+        // instruction to call the user destructor but still call the field
+        // destructors if the user destructor fails.
+        let field_scope = variant_cx.fcx.push_custom_cleanup_scope();
+
+        // Class dtors have no explicit args, so the params should
+        // just consist of the environment (self).
+        assert_eq!(params.len(), 1);
+        let self_arg = PointerCast(variant_cx, value, *params.get(0));
+        let args = vec!(self_arg);
+
+        // Add all the fields as a value which needs to be cleaned at the end of
+        // this scope.
+        for (i, ty) in st.fields.iter().enumerate() {
+            let llfld_a = adt::struct_field_ptr(variant_cx, &*st, value, i, false);
+            variant_cx.fcx.schedule_drop_mem(cleanup::CustomScope(field_scope),
+                                             llfld_a, *ty);
+        }
 
-    let dtor_ty = ty::mk_ctor_fn(bcx.tcx(), ast::DUMMY_NODE_ID,
-                                 [get_drop_glue_type(bcx.ccx(), t)], ty::mk_nil());
-    let (_, bcx) = invoke(bcx, dtor_addr, args, dtor_ty, None);
+        let dtor_ty = ty::mk_ctor_fn(variant_cx.tcx(), ast::DUMMY_NODE_ID,
+                                     [get_drop_glue_type(bcx.ccx(), t)], ty::mk_nil());
+        let (_, variant_cx) = invoke(variant_cx, dtor_addr, args, dtor_ty, None);
 
-    bcx.fcx.pop_and_trans_custom_cleanup_scope(bcx, field_scope)
+        variant_cx.fcx.pop_and_trans_custom_cleanup_scope(variant_cx, field_scope);
+        variant_cx
+    })
 }
 
 fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'a> {
@@ -324,7 +303,7 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
                         Call(bcx,
                              dtor,
                              [PointerCast(bcx, lluniquevalue, Type::i8p(bcx.ccx()))],
-                             []);
+                             None);
                         bcx
                     })
                 }
@@ -338,7 +317,7 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
                 }
             }
         }
-        ty::ty_struct(did, ref substs) => {
+        ty::ty_struct(did, ref substs) | ty::ty_enum(did, ref substs) => {
             let tcx = bcx.tcx();
             match ty::ty_dtor(tcx, did) {
                 ty::TraitDtor(dtor, true) => {
@@ -363,7 +342,7 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
                 let dtor_ptr = GEPi(bcx, env, [0u, abi::box_field_tydesc]);
                 let dtor = Load(bcx, dtor_ptr);
                 let cdata = GEPi(bcx, env, [0u, abi::box_field_body]);
-                Call(bcx, dtor, [PointerCast(bcx, cdata, Type::i8p(bcx.ccx()))], []);
+                Call(bcx, dtor, [PointerCast(bcx, cdata, Type::i8p(bcx.ccx()))], None);
 
                 // Free the environment itself
                 // FIXME: #13994: pass align and size here
@@ -489,7 +468,7 @@ fn make_generic_glue(ccx: &CrateContext,
     let arena = TypedArena::new();
     let empty_param_substs = param_substs::empty();
     let fcx = new_fn_ctxt(ccx, llfn, -1, false, ty::mk_nil(),
-                          &empty_param_substs, None, &arena);
+                          &empty_param_substs, None, &arena, TranslateItems);
 
     let bcx = init_function(&fcx, false, ty::mk_nil());