mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 02:33:55 +00:00
move destructors_for_type into AdtDef
This commit is contained in:
parent
d07ee255d0
commit
277eeb95c3
@ -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,
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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(|| {
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 `{}`, \
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) => {
|
||||
|
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user