let recursion_depth_reset;
match starting_point {
- TransItem::DropGlue(_) |
+ TransItem::DropGlue(t) => {
+ find_drop_glue_neighbors(ccx, t, &mut neighbors);
+ recursion_depth_reset = None;
+ }
TransItem::Static(_) => {
recursion_depth_reset = None;
}
- TransItem::Fn {
- def_id,
- substs: ref param_substs
- } => {
+ TransItem::Fn { def_id, substs: ref param_substs } => {
// Keep track of the monomorphization recursion depth
recursion_depth_reset = Some(check_recursion_limit(ccx,
def_id,
self.param_substs,
&ty);
let ty = self.ccx.tcx().erase_regions(&ty);
-
- create_drop_glue_trans_items(self.ccx,
- ty,
- self.param_substs,
- &mut self.output);
+ let ty = glue::get_drop_glue_type(self.ccx, ty);
+ self.output.push(TransItem::DropGlue(ty));
}
self.super_lvalue(lvalue, context);
def_id.is_local() || ccx.sess().cstore.is_item_mir_available(def_id)
}
-fn create_drop_glue_trans_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
- mono_ty: ty::Ty<'tcx>,
- param_substs: &'tcx Substs<'tcx>,
- output: &mut Vec<TransItem<'tcx>>)
+fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
+ ty: ty::Ty<'tcx>,
+ output: &mut Vec<TransItem<'tcx>>)
{
- visit_types_of_owned_components(ccx,
- mono_ty,
- &mut FnvHashSet(),
- &mut |ty| {
- debug!("create_drop_glue_trans_items: {}", type_to_string(ccx, ty));
- // Add a translation item for the drop glue, if even this type does not
- // need to be dropped (in which case it has been mapped to i8)
- output.push(TransItem::DropGlue(ty));
-
- if glue::type_needs_drop(ccx.tcx(), ty) {
-
- // Make sure the exchange_free_fn() lang-item gets translated if
- // there is a boxed value.
- if let ty::TyBox(_) = ty.sty {
-
- let exchange_free_fn_def_id = ccx.tcx()
- .lang_items
- .require(ExchangeFreeFnLangItem)
- .expect("Could not find ExchangeFreeFnLangItem");
-
- assert!(can_have_local_instance(ccx, exchange_free_fn_def_id));
- let exchange_free_fn_trans_item =
- create_fn_trans_item(ccx,
- exchange_free_fn_def_id,
- &Substs::trans_empty(),
- param_substs);
-
- output.push(exchange_free_fn_trans_item);
- }
-
- // If the type implements Drop, also add a translation item for the
- // monomorphized Drop::drop() implementation.
- let destructor_did = match ty.sty {
- ty::TyStruct(def, _) |
- ty::TyEnum(def, _) => def.destructor(),
- _ => None
- };
-
- if let Some(destructor_did) = destructor_did {
- use rustc::middle::ty::ToPolyTraitRef;
+ debug!("find_drop_glue_neighbors: {}", type_to_string(ccx, ty));
+
+ // Make sure the exchange_free_fn() lang-item gets translated if
+ // there is a boxed value.
+ if let ty::TyBox(_) = ty.sty {
+ let exchange_free_fn_def_id = ccx.tcx()
+ .lang_items
+ .require(ExchangeFreeFnLangItem)
+ .expect("Could not find ExchangeFreeFnLangItem");
+
+ assert!(can_have_local_instance(ccx, exchange_free_fn_def_id));
+ let exchange_free_fn_trans_item =
+ create_fn_trans_item(ccx,
+ exchange_free_fn_def_id,
+ &Substs::trans_empty(),
+ &Substs::trans_empty());
+
+ output.push(exchange_free_fn_trans_item);
+ }
- let drop_trait_def_id = ccx.tcx()
- .lang_items
- .drop_trait()
- .unwrap();
+ // If the type implements Drop, also add a translation item for the
+ // monomorphized Drop::drop() implementation.
+ let destructor_did = match ty.sty {
+ ty::TyStruct(def, _) |
+ ty::TyEnum(def, _) => def.destructor(),
+ _ => None
+ };
- let self_type_substs = ccx.tcx().mk_substs(
- Substs::trans_empty().with_self_ty(ty));
+ if let Some(destructor_did) = destructor_did {
+ use rustc::middle::ty::ToPolyTraitRef;
- let trait_ref = ty::TraitRef {
- def_id: drop_trait_def_id,
- substs: self_type_substs,
- }.to_poly_trait_ref();
+ let drop_trait_def_id = ccx.tcx()
+ .lang_items
+ .drop_trait()
+ .unwrap();
- let substs = match fulfill_obligation(ccx, DUMMY_SP, trait_ref) {
- traits::VtableImpl(data) => data.substs,
- _ => unreachable!()
- };
-
- if can_have_local_instance(ccx, destructor_did) {
- let trans_item = create_fn_trans_item(ccx,
- destructor_did,
- ccx.tcx().mk_substs(substs),
- param_substs);
- output.push(trans_item);
- }
- }
+ let self_type_substs = ccx.tcx().mk_substs(
+ Substs::trans_empty().with_self_ty(ty));
- true
- } else {
- false
- }
- });
+ let trait_ref = ty::TraitRef {
+ def_id: drop_trait_def_id,
+ substs: self_type_substs,
+ }.to_poly_trait_ref();
- fn visit_types_of_owned_components<'a, 'tcx, F>(ccx: &CrateContext<'a, 'tcx>,
- ty: ty::Ty<'tcx>,
- visited: &mut FnvHashSet<ty::Ty<'tcx>>,
- mut f: &mut F)
- where F: FnMut(ty::Ty<'tcx>) -> bool
- {
- let ty = glue::get_drop_glue_type(ccx, ty);
+ let substs = match fulfill_obligation(ccx, DUMMY_SP, trait_ref) {
+ traits::VtableImpl(data) => data.substs,
+ _ => unreachable!()
+ };
- if !visited.insert(ty) {
- return;
+ if can_have_local_instance(ccx, destructor_did) {
+ let trans_item = create_fn_trans_item(ccx,
+ destructor_did,
+ ccx.tcx().mk_substs(substs),
+ &Substs::trans_empty());
+ output.push(trans_item);
}
+ }
- if !f(ty) {
- // Don't recurse further
- return;
+ // Finally add the types of nested values
+ match ty.sty {
+ ty::TyBool |
+ ty::TyChar |
+ ty::TyInt(_) |
+ ty::TyUint(_) |
+ ty::TyStr |
+ ty::TyFloat(_) |
+ ty::TyRawPtr(_) |
+ ty::TyRef(..) |
+ ty::TyBareFn(..) |
+ ty::TySlice(_) |
+ ty::TyTrait(_) => {
+ /* nothing to do */
}
-
- match ty.sty {
- ty::TyBool |
- ty::TyChar |
- ty::TyInt(_) |
- ty::TyUint(_) |
- ty::TyStr |
- ty::TyFloat(_) |
- ty::TyRawPtr(_) |
- ty::TyRef(..) |
- ty::TyBareFn(..) |
- ty::TySlice(_) |
- ty::TyTrait(_) => {
- /* nothing to do */
- }
- ty::TyStruct(ref adt_def, substs) |
- ty::TyEnum(ref adt_def, substs) => {
- for field in adt_def.all_fields() {
- let field_type = monomorphize::apply_param_substs(ccx.tcx(),
- substs,
- &field.unsubst_ty());
- visit_types_of_owned_components(ccx, field_type, visited, f);
+ ty::TyStruct(ref adt_def, substs) |
+ ty::TyEnum(ref adt_def, substs) => {
+ for field in adt_def.all_fields() {
+ let field_type = monomorphize::apply_param_substs(ccx.tcx(),
+ substs,
+ &field.unsubst_ty());
+ let field_type = glue::get_drop_glue_type(ccx, field_type);
+
+ if glue::type_needs_drop(ccx.tcx(), field_type) {
+ output.push(TransItem::DropGlue(field_type));
}
}
- ty::TyClosure(_, ref substs) => {
- for upvar_ty in &substs.upvar_tys {
- visit_types_of_owned_components(ccx, upvar_ty, visited, f);
+ }
+ ty::TyClosure(_, ref substs) => {
+ for upvar_ty in &substs.upvar_tys {
+ let upvar_ty = glue::get_drop_glue_type(ccx, upvar_ty);
+ if glue::type_needs_drop(ccx.tcx(), upvar_ty) {
+ output.push(TransItem::DropGlue(upvar_ty));
}
}
- ty::TyBox(inner_type) |
- ty::TyArray(inner_type, _) => {
- visit_types_of_owned_components(ccx, inner_type, visited, f);
+ }
+ ty::TyBox(inner_type) |
+ ty::TyArray(inner_type, _) => {
+ let inner_type = glue::get_drop_glue_type(ccx, inner_type);
+ if glue::type_needs_drop(ccx.tcx(), inner_type) {
+ output.push(TransItem::DropGlue(inner_type));
}
- ty::TyTuple(ref args) => {
- for arg in args {
- visit_types_of_owned_components(ccx, arg, visited, f);
+ }
+ ty::TyTuple(ref args) => {
+ for arg in args {
+ let arg = glue::get_drop_glue_type(ccx, arg);
+ if glue::type_needs_drop(ccx.tcx(), arg) {
+ output.push(TransItem::DropGlue(arg));
}
}
- ty::TyProjection(_) |
- ty::TyParam(_) |
- ty::TyInfer(_) |
- ty::TyError => {
- ccx.sess().bug("encountered unexpected type");
- }
+ }
+ ty::TyProjection(_) |
+ ty::TyParam(_) |
+ ty::TyInfer(_) |
+ ty::TyError => {
+ ccx.sess().bug("encountered unexpected type");
}
}
}
self.ccx.tcx().map.local_def_id(item.id),
None));
- create_drop_glue_trans_items(self.ccx,
- ty,
- self.trans_empty_substs,
- self.output);
+ let ty = glue::get_drop_glue_type(self.ccx, ty);
+ self.output.push(TransItem::DropGlue(ty));
}
}
}