Simplify handling of dropping structs.

This commit is contained in:
Mark Simulacrum 2017-01-03 20:54:22 -07:00
parent 7dadd14d6c
commit 21f86ba1bc
2 changed files with 11 additions and 66 deletions

View File

@ -15,7 +15,6 @@
use llvm;
use llvm::{ValueRef, ContextRef, TypeKind};
use llvm::{True, False, Bool, OperandBundleDef};
use rustc::hir::def::Def;
use rustc::hir::def_id::DefId;
use rustc::hir::map::DefPathData;
use rustc::util::common::MemoizationMap;
@ -38,7 +37,7 @@ use std::borrow::Cow;
use std::iter;
use syntax::ast;
use syntax::symbol::{Symbol, InternedString};
use syntax::symbol::InternedString;
use syntax_pos::Span;
use rustc_i128::u128;
@ -169,55 +168,6 @@ pub fn type_is_zero_size<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -
*
*/
use Disr;
/// The concrete version of ty::FieldDef. The name is the field index if
/// the field is numeric.
pub struct Field<'tcx>(pub ast::Name, pub Ty<'tcx>);
/// The concrete version of ty::VariantDef
pub struct VariantInfo<'tcx> {
pub discr: Disr,
pub fields: Vec<Field<'tcx>>
}
impl<'a, 'tcx> VariantInfo<'tcx> {
pub fn from_ty(tcx: TyCtxt<'a, 'tcx, 'tcx>,
ty: Ty<'tcx>,
opt_def: Option<Def>)
-> Self
{
match ty.sty {
ty::TyAdt(adt, substs) => {
let variant = match opt_def {
None => adt.struct_variant(),
Some(def) => adt.variant_of_def(def)
};
VariantInfo {
discr: Disr::from(variant.disr_val),
fields: variant.fields.iter().map(|f| {
Field(f.name, monomorphize::field_ty(tcx, substs, f))
}).collect()
}
}
ty::TyTuple(ref v) => {
VariantInfo {
discr: Disr(0),
fields: v.iter().enumerate().map(|(i, &t)| {
Field(Symbol::intern(&i.to_string()), t)
}).collect()
}
}
_ => {
bug!("cannot get field types from the type {:?}", ty);
}
}
}
}
/// A structure representing an active landing pad for the duration of a basic
/// block.
///

View File

@ -13,6 +13,7 @@
// Code relating to drop glue.
use std;
use std::ptr;
use std::iter;
use llvm;
@ -444,21 +445,15 @@ fn drop_structural_ty<'a, 'tcx>(
}
ty::TyAdt(adt, substs) => match adt.adt_kind() {
AdtKind::Struct => {
let VariantInfo { fields, discr } = VariantInfo::from_ty(cx.tcx(), t, None);
for (i, &Field(_, field_ty)) in fields.iter().enumerate() {
let mut ptr = ptr.clone();
ptr.ty = LvalueTy::Downcast {
adt_def: adt,
substs: substs,
variant_index: Disr::from(discr).0 as usize,
};
let llfld_a = ptr.trans_field_ptr(&cx, i);
let ptr = if cx.ccx.shared().type_is_sized(field_ty) {
LvalueRef::new_sized_ty(llfld_a, field_ty)
} else {
LvalueRef::new_unsized_ty(llfld_a, ptr.llextra, field_ty)
};
drop_ty(&cx, ptr);
for (i, field) in adt.variants[0].fields.iter().enumerate() {
let field_ty = monomorphize::field_ty(cx.tcx(), substs, field);
let mut field_ptr = ptr.clone();
field_ptr.llval = ptr.trans_field_ptr(&cx, i);
field_ptr.ty = LvalueTy::from_ty(field_ty);
if cx.ccx.shared().type_is_sized(field_ty) {
field_ptr.llextra = ptr::null_mut();
}
drop_ty(&cx, field_ptr);
}
}
AdtKind::Union => {