Skip to content

Commit 277eeb9

Browse files
author
Ariel Ben-Yehuda
committed
move destructors_for_type into AdtDef
1 parent d07ee25 commit 277eeb9

File tree

12 files changed

+69
-56
lines changed

12 files changed

+69
-56
lines changed

src/librustc/middle/check_const.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
548548
e: &ast::Expr, node_ty: Ty<'tcx>) {
549549
match node_ty.sty {
550550
ty::TyStruct(def, _) |
551-
ty::TyEnum(def, _) if def.has_dtor(v.tcx) => {
551+
ty::TyEnum(def, _) if def.has_dtor() => {
552552
v.add_qualif(ConstQualif::NEEDS_DROP);
553553
if v.mode != Mode::Var {
554554
v.tcx.sess.span_err(e.span,

src/librustc/middle/expr_use_visitor.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,9 @@ impl OverloadedCallType {
239239
// mem_categorization, it requires a TYPER, which is a type that
240240
// supplies types from the tree. After type checking is complete, you
241241
// can just use the tcx as the typer.
242-
243-
pub struct ExprUseVisitor<'d, 't, 'a: 't, 'tcx:'a+'d> {
242+
//
243+
// FIXME(stage0): the :'t here is probably only important for stage0
244+
pub struct ExprUseVisitor<'d, 't, 'a: 't, 'tcx:'a+'d+'t> {
244245
typer: &'t infer::InferCtxt<'a, 'tcx>,
245246
mc: mc::MemCategorizationContext<'t, 'a, 'tcx>,
246247
delegate: &'d mut (Delegate<'tcx>+'d),

src/librustc/middle/reachable.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,9 +355,11 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
355355
// this properly would result in the necessity of computing *type*
356356
// reachability, which might result in a compile time loss.
357357
fn mark_destructors_reachable(&mut self) {
358-
for (_, destructor_def_id) in self.tcx.destructor_for_type.borrow().iter() {
359-
if destructor_def_id.is_local() {
360-
self.reachable_symbols.insert(destructor_def_id.node);
358+
for adt in self.tcx.adt_defs() {
359+
if let Some(destructor_def_id) = adt.destructor() {
360+
if destructor_def_id.is_local() {
361+
self.reachable_symbols.insert(destructor_def_id.node);
362+
}
361363
}
362364
}
363365
}

src/librustc/middle/ty.rs

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ pub struct CrateAnalysis {
112112
#[derive(Copy, Clone)]
113113
pub enum DtorKind {
114114
NoDtor,
115-
TraitDtor(DefId, bool)
115+
TraitDtor(bool)
116116
}
117117

118118
impl DtorKind {
@@ -126,7 +126,7 @@ impl DtorKind {
126126
pub fn has_drop_flag(&self) -> bool {
127127
match self {
128128
&NoDtor => false,
129-
&TraitDtor(_, flag) => flag
129+
&TraitDtor(flag) => flag
130130
}
131131
}
132132
}
@@ -797,12 +797,6 @@ pub struct ctxt<'tcx> {
797797
/// True if the variance has been computed yet; false otherwise.
798798
pub variance_computed: Cell<bool>,
799799

800-
/// A mapping from the def ID of an enum or struct type to the def ID
801-
/// of the method that implements its destructor. If the type is not
802-
/// present in this map, it does not have a destructor. This map is
803-
/// populated during the coherence phase of typechecking.
804-
pub destructor_for_type: RefCell<DefIdMap<DefId>>,
805-
806800
/// A method will be in this list if and only if it is a destructor.
807801
pub destructors: RefCell<DefIdSet>,
808802

@@ -3057,7 +3051,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
30573051
_ => return Err(TypeIsStructural),
30583052
};
30593053

3060-
if adt.has_dtor(tcx) {
3054+
if adt.has_dtor() {
30613055
return Err(TypeHasDestructor)
30623056
}
30633057

@@ -3262,6 +3256,7 @@ bitflags! {
32623256
const IS_PHANTOM_DATA = 1 << 3,
32633257
const IS_SIMD = 1 << 4,
32643258
const IS_FUNDAMENTAL = 1 << 5,
3259+
const IS_NO_DROP_FLAG = 1 << 6,
32653260
}
32663261
}
32673262

@@ -3312,6 +3307,7 @@ pub struct FieldDefData<'tcx, 'container: 'tcx> {
33123307
pub struct AdtDefData<'tcx, 'container: 'tcx> {
33133308
pub did: DefId,
33143309
pub variants: Vec<VariantDefData<'tcx, 'container>>,
3310+
destructor: Cell<Option<DefId>>,
33153311
flags: Cell<AdtFlags>,
33163312
}
33173313

@@ -3347,6 +3343,9 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
33473343
if attr::contains_name(&attrs, "fundamental") {
33483344
flags = flags | AdtFlags::IS_FUNDAMENTAL;
33493345
}
3346+
if attr::contains_name(&attrs, "unsafe_no_drop_flag") {
3347+
flags = flags | AdtFlags::IS_NO_DROP_FLAG;
3348+
}
33503349
if tcx.lookup_simd(did) {
33513350
flags = flags | AdtFlags::IS_SIMD;
33523351
}
@@ -3360,6 +3359,7 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
33603359
did: did,
33613360
variants: variants,
33623361
flags: Cell::new(flags),
3362+
destructor: Cell::new(None)
33633363
}
33643364
}
33653365

@@ -3410,8 +3410,11 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
34103410
}
34113411

34123412
/// Returns whether this type has a destructor.
3413-
pub fn has_dtor(&self, tcx: &ctxt<'tcx>) -> bool {
3414-
tcx.destructor_for_type.borrow().contains_key(&self.did)
3413+
pub fn has_dtor(&self) -> bool {
3414+
match self.dtor_kind() {
3415+
NoDtor => false,
3416+
TraitDtor(..) => true
3417+
}
34153418
}
34163419

34173420
/// Asserts this is a struct and returns the struct's unique
@@ -3473,6 +3476,24 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
34733476
_ => panic!("unexpected def {:?} in variant_of_def", def)
34743477
}
34753478
}
3479+
3480+
pub fn destructor(&self) -> Option<DefId> {
3481+
self.destructor.get()
3482+
}
3483+
3484+
pub fn set_destructor(&self, dtor: DefId) {
3485+
assert!(self.destructor.get().is_none());
3486+
self.destructor.set(Some(dtor));
3487+
}
3488+
3489+
pub fn dtor_kind(&self) -> DtorKind {
3490+
match self.destructor.get() {
3491+
Some(_) => {
3492+
TraitDtor(!self.flags.get().intersects(AdtFlags::IS_NO_DROP_FLAG))
3493+
}
3494+
None => NoDtor,
3495+
}
3496+
}
34763497
}
34773498

34783499
impl<'tcx, 'container> VariantDefData<'tcx, 'container> {
@@ -3856,7 +3877,6 @@ impl<'tcx> ctxt<'tcx> {
38563877
normalized_cache: RefCell::new(FnvHashMap()),
38573878
lang_items: lang_items,
38583879
provided_method_sources: RefCell::new(DefIdMap()),
3859-
destructor_for_type: RefCell::new(DefIdMap()),
38603880
destructors: RefCell::new(DefIdSet()),
38613881
inherent_impls: RefCell::new(DefIdMap()),
38623882
impl_items: RefCell::new(DefIdMap()),
@@ -4679,7 +4699,7 @@ impl<'tcx> TyS<'tcx> {
46794699
})
46804700
});
46814701

4682-
if def.has_dtor(cx) {
4702+
if def.has_dtor() {
46834703
res = res | TC::OwnsDtor;
46844704
}
46854705

@@ -6017,18 +6037,6 @@ impl<'tcx> ctxt<'tcx> {
60176037
self.with_path(id, |path| ast_map::path_to_string(path))
60186038
}
60196039

6020-
/* If struct_id names a struct with a dtor. */
6021-
pub fn ty_dtor(&self, struct_id: DefId) -> DtorKind {
6022-
match self.destructor_for_type.borrow().get(&struct_id) {
6023-
Some(&method_def_id) => {
6024-
let flag = !self.has_attr(struct_id, "unsafe_no_drop_flag");
6025-
6026-
TraitDtor(method_def_id, flag)
6027-
}
6028-
None => NoDtor,
6029-
}
6030-
}
6031-
60326040
pub fn with_path<T, F>(&self, id: DefId, f: F) -> T where
60336041
F: FnOnce(ast_map::PathElems) -> T,
60346042
{
@@ -6113,6 +6121,11 @@ impl<'tcx> ctxt<'tcx> {
61136121
self.lookup_adt_def_master(did)
61146122
}
61156123

6124+
/// Return the list of all interned ADT definitions
6125+
pub fn adt_defs(&self) -> Vec<AdtDef<'tcx>> {
6126+
self.adt_defs.borrow().values().cloned().collect()
6127+
}
6128+
61166129
/// Given the did of an item, returns its full set of predicates.
61176130
pub fn lookup_predicates(&self, did: DefId) -> GenericPredicates<'tcx> {
61186131
lookup_locally_or_in_crate_store(
@@ -6760,8 +6773,8 @@ impl<'tcx> ctxt<'tcx> {
67606773
/// Returns true if this ADT is a dtorck type, i.e. whether it being
67616774
/// safe for destruction requires it to be alive
67626775
fn is_adt_dtorck(&self, adt: AdtDef<'tcx>) -> bool {
6763-
let dtor_method = match self.destructor_for_type.borrow().get(&adt.did) {
6764-
Some(dtor) => *dtor,
6776+
let dtor_method = match adt.destructor() {
6777+
Some(dtor) => dtor,
67656778
None => return false
67666779
};
67676780
let impl_did = self.impl_of_method(dtor_method).unwrap_or_else(|| {

src/librustc_borrowck/borrowck/check_loans.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
747747
}
748748
LpExtend(ref lp_base, _, LpInterior(InteriorField(_))) => {
749749
match lp_base.to_type().sty {
750-
ty::TyStruct(def, _) | ty::TyEnum(def, _) if def.has_dtor(self.tcx()) => {
750+
ty::TyStruct(def, _) | ty::TyEnum(def, _) if def.has_dtor() => {
751751
// In the case where the owner implements drop, then
752752
// the path must be initialized to prevent a case of
753753
// partial reinitialization

src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ fn check_and_get_illegal_move_origin<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
180180
mc::cat_interior(ref b, mc::InteriorElement(Kind::Pattern, _)) => {
181181
match b.ty.sty {
182182
ty::TyStruct(def, _) | ty::TyEnum(def, _) => {
183-
if def.has_dtor(bccx.tcx) {
183+
if def.has_dtor() {
184184
Some(cmt.clone())
185185
} else {
186186
check_and_get_illegal_move_origin(bccx, b)

src/librustc_borrowck/borrowck/gather_loans/move_error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
137137
mc::cat_interior(ref b, mc::InteriorField(_)) => {
138138
match b.ty.sty {
139139
ty::TyStruct(def, _) |
140-
ty::TyEnum(def, _) if def.has_dtor(bccx.tcx) => {
140+
ty::TyEnum(def, _) if def.has_dtor() => {
141141
bccx.span_err(
142142
move_from.span,
143143
&format!("cannot move out of type `{}`, \

src/librustc_lint/builtin.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1952,26 +1952,26 @@ impl LintPass for MissingCopyImplementations {
19521952
if !cx.exported_items.contains(&item.id) {
19531953
return;
19541954
}
1955-
if cx.tcx.destructor_for_type.borrow().contains_key(&DefId::local(item.id)) {
1956-
return;
1957-
}
1958-
let ty = match item.node {
1955+
let (def, ty) = match item.node {
19591956
ast::ItemStruct(_, ref ast_generics) => {
19601957
if ast_generics.is_parameterized() {
19611958
return;
19621959
}
1963-
cx.tcx.mk_struct(cx.tcx.lookup_adt_def(DefId::local(item.id)),
1964-
cx.tcx.mk_substs(Substs::empty()))
1960+
let def = cx.tcx.lookup_adt_def(DefId::local(item.id));
1961+
(def, cx.tcx.mk_struct(def,
1962+
cx.tcx.mk_substs(Substs::empty())))
19651963
}
19661964
ast::ItemEnum(_, ref ast_generics) => {
19671965
if ast_generics.is_parameterized() {
19681966
return;
19691967
}
1970-
cx.tcx.mk_enum(cx.tcx.lookup_adt_def(DefId::local(item.id)),
1971-
cx.tcx.mk_substs(Substs::empty()))
1968+
let def = cx.tcx.lookup_adt_def(DefId::local(item.id));
1969+
(def, cx.tcx.mk_enum(def,
1970+
cx.tcx.mk_substs(Substs::empty())))
19721971
}
19731972
_ => return,
19741973
};
1974+
if def.has_dtor() { return; }
19751975
let parameter_environment = cx.tcx.empty_parameter_environment();
19761976
// FIXME (@jroesch) should probably inver this so that the parameter env still impls this
19771977
// method
@@ -2583,7 +2583,7 @@ impl LintPass for DropWithReprExtern {
25832583
let self_type_did = self_type_def.did;
25842584
let hints = ctx.tcx.lookup_repr_hints(self_type_did);
25852585
if hints.iter().any(|attr| *attr == attr::ReprExtern) &&
2586-
ctx.tcx.ty_dtor(self_type_did).has_drop_flag() {
2586+
self_type_def.dtor_kind().has_drop_flag() {
25872587
let drop_impl_span = ctx.tcx.map.def_id_span(drop_impl_did,
25882588
codemap::DUMMY_SP);
25892589
let self_defn_span = ctx.tcx.map.def_id_span(self_type_did,

src/librustc_trans/trans/adt.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
250250
monomorphize::field_ty(cx.tcx(), substs, field)
251251
}).collect::<Vec<_>>();
252252
let packed = cx.tcx().lookup_packed(def.did);
253-
let dtor = cx.tcx().ty_dtor(def.did).has_drop_flag();
253+
let dtor = def.dtor_kind().has_drop_flag();
254254
if dtor {
255255
ftys.push(cx.tcx().dtor_type());
256256
}
@@ -265,7 +265,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
265265
let hint = *cx.tcx().lookup_repr_hints(def.did).get(0)
266266
.unwrap_or(&attr::ReprAny);
267267

268-
let dtor = cx.tcx().ty_dtor(def.did).has_drop_flag();
268+
let dtor = def.dtor_kind().has_drop_flag();
269269

270270
if cases.is_empty() {
271271
// Uninhabitable; represent as unit

src/librustc_trans/trans/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1267,7 +1267,7 @@ fn trans_def_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
12671267
def::DefStruct(_) => {
12681268
let ty = expr_ty(bcx, ref_expr);
12691269
match ty.sty {
1270-
ty::TyStruct(def, _) if def.has_dtor(bcx.tcx()) => {
1270+
ty::TyStruct(def, _) if def.has_dtor() => {
12711271
let repr = adt::represent_type(bcx.ccx(), ty);
12721272
adt::trans_set_discr(bcx, &*repr, lldest, 0);
12731273
}

src/librustc_trans/trans/glue.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
356356
traits::VtableImpl(data) => data,
357357
_ => tcx.sess.bug(&format!("dtor for {:?} is not an impl???", t))
358358
};
359-
let dtor_did = tcx.destructor_for_type.borrow()[&def.did];
359+
let dtor_did = def.destructor().unwrap();
360360
let datum = callee::trans_fn_ref_with_substs(bcx.ccx(),
361361
dtor_did,
362362
ExprId(0),
@@ -534,9 +534,8 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, g: DropGlueK
534534
}
535535
}
536536
ty::TyStruct(def, _) | ty::TyEnum(def, _) => {
537-
let tcx = bcx.tcx();
538-
match (tcx.ty_dtor(def.did), skip_dtor) {
539-
(ty::TraitDtor(_, true), false) => {
537+
match (def.dtor_kind(), skip_dtor) {
538+
(ty::TraitDtor(true), false) => {
540539
// FIXME(16758) Since the struct is unsized, it is hard to
541540
// find the drop flag (which is at the end of the struct).
542541
// 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
552551
trans_struct_drop(bcx, t, v0)
553552
}
554553
}
555-
(ty::TraitDtor(_, false), false) => {
554+
(ty::TraitDtor(false), false) => {
556555
trans_struct_drop(bcx, t, v0)
557556
}
558557
(ty::NoDtor, _) | (_, true) => {

src/librustc_typeck/coherence/mod.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,9 +311,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
311311
match self_type.ty.sty {
312312
ty::TyEnum(type_def, _) |
313313
ty::TyStruct(type_def, _) => {
314-
tcx.destructor_for_type
315-
.borrow_mut()
316-
.insert(type_def.did, method_def_id.def_id());
314+
type_def.set_destructor(method_def_id.def_id());
317315
tcx.destructors
318316
.borrow_mut()
319317
.insert(method_def_id.def_id());

0 commit comments

Comments
 (0)