about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <arielb1@mail.tau.ac.il>2015-08-25 21:52:15 +0300
committerAriel Ben-Yehuda <arielb1@mail.tau.ac.il>2015-08-25 21:52:15 +0300
commit277eeb95c33ce33090409549b184c9977bf535e5 (patch)
treeffdafe17916efc8a73da355053f516d7f90cc721
parentd07ee255d0587f696155f6095f263b53237c0dca (diff)
downloadrust-277eeb95c33ce33090409549b184c9977bf535e5.tar.gz
rust-277eeb95c33ce33090409549b184c9977bf535e5.zip
move destructors_for_type into AdtDef
-rw-r--r--src/librustc/middle/check_const.rs2
-rw-r--r--src/librustc/middle/expr_use_visitor.rs5
-rw-r--r--src/librustc/middle/reachable.rs8
-rw-r--r--src/librustc/middle/ty.rs67
-rw-r--r--src/librustc_borrowck/borrowck/check_loans.rs2
-rw-r--r--src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs2
-rw-r--r--src/librustc_borrowck/borrowck/gather_loans/move_error.rs2
-rw-r--r--src/librustc_lint/builtin.rs18
-rw-r--r--src/librustc_trans/trans/adt.rs4
-rw-r--r--src/librustc_trans/trans/expr.rs2
-rw-r--r--src/librustc_trans/trans/glue.rs9
-rw-r--r--src/librustc_typeck/coherence/mod.rs4
12 files changed, 69 insertions, 56 deletions
diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs
index 1ed43a57041..9153fd6484e 100644
--- a/src/librustc/middle/check_const.rs
+++ b/src/librustc/middle/check_const.rs
@@ -548,7 +548,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                         e: &ast::Expr, node_ty: Ty<'tcx>) {
     match node_ty.sty {
         ty::TyStruct(def, _) |
-        ty::TyEnum(def, _) if def.has_dtor(v.tcx) => {
+        ty::TyEnum(def, _) if def.has_dtor() => {
             v.add_qualif(ConstQualif::NEEDS_DROP);
             if v.mode != Mode::Var {
                 v.tcx.sess.span_err(e.span,
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index ce03e10418d..d8f3ff3d9cb 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -239,8 +239,9 @@ impl OverloadedCallType {
 // mem_categorization, it requires a TYPER, which is a type that
 // supplies types from the tree. After type checking is complete, you
 // can just use the tcx as the typer.
-
-pub struct ExprUseVisitor<'d, 't, 'a: 't, 'tcx:'a+'d> {
+//
+// FIXME(stage0): the :'t here is probably only important for stage0
+pub struct ExprUseVisitor<'d, 't, 'a: 't, 'tcx:'a+'d+'t> {
     typer: &'t infer::InferCtxt<'a, 'tcx>,
     mc: mc::MemCategorizationContext<'t, 'a, 'tcx>,
     delegate: &'d mut (Delegate<'tcx>+'d),
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 206e1f2ba64..4eef0001696 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -355,9 +355,11 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
     // this properly would result in the necessity of computing *type*
     // reachability, which might result in a compile time loss.
     fn mark_destructors_reachable(&mut self) {
-        for (_, destructor_def_id) in self.tcx.destructor_for_type.borrow().iter() {
-            if destructor_def_id.is_local() {
-                self.reachable_symbols.insert(destructor_def_id.node);
+        for adt in self.tcx.adt_defs() {
+            if let Some(destructor_def_id) = adt.destructor() {
+                if destructor_def_id.is_local() {
+                    self.reachable_symbols.insert(destructor_def_id.node);
+                }
             }
         }
     }
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index cb00e3b9baf..e9be9010d4a 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -112,7 +112,7 @@ pub struct CrateAnalysis {
 #[derive(Copy, Clone)]
 pub enum DtorKind {
     NoDtor,
-    TraitDtor(DefId, bool)
+    TraitDtor(bool)
 }
 
 impl DtorKind {
@@ -126,7 +126,7 @@ impl DtorKind {
     pub fn has_drop_flag(&self) -> bool {
         match self {
             &NoDtor => false,
-            &TraitDtor(_, flag) => flag
+            &TraitDtor(flag) => flag
         }
     }
 }
@@ -797,12 +797,6 @@ pub struct ctxt<'tcx> {
     /// True if the variance has been computed yet; false otherwise.
     pub variance_computed: Cell<bool>,
 
-    /// A mapping from the def ID of an enum or struct type to the def ID
-    /// of the method that implements its destructor. If the type is not
-    /// present in this map, it does not have a destructor. This map is
-    /// populated during the coherence phase of typechecking.
-    pub destructor_for_type: RefCell<DefIdMap<DefId>>,
-
     /// A method will be in this list if and only if it is a destructor.
     pub destructors: RefCell<DefIdSet>,
 
@@ -3057,7 +3051,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
             _ => return Err(TypeIsStructural),
         };
 
-        if adt.has_dtor(tcx) {
+        if adt.has_dtor() {
             return Err(TypeHasDestructor)
         }
 
@@ -3262,6 +3256,7 @@ bitflags! {
         const IS_PHANTOM_DATA     = 1 << 3,
         const IS_SIMD             = 1 << 4,
         const IS_FUNDAMENTAL      = 1 << 5,
+        const IS_NO_DROP_FLAG     = 1 << 6,
     }
 }
 
@@ -3312,6 +3307,7 @@ pub struct FieldDefData<'tcx, 'container: 'tcx> {
 pub struct AdtDefData<'tcx, 'container: 'tcx> {
     pub did: DefId,
     pub variants: Vec<VariantDefData<'tcx, 'container>>,
+    destructor: Cell<Option<DefId>>,
     flags: Cell<AdtFlags>,
 }
 
@@ -3347,6 +3343,9 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
         if attr::contains_name(&attrs, "fundamental") {
             flags = flags | AdtFlags::IS_FUNDAMENTAL;
         }
+        if attr::contains_name(&attrs, "unsafe_no_drop_flag") {
+            flags = flags | AdtFlags::IS_NO_DROP_FLAG;
+        }
         if tcx.lookup_simd(did) {
             flags = flags | AdtFlags::IS_SIMD;
         }
@@ -3360,6 +3359,7 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
             did: did,
             variants: variants,
             flags: Cell::new(flags),
+            destructor: Cell::new(None)
         }
     }
 
@@ -3410,8 +3410,11 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
     }
 
     /// Returns whether this type has a destructor.
-    pub fn has_dtor(&self, tcx: &ctxt<'tcx>) -> bool {
-        tcx.destructor_for_type.borrow().contains_key(&self.did)
+    pub fn has_dtor(&self) -> bool {
+        match self.dtor_kind() {
+            NoDtor => false,
+            TraitDtor(..) => true
+        }
     }
 
     /// Asserts this is a struct and returns the struct's unique
@@ -3473,6 +3476,24 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
             _ => panic!("unexpected def {:?} in variant_of_def", def)
         }
     }
+
+    pub fn destructor(&self) -> Option<DefId> {
+        self.destructor.get()
+    }
+
+    pub fn set_destructor(&self, dtor: DefId) {
+        assert!(self.destructor.get().is_none());
+        self.destructor.set(Some(dtor));
+    }
+
+    pub fn dtor_kind(&self) -> DtorKind {
+        match self.destructor.get() {
+            Some(_) => {
+                TraitDtor(!self.flags.get().intersects(AdtFlags::IS_NO_DROP_FLAG))
+            }
+            None => NoDtor,
+        }
+    }
 }
 
 impl<'tcx, 'container> VariantDefData<'tcx, 'container> {
@@ -3856,7 +3877,6 @@ impl<'tcx> ctxt<'tcx> {
             normalized_cache: RefCell::new(FnvHashMap()),
             lang_items: lang_items,
             provided_method_sources: RefCell::new(DefIdMap()),
-            destructor_for_type: RefCell::new(DefIdMap()),
             destructors: RefCell::new(DefIdSet()),
             inherent_impls: RefCell::new(DefIdMap()),
             impl_items: RefCell::new(DefIdMap()),
@@ -4679,7 +4699,7 @@ impl<'tcx> TyS<'tcx> {
                             })
                         });
 
-                    if def.has_dtor(cx) {
+                    if def.has_dtor() {
                         res = res | TC::OwnsDtor;
                     }
 
@@ -6017,18 +6037,6 @@ impl<'tcx> ctxt<'tcx> {
         self.with_path(id, |path| ast_map::path_to_string(path))
     }
 
-    /* If struct_id names a struct with a dtor. */
-    pub fn ty_dtor(&self, struct_id: DefId) -> DtorKind {
-        match self.destructor_for_type.borrow().get(&struct_id) {
-            Some(&method_def_id) => {
-                let flag = !self.has_attr(struct_id, "unsafe_no_drop_flag");
-
-                TraitDtor(method_def_id, flag)
-            }
-            None => NoDtor,
-        }
-    }
-
     pub fn with_path<T, F>(&self, id: DefId, f: F) -> T where
         F: FnOnce(ast_map::PathElems) -> T,
     {
@@ -6113,6 +6121,11 @@ impl<'tcx> ctxt<'tcx> {
         self.lookup_adt_def_master(did)
     }
 
+    /// Return the list of all interned ADT definitions
+    pub fn adt_defs(&self) -> Vec<AdtDef<'tcx>> {
+        self.adt_defs.borrow().values().cloned().collect()
+    }
+
     /// Given the did of an item, returns its full set of predicates.
     pub fn lookup_predicates(&self, did: DefId) -> GenericPredicates<'tcx> {
         lookup_locally_or_in_crate_store(
@@ -6760,8 +6773,8 @@ impl<'tcx> ctxt<'tcx> {
     /// Returns true if this ADT is a dtorck type, i.e. whether it being
     /// safe for destruction requires it to be alive
     fn is_adt_dtorck(&self, adt: AdtDef<'tcx>) -> bool {
-        let dtor_method = match self.destructor_for_type.borrow().get(&adt.did) {
-            Some(dtor) => *dtor,
+        let dtor_method = match adt.destructor() {
+            Some(dtor) => dtor,
             None => return false
         };
         let impl_did = self.impl_of_method(dtor_method).unwrap_or_else(|| {
diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs
index 3e3ce5c7be0..7f9128228a5 100644
--- a/src/librustc_borrowck/borrowck/check_loans.rs
+++ b/src/librustc_borrowck/borrowck/check_loans.rs
@@ -747,7 +747,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
             }
             LpExtend(ref lp_base, _, LpInterior(InteriorField(_))) => {
                 match lp_base.to_type().sty {
-                    ty::TyStruct(def, _) | ty::TyEnum(def, _) if def.has_dtor(self.tcx()) => {
+                    ty::TyStruct(def, _) | ty::TyEnum(def, _) if def.has_dtor() => {
                         // In the case where the owner implements drop, then
                         // the path must be initialized to prevent a case of
                         // partial reinitialization
diff --git a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
index 308ae42c16f..2d08183ba6e 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
@@ -180,7 +180,7 @@ fn check_and_get_illegal_move_origin<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
         mc::cat_interior(ref b, mc::InteriorElement(Kind::Pattern, _)) => {
             match b.ty.sty {
                 ty::TyStruct(def, _) | ty::TyEnum(def, _) => {
-                    if def.has_dtor(bccx.tcx) {
+                    if def.has_dtor() {
                         Some(cmt.clone())
                     } else {
                         check_and_get_illegal_move_origin(bccx, b)
diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
index 1246449327d..465fffe3385 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
@@ -137,7 +137,7 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
         mc::cat_interior(ref b, mc::InteriorField(_)) => {
             match b.ty.sty {
                 ty::TyStruct(def, _) |
-                ty::TyEnum(def, _) if def.has_dtor(bccx.tcx) => {
+                ty::TyEnum(def, _) if def.has_dtor() => {
                     bccx.span_err(
                         move_from.span,
                         &format!("cannot move out of type `{}`, \
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 7af2b3c1bfc..e582b9266cd 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -1952,26 +1952,26 @@ impl LintPass for MissingCopyImplementations {
         if !cx.exported_items.contains(&item.id) {
             return;
         }
-        if cx.tcx.destructor_for_type.borrow().contains_key(&DefId::local(item.id)) {
-            return;
-        }
-        let ty = match item.node {
+        let (def, ty) = match item.node {
             ast::ItemStruct(_, ref ast_generics) => {
                 if ast_generics.is_parameterized() {
                     return;
                 }
-                cx.tcx.mk_struct(cx.tcx.lookup_adt_def(DefId::local(item.id)),
-                                 cx.tcx.mk_substs(Substs::empty()))
+                let def = cx.tcx.lookup_adt_def(DefId::local(item.id));
+                (def, cx.tcx.mk_struct(def,
+                                       cx.tcx.mk_substs(Substs::empty())))
             }
             ast::ItemEnum(_, ref ast_generics) => {
                 if ast_generics.is_parameterized() {
                     return;
                 }
-                cx.tcx.mk_enum(cx.tcx.lookup_adt_def(DefId::local(item.id)),
-                               cx.tcx.mk_substs(Substs::empty()))
+                let def = cx.tcx.lookup_adt_def(DefId::local(item.id));
+                (def, cx.tcx.mk_enum(def,
+                                     cx.tcx.mk_substs(Substs::empty())))
             }
             _ => return,
         };
+        if def.has_dtor() { return; }
         let parameter_environment = cx.tcx.empty_parameter_environment();
         // FIXME (@jroesch) should probably inver this so that the parameter env still impls this
         // method
@@ -2583,7 +2583,7 @@ impl LintPass for DropWithReprExtern {
                     let self_type_did = self_type_def.did;
                     let hints = ctx.tcx.lookup_repr_hints(self_type_did);
                     if hints.iter().any(|attr| *attr == attr::ReprExtern) &&
-                        ctx.tcx.ty_dtor(self_type_did).has_drop_flag() {
+                        self_type_def.dtor_kind().has_drop_flag() {
                         let drop_impl_span = ctx.tcx.map.def_id_span(drop_impl_did,
                                                                      codemap::DUMMY_SP);
                         let self_defn_span = ctx.tcx.map.def_id_span(self_type_did,
diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs
index 46211e6bd01..e425ffcaebf 100644
--- a/src/librustc_trans/trans/adt.rs
+++ b/src/librustc_trans/trans/adt.rs
@@ -250,7 +250,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 monomorphize::field_ty(cx.tcx(), substs, field)
             }).collect::<Vec<_>>();
             let packed = cx.tcx().lookup_packed(def.did);
-            let dtor = cx.tcx().ty_dtor(def.did).has_drop_flag();
+            let dtor = def.dtor_kind().has_drop_flag();
             if dtor {
                 ftys.push(cx.tcx().dtor_type());
             }
@@ -265,7 +265,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             let hint = *cx.tcx().lookup_repr_hints(def.did).get(0)
                 .unwrap_or(&attr::ReprAny);
 
-            let dtor = cx.tcx().ty_dtor(def.did).has_drop_flag();
+            let dtor = def.dtor_kind().has_drop_flag();
 
             if cases.is_empty() {
                 // Uninhabitable; represent as unit
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index efccba91650..64c146e3825 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -1267,7 +1267,7 @@ fn trans_def_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         def::DefStruct(_) => {
             let ty = expr_ty(bcx, ref_expr);
             match ty.sty {
-                ty::TyStruct(def, _) if def.has_dtor(bcx.tcx()) => {
+                ty::TyStruct(def, _) if def.has_dtor() => {
                     let repr = adt::represent_type(bcx.ccx(), ty);
                     adt::trans_set_discr(bcx, &*repr, lldest, 0);
                 }
diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs
index 99495317c20..b72f6bbb451 100644
--- a/src/librustc_trans/trans/glue.rs
+++ b/src/librustc_trans/trans/glue.rs
@@ -356,7 +356,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             traits::VtableImpl(data) => data,
             _ => tcx.sess.bug(&format!("dtor for {:?} is not an impl???", t))
         };
-        let dtor_did = tcx.destructor_for_type.borrow()[&def.did];
+        let dtor_did = def.destructor().unwrap();
         let datum = callee::trans_fn_ref_with_substs(bcx.ccx(),
                                                      dtor_did,
                                                      ExprId(0),
@@ -534,9 +534,8 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, g: DropGlueK
             }
         }
         ty::TyStruct(def, _) | ty::TyEnum(def, _) => {
-            let tcx = bcx.tcx();
-            match (tcx.ty_dtor(def.did), skip_dtor) {
-                (ty::TraitDtor(_, true), false) => {
+            match (def.dtor_kind(), skip_dtor) {
+                (ty::TraitDtor(true), false) => {
                     // FIXME(16758) Since the struct is unsized, it is hard to
                     // find the drop flag (which is at the end of the struct).
                     // Lets just ignore the flag and pretend everything will be
@@ -552,7 +551,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, g: DropGlueK
                         trans_struct_drop(bcx, t, v0)
                     }
                 }
-                (ty::TraitDtor(_, false), false) => {
+                (ty::TraitDtor(false), false) => {
                     trans_struct_drop(bcx, t, v0)
                 }
                 (ty::NoDtor, _) | (_, true) => {
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index aadd74708ab..f8778fbc42d 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -311,9 +311,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
             match self_type.ty.sty {
                 ty::TyEnum(type_def, _) |
                 ty::TyStruct(type_def, _) => {
-                    tcx.destructor_for_type
-                       .borrow_mut()
-                       .insert(type_def.did, method_def_id.def_id());
+                    type_def.set_destructor(method_def_id.def_id());
                     tcx.destructors
                        .borrow_mut()
                        .insert(method_def_id.def_id());