diff options
| author | Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> | 2015-08-25 21:52:15 +0300 |
|---|---|---|
| committer | Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> | 2015-08-25 21:52:15 +0300 |
| commit | 277eeb95c33ce33090409549b184c9977bf535e5 (patch) | |
| tree | ffdafe17916efc8a73da355053f516d7f90cc721 | |
| parent | d07ee255d0587f696155f6095f263b53237c0dca (diff) | |
| download | rust-277eeb95c33ce33090409549b184c9977bf535e5.tar.gz rust-277eeb95c33ce33090409549b184c9977bf535e5.zip | |
move destructors_for_type into AdtDef
| -rw-r--r-- | src/librustc/middle/check_const.rs | 2 | ||||
| -rw-r--r-- | src/librustc/middle/expr_use_visitor.rs | 5 | ||||
| -rw-r--r-- | src/librustc/middle/reachable.rs | 8 | ||||
| -rw-r--r-- | src/librustc/middle/ty.rs | 67 | ||||
| -rw-r--r-- | src/librustc_borrowck/borrowck/check_loans.rs | 2 | ||||
| -rw-r--r-- | src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs | 2 | ||||
| -rw-r--r-- | src/librustc_borrowck/borrowck/gather_loans/move_error.rs | 2 | ||||
| -rw-r--r-- | src/librustc_lint/builtin.rs | 18 | ||||
| -rw-r--r-- | src/librustc_trans/trans/adt.rs | 4 | ||||
| -rw-r--r-- | src/librustc_trans/trans/expr.rs | 2 | ||||
| -rw-r--r-- | src/librustc_trans/trans/glue.rs | 9 | ||||
| -rw-r--r-- | src/librustc_typeck/coherence/mod.rs | 4 |
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()); |
