about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/middle/ty.rs44
-rw-r--r--src/librustc_trans/trans/callee.rs2
-rw-r--r--src/librustc_trans/trans/cleanup.rs12
-rw-r--r--src/librustc_trans/trans/common.rs49
-rw-r--r--src/librustc_trans/trans/context.rs6
-rw-r--r--src/librustc_trans/trans/controlflow.rs2
-rw-r--r--src/librustc_trans/trans/datum.rs4
-rw-r--r--src/librustc_trans/trans/expr.rs6
-rw-r--r--src/librustc_trans/trans/glue.rs8
-rw-r--r--src/librustc_trans/trans/intrinsic.rs2
-rw-r--r--src/librustc_trans/trans/meth.rs2
-rw-r--r--src/librustc_trans/trans/tvec.rs2
12 files changed, 75 insertions, 64 deletions
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 617be82701a..d09efb006f2 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -682,7 +682,6 @@ pub struct ctxt<'tcx> {
     pub tcache: RefCell<DefIdMap<Polytype<'tcx>>>,
     pub rcache: RefCell<FnvHashMap<creader_cache_key, Ty<'tcx>>>,
     pub short_names_cache: RefCell<FnvHashMap<Ty<'tcx>, String>>,
-    pub needs_unwind_cleanup_cache: RefCell<FnvHashMap<Ty<'tcx>, bool>>,
     pub tc_cache: RefCell<FnvHashMap<Ty<'tcx>, TypeContents>>,
     pub ast_ty_to_ty_cache: RefCell<NodeMap<ast_ty_to_ty_cache_entry<'tcx>>>,
     pub enum_var_cache: RefCell<DefIdMap<Rc<Vec<Rc<VariantInfo<'tcx>>>>>>,
@@ -2108,7 +2107,6 @@ pub fn mk_ctxt<'tcx>(s: Session,
         tcache: RefCell::new(DefIdMap::new()),
         rcache: RefCell::new(FnvHashMap::new()),
         short_names_cache: RefCell::new(FnvHashMap::new()),
-        needs_unwind_cleanup_cache: RefCell::new(FnvHashMap::new()),
         tc_cache: RefCell::new(FnvHashMap::new()),
         ast_ty_to_ty_cache: RefCell::new(NodeMap::new()),
         enum_var_cache: RefCell::new(DefIdMap::new()),
@@ -2824,48 +2822,6 @@ pub fn type_is_floating_point(ty: Ty) -> bool {
     }
 }
 
-pub fn type_needs_drop<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
-    type_contents(cx, ty).needs_drop(cx)
-}
-
-// Some things don't need cleanups during unwinding because the
-// task can free them all at once later. Currently only things
-// that only contain scalars and shared boxes can avoid unwind
-// cleanups.
-pub fn type_needs_unwind_cleanup<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
-    return memoized(&cx.needs_unwind_cleanup_cache, ty, |ty| {
-        type_needs_unwind_cleanup_(cx, ty, &mut FnvHashSet::new())
-    });
-
-    fn type_needs_unwind_cleanup_<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>,
-                                        tycache: &mut FnvHashSet<Ty<'tcx>>) -> bool {
-        // Prevent infinite recursion
-        if !tycache.insert(ty) {
-            return false;
-        }
-
-        let mut needs_unwind_cleanup = false;
-        maybe_walk_ty(ty, |ty| {
-            needs_unwind_cleanup |= match ty.sty {
-                ty_bool | ty_int(_) | ty_uint(_) |
-                ty_float(_) | ty_tup(_) | ty_ptr(_) => false,
-
-                ty_enum(did, substs) =>
-                    enum_variants(cx, did).iter().any(|v|
-                        v.args.iter().any(|aty| {
-                            let t = aty.subst(cx, substs);
-                            type_needs_unwind_cleanup_(cx, t, tycache)
-                        })
-                    ),
-
-                _ => true
-            };
-            !needs_unwind_cleanup
-        });
-        needs_unwind_cleanup
-    }
-}
-
 /// Type contents is how the type checker reasons about kinds.
 /// They track what kinds of things are found within a type.  You can
 /// think of them as kind of an "anti-kind".  They track the kinds of values
diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs
index a159cda9fba..dab4c0273d0 100644
--- a/src/librustc_trans/trans/callee.rs
+++ b/src/librustc_trans/trans/callee.rs
@@ -722,7 +722,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
             };
             if !is_rust_fn ||
               type_of::return_uses_outptr(ccx, ret_ty) ||
-              ty::type_needs_drop(bcx.tcx(), ret_ty) {
+              type_needs_drop(bcx.tcx(), ret_ty) {
                 // Push the out-pointer if we use an out-pointer for this
                 // return type, otherwise push "undef".
                 if type_is_zero_size(ccx, ret_ty) {
diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs
index f96aa484ffc..d02d6c1e872 100644
--- a/src/librustc_trans/trans/cleanup.rs
+++ b/src/librustc_trans/trans/cleanup.rs
@@ -279,10 +279,10 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
                          cleanup_scope: ScopeId,
                          val: ValueRef,
                          ty: Ty<'tcx>) {
-        if !ty::type_needs_drop(self.ccx.tcx(), ty) { return; }
+        if !common::type_needs_drop(self.ccx.tcx(), ty) { return; }
         let drop = box DropValue {
             is_immediate: false,
-            must_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
+            must_unwind: common::type_needs_unwind_cleanup(self.ccx, ty),
             val: val,
             ty: ty,
             zero: false
@@ -301,10 +301,10 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
                                   cleanup_scope: ScopeId,
                                   val: ValueRef,
                                   ty: Ty<'tcx>) {
-        if !ty::type_needs_drop(self.ccx.tcx(), ty) { return; }
+        if !common::type_needs_drop(self.ccx.tcx(), ty) { return; }
         let drop = box DropValue {
             is_immediate: false,
-            must_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
+            must_unwind: common::type_needs_unwind_cleanup(self.ccx, ty),
             val: val,
             ty: ty,
             zero: true
@@ -325,10 +325,10 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
                                val: ValueRef,
                                ty: Ty<'tcx>) {
 
-        if !ty::type_needs_drop(self.ccx.tcx(), ty) { return; }
+        if !common::type_needs_drop(self.ccx.tcx(), ty) { return; }
         let drop = box DropValue {
             is_immediate: true,
-            must_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
+            must_unwind: common::type_needs_unwind_cleanup(self.ccx, ty),
             val: val,
             ty: ty,
             zero: false
diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs
index b15b75c6715..7ee4be0ae56 100644
--- a/src/librustc_trans/trans/common.rs
+++ b/src/librustc_trans/trans/common.rs
@@ -53,9 +53,58 @@ use syntax::ast_map::{PathElem, PathName};
 use syntax::codemap::Span;
 use syntax::parse::token::InternedString;
 use syntax::parse::token;
+use util::common::memoized;
+use util::nodemap::FnvHashSet;
 
 pub use trans::context::CrateContext;
 
+// Some things don't need cleanups during unwinding because the
+// task can free them all at once later. Currently only things
+// that only contain scalars and shared boxes can avoid unwind
+// cleanups.
+pub fn type_needs_unwind_cleanup<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
+    return memoized(ccx.needs_unwind_cleanup_cache(), ty, |ty| {
+        type_needs_unwind_cleanup_(ccx.tcx(), ty, &mut FnvHashSet::new())
+    });
+
+    fn type_needs_unwind_cleanup_<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                        ty: Ty<'tcx>,
+                                        tycache: &mut FnvHashSet<Ty<'tcx>>)
+                                        -> bool
+    {
+        // Prevent infinite recursion
+        if !tycache.insert(ty) {
+            return false;
+        }
+
+        let mut needs_unwind_cleanup = false;
+        ty::maybe_walk_ty(ty, |ty| {
+            needs_unwind_cleanup |= match ty.sty {
+                ty::ty_bool | ty::ty_int(_) | ty::ty_uint(_) |
+                ty::ty_float(_) | ty::ty_tup(_) | ty::ty_ptr(_) => false,
+
+                ty::ty_enum(did, substs) =>
+                    ty::enum_variants(tcx, did).iter().any(|v|
+                        v.args.iter().any(|aty| {
+                            let t = aty.subst(tcx, substs);
+                            type_needs_unwind_cleanup_(tcx, t, tycache)
+                        })
+                    ),
+
+                _ => true
+            };
+            !needs_unwind_cleanup
+        });
+        needs_unwind_cleanup
+    }
+}
+
+pub fn type_needs_drop<'tcx>(cx: &ty::ctxt<'tcx>,
+                             ty: Ty<'tcx>)
+                             -> bool {
+    ty::type_contents(cx, ty).needs_drop(cx)
+}
+
 fn type_is_newtype_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                        ty: Ty<'tcx>) -> bool {
     match ty.sty {
diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs
index 2c71dd831fb..02eaef88548 100644
--- a/src/librustc_trans/trans/context.rs
+++ b/src/librustc_trans/trans/context.rs
@@ -84,6 +84,7 @@ pub struct LocalCrateContext<'tcx> {
     tn: TypeNames,
     externs: RefCell<ExternMap>,
     item_vals: RefCell<NodeMap<ValueRef>>,
+    needs_unwind_cleanup_cache: RefCell<FnvHashMap<Ty<'tcx>, bool>>,
     fn_pointer_shims: RefCell<FnvHashMap<Ty<'tcx>, ValueRef>>,
     drop_glues: RefCell<FnvHashMap<Ty<'tcx>, ValueRef>>,
     tydescs: RefCell<FnvHashMap<Ty<'tcx>, Rc<tydesc_info<'tcx>>>>,
@@ -389,6 +390,7 @@ impl<'tcx> LocalCrateContext<'tcx> {
                 tn: TypeNames::new(),
                 externs: RefCell::new(FnvHashMap::new()),
                 item_vals: RefCell::new(NodeMap::new()),
+                needs_unwind_cleanup_cache: RefCell::new(FnvHashMap::new()),
                 fn_pointer_shims: RefCell::new(FnvHashMap::new()),
                 drop_glues: RefCell::new(FnvHashMap::new()),
                 tydescs: RefCell::new(FnvHashMap::new()),
@@ -569,6 +571,10 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         &self.shared.link_meta
     }
 
+    pub fn needs_unwind_cleanup_cache(&self) -> &RefCell<FnvHashMap<Ty<'tcx>, bool>> {
+        &self.local.needs_unwind_cleanup_cache
+    }
+
     pub fn fn_pointer_shims(&self) -> &RefCell<FnvHashMap<Ty<'tcx>, ValueRef>> {
         &self.local.fn_pointer_shims
     }
diff --git a/src/librustc_trans/trans/controlflow.rs b/src/librustc_trans/trans/controlflow.rs
index 3b24ded6717..768de89d593 100644
--- a/src/librustc_trans/trans/controlflow.rs
+++ b/src/librustc_trans/trans/controlflow.rs
@@ -87,7 +87,7 @@ pub fn trans_stmt_semi<'blk, 'tcx>(cx: Block<'blk, 'tcx>, e: &ast::Expr)
                                    -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("trans_stmt_semi");
     let ty = expr_ty(cx, e);
-    if ty::type_needs_drop(cx.tcx(), ty) {
+    if type_needs_drop(cx.tcx(), ty) {
         expr::trans_to_lvalue(cx, e, "stmt").bcx
     } else {
         expr::trans_into(cx, e, expr::Ignore)
diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs
index 9ab4e92b511..ca274ab605e 100644
--- a/src/librustc_trans/trans/datum.rs
+++ b/src/librustc_trans/trans/datum.rs
@@ -218,7 +218,7 @@ impl KindOps for Lvalue {
                               val: ValueRef,
                               ty: Ty<'tcx>)
                               -> Block<'blk, 'tcx> {
-        if ty::type_needs_drop(bcx.tcx(), ty) {
+        if type_needs_drop(bcx.tcx(), ty) {
             // cancel cleanup of affine values by zeroing out
             let () = zero_mem(bcx, val, ty);
             bcx
@@ -567,7 +567,7 @@ impl<'tcx, K: KindOps + fmt::Show> Datum<'tcx, K> {
     /// scalar-ish (like an int or a pointer) which (1) does not require drop glue and (2) is
     /// naturally passed around by value, and not by reference.
     pub fn to_llscalarish<'blk>(self, bcx: Block<'blk, 'tcx>) -> ValueRef {
-        assert!(!ty::type_needs_drop(bcx.tcx(), self.ty));
+        assert!(!type_needs_drop(bcx.tcx(), self.ty));
         assert!(self.appropriate_rvalue_mode(bcx.ccx()) == ByValue);
         if self.kind.is_by_ref() {
             load_ty(bcx, self.val, self.ty)
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index f49769ba0d9..ae07e094a5c 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -976,7 +976,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             let src_datum = unpack_datum!(bcx, trans(bcx, &**src));
             let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, &**dst, "assign"));
 
-            if ty::type_needs_drop(bcx.tcx(), dst_datum.ty) {
+            if type_needs_drop(bcx.tcx(), dst_datum.ty) {
                 // If there are destructors involved, make sure we
                 // are copying from an rvalue, since that cannot possible
                 // alias an lvalue. We are concerned about code like:
@@ -1513,7 +1513,7 @@ pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
         assert_eq!(discr, 0);
 
         match ty::expr_kind(bcx.tcx(), &*base.expr) {
-            ty::RvalueDpsExpr | ty::RvalueDatumExpr if !ty::type_needs_drop(bcx.tcx(), ty) => {
+            ty::RvalueDpsExpr | ty::RvalueDatumExpr if !type_needs_drop(bcx.tcx(), ty) => {
                 bcx = trans_into(bcx, &*base.expr, SaveIn(addr));
             },
             ty::RvalueStmtExpr => bcx.tcx().sess.bug("unexpected expr kind for struct base expr"),
@@ -2117,7 +2117,7 @@ fn trans_assign_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     // Evaluate LHS (destination), which should be an lvalue
     let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, dst, "assign_op"));
-    assert!(!ty::type_needs_drop(bcx.tcx(), dst_datum.ty));
+    assert!(!type_needs_drop(bcx.tcx(), dst_datum.ty));
     let dst_ty = dst_datum.ty;
     let dst = load_ty(bcx, dst_datum.val, dst_datum.ty);
 
diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs
index e0a878c8261..4217dd4c671 100644
--- a/src/librustc_trans/trans/glue.rs
+++ b/src/librustc_trans/trans/glue.rs
@@ -84,11 +84,11 @@ pub fn get_drop_glue_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     if !ty::type_is_sized(tcx, t) {
         return t
     }
-    if !ty::type_needs_drop(tcx, t) {
+    if !type_needs_drop(tcx, t) {
         return ty::mk_i8();
     }
     match t.sty {
-        ty::ty_uniq(typ) if !ty::type_needs_drop(tcx, typ)
+        ty::ty_uniq(typ) if !type_needs_drop(tcx, typ)
                          && ty::type_is_sized(tcx, typ) => {
             let llty = sizing_type_of(ccx, typ);
             // `Box<ZeroSizeType>` does not allocate.
@@ -110,7 +110,7 @@ pub fn drop_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     // NB: v is an *alias* of type t here, not a direct value.
     debug!("drop_ty(t={})", t.repr(bcx.tcx()));
     let _icx = push_ctxt("drop_ty");
-    if ty::type_needs_drop(bcx.tcx(), t) {
+    if type_needs_drop(bcx.tcx(), t) {
         let ccx = bcx.ccx();
         let glue = get_drop_glue(ccx, t);
         let glue_type = get_drop_glue_type(ccx, t);
@@ -469,7 +469,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
         ty::ty_vec(ty, None) => tvec::make_drop_glue_unboxed(bcx, v0, ty, false),
         _ => {
             assert!(ty::type_is_sized(bcx.tcx(), t));
-            if ty::type_needs_drop(bcx.tcx(), t) &&
+            if type_needs_drop(bcx.tcx(), t) &&
                 ty::type_is_structural(t) {
                 iter_structural_ty(bcx, v0, t, |bb, vv, tt| drop_ty(bb, vv, tt, None))
             } else {
diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs
index fff89999d99..f471a92f6c3 100644
--- a/src/librustc_trans/trans/intrinsic.rs
+++ b/src/librustc_trans/trans/intrinsic.rs
@@ -365,7 +365,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
         }
         (_, "needs_drop") => {
             let tp_ty = *substs.types.get(FnSpace, 0);
-            C_bool(ccx, ty::type_needs_drop(ccx.tcx(), tp_ty))
+            C_bool(ccx, type_needs_drop(ccx.tcx(), tp_ty))
         }
         (_, "owns_managed") => {
             let tp_ty = *substs.types.get(FnSpace, 0);
diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs
index 553613a8eac..a937f989b3a 100644
--- a/src/librustc_trans/trans/meth.rs
+++ b/src/librustc_trans/trans/meth.rs
@@ -436,7 +436,7 @@ fn trans_trait_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let self_datum = unpack_datum!(
         bcx, expr::trans(bcx, self_expr));
 
-    let llval = if ty::type_needs_drop(bcx.tcx(), self_datum.ty) {
+    let llval = if type_needs_drop(bcx.tcx(), self_datum.ty) {
         let self_datum = unpack_datum!(
             bcx, self_datum.to_rvalue_datum(bcx, "trait_callee"));
 
diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs
index e09032ac2d0..688a0d07250 100644
--- a/src/librustc_trans/trans/tvec.rs
+++ b/src/librustc_trans/trans/tvec.rs
@@ -62,7 +62,7 @@ pub fn make_drop_glue_unboxed<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         let _icx = push_ctxt("tvec::make_drop_glue_unboxed");
 
         let dataptr = get_dataptr(bcx, vptr);
-        let bcx = if ty::type_needs_drop(tcx, unit_ty) {
+        let bcx = if type_needs_drop(tcx, unit_ty) {
             let len = get_len(bcx, vptr);
             iter_vec_raw(bcx, dataptr, unit_ty, len, |bb, vv, tt| glue::drop_ty(bb, vv, tt, None))
         } else {