@@ -350,14 +350,14 @@ fn collect_items_rec<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>,
350350 let recursion_depth_reset;
351351
352352 match starting_point {
353- TransItem :: DropGlue ( _) |
353+ TransItem :: DropGlue ( t) => {
354+ find_drop_glue_neighbors ( ccx, t, & mut neighbors) ;
355+ recursion_depth_reset = None ;
356+ }
354357 TransItem :: Static ( _) => {
355358 recursion_depth_reset = None ;
356359 }
357- TransItem :: Fn {
358- def_id,
359- substs : ref param_substs
360- } => {
360+ TransItem :: Fn { def_id, substs : ref param_substs } => {
361361 // Keep track of the monomorphization recursion depth
362362 recursion_depth_reset = Some ( check_recursion_limit ( ccx,
363363 def_id,
@@ -531,11 +531,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
531531 self . param_substs ,
532532 & ty) ;
533533 let ty = self . ccx . tcx ( ) . erase_regions ( & ty) ;
534-
535- create_drop_glue_trans_items ( self . ccx ,
536- ty,
537- self . param_substs ,
538- & mut self . output ) ;
534+ let ty = glue:: get_drop_glue_type ( self . ccx , ty) ;
535+ self . output . push ( TransItem :: DropGlue ( ty) ) ;
539536 }
540537
541538 self . super_lvalue ( lvalue, context) ;
@@ -636,145 +633,124 @@ fn can_have_local_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
636633 def_id. is_local ( ) || ccx. sess ( ) . cstore . is_item_mir_available ( def_id)
637634}
638635
639- fn create_drop_glue_trans_items < ' a , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > ,
640- mono_ty : ty:: Ty < ' tcx > ,
641- param_substs : & ' tcx Substs < ' tcx > ,
642- output : & mut Vec < TransItem < ' tcx > > )
636+ fn find_drop_glue_neighbors < ' a , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > ,
637+ ty : ty:: Ty < ' tcx > ,
638+ output : & mut Vec < TransItem < ' tcx > > )
643639{
644- visit_types_of_owned_components ( ccx,
645- mono_ty,
646- & mut FnvHashSet ( ) ,
647- & mut |ty| {
648- debug ! ( "create_drop_glue_trans_items: {}" , type_to_string( ccx, ty) ) ;
649- // Add a translation item for the drop glue, if even this type does not
650- // need to be dropped (in which case it has been mapped to i8)
651- output. push ( TransItem :: DropGlue ( ty) ) ;
652-
653- if glue:: type_needs_drop ( ccx. tcx ( ) , ty) {
654-
655- // Make sure the exchange_free_fn() lang-item gets translated if
656- // there is a boxed value.
657- if let ty:: TyBox ( _) = ty. sty {
658-
659- let exchange_free_fn_def_id = ccx. tcx ( )
660- . lang_items
661- . require ( ExchangeFreeFnLangItem )
662- . expect ( "Could not find ExchangeFreeFnLangItem" ) ;
663-
664- assert ! ( can_have_local_instance( ccx, exchange_free_fn_def_id) ) ;
665- let exchange_free_fn_trans_item =
666- create_fn_trans_item ( ccx,
667- exchange_free_fn_def_id,
668- & Substs :: trans_empty ( ) ,
669- param_substs) ;
670-
671- output. push ( exchange_free_fn_trans_item) ;
672- }
673-
674- // If the type implements Drop, also add a translation item for the
675- // monomorphized Drop::drop() implementation.
676- let destructor_did = match ty. sty {
677- ty:: TyStruct ( def, _) |
678- ty:: TyEnum ( def, _) => def. destructor ( ) ,
679- _ => None
680- } ;
681-
682- if let Some ( destructor_did) = destructor_did {
683- use rustc:: middle:: ty:: ToPolyTraitRef ;
640+ debug ! ( "find_drop_glue_neighbors: {}" , type_to_string( ccx, ty) ) ;
641+
642+ // Make sure the exchange_free_fn() lang-item gets translated if
643+ // there is a boxed value.
644+ if let ty:: TyBox ( _) = ty. sty {
645+ let exchange_free_fn_def_id = ccx. tcx ( )
646+ . lang_items
647+ . require ( ExchangeFreeFnLangItem )
648+ . expect ( "Could not find ExchangeFreeFnLangItem" ) ;
649+
650+ assert ! ( can_have_local_instance( ccx, exchange_free_fn_def_id) ) ;
651+ let exchange_free_fn_trans_item =
652+ create_fn_trans_item ( ccx,
653+ exchange_free_fn_def_id,
654+ & Substs :: trans_empty ( ) ,
655+ & Substs :: trans_empty ( ) ) ;
656+
657+ output. push ( exchange_free_fn_trans_item) ;
658+ }
684659
685- let drop_trait_def_id = ccx. tcx ( )
686- . lang_items
687- . drop_trait ( )
688- . unwrap ( ) ;
660+ // If the type implements Drop, also add a translation item for the
661+ // monomorphized Drop::drop() implementation.
662+ let destructor_did = match ty. sty {
663+ ty:: TyStruct ( def, _) |
664+ ty:: TyEnum ( def, _) => def. destructor ( ) ,
665+ _ => None
666+ } ;
689667
690- let self_type_substs = ccx . tcx ( ) . mk_substs (
691- Substs :: trans_empty ( ) . with_self_ty ( ty ) ) ;
668+ if let Some ( destructor_did ) = destructor_did {
669+ use rustc :: middle :: ty :: ToPolyTraitRef ;
692670
693- let trait_ref = ty :: TraitRef {
694- def_id : drop_trait_def_id ,
695- substs : self_type_substs ,
696- } . to_poly_trait_ref ( ) ;
671+ let drop_trait_def_id = ccx . tcx ( )
672+ . lang_items
673+ . drop_trait ( )
674+ . unwrap ( ) ;
697675
698- let substs = match fulfill_obligation ( ccx, DUMMY_SP , trait_ref) {
699- traits:: VtableImpl ( data) => data. substs ,
700- _ => unreachable ! ( )
701- } ;
702-
703- if can_have_local_instance ( ccx, destructor_did) {
704- let trans_item = create_fn_trans_item ( ccx,
705- destructor_did,
706- ccx. tcx ( ) . mk_substs ( substs) ,
707- param_substs) ;
708- output. push ( trans_item) ;
709- }
710- }
676+ let self_type_substs = ccx. tcx ( ) . mk_substs (
677+ Substs :: trans_empty ( ) . with_self_ty ( ty) ) ;
711678
712- true
713- } else {
714- false
715- }
716- } ) ;
679+ let trait_ref = ty:: TraitRef {
680+ def_id : drop_trait_def_id,
681+ substs : self_type_substs,
682+ } . to_poly_trait_ref ( ) ;
717683
718- fn visit_types_of_owned_components < ' a , ' tcx , F > ( ccx : & CrateContext < ' a , ' tcx > ,
719- ty : ty:: Ty < ' tcx > ,
720- visited : & mut FnvHashSet < ty:: Ty < ' tcx > > ,
721- mut f : & mut F )
722- where F : FnMut ( ty:: Ty < ' tcx > ) -> bool
723- {
724- let ty = glue:: get_drop_glue_type ( ccx, ty) ;
684+ let substs = match fulfill_obligation ( ccx, DUMMY_SP , trait_ref) {
685+ traits:: VtableImpl ( data) => data. substs ,
686+ _ => unreachable ! ( )
687+ } ;
725688
726- if !visited. insert ( ty) {
727- return ;
689+ if can_have_local_instance ( ccx, destructor_did) {
690+ let trans_item = create_fn_trans_item ( ccx,
691+ destructor_did,
692+ ccx. tcx ( ) . mk_substs ( substs) ,
693+ & Substs :: trans_empty ( ) ) ;
694+ output. push ( trans_item) ;
728695 }
696+ }
729697
730- if !f ( ty) {
731- // Don't recurse further
732- return ;
698+ // Finally add the types of nested values
699+ match ty. sty {
700+ ty:: TyBool |
701+ ty:: TyChar |
702+ ty:: TyInt ( _) |
703+ ty:: TyUint ( _) |
704+ ty:: TyStr |
705+ ty:: TyFloat ( _) |
706+ ty:: TyRawPtr ( _) |
707+ ty:: TyRef ( ..) |
708+ ty:: TyBareFn ( ..) |
709+ ty:: TySlice ( _) |
710+ ty:: TyTrait ( _) => {
711+ /* nothing to do */
733712 }
734-
735- match ty. sty {
736- ty:: TyBool |
737- ty:: TyChar |
738- ty:: TyInt ( _) |
739- ty:: TyUint ( _) |
740- ty:: TyStr |
741- ty:: TyFloat ( _) |
742- ty:: TyRawPtr ( _) |
743- ty:: TyRef ( ..) |
744- ty:: TyBareFn ( ..) |
745- ty:: TySlice ( _) |
746- ty:: TyTrait ( _) => {
747- /* nothing to do */
748- }
749- ty:: TyStruct ( ref adt_def, substs) |
750- ty:: TyEnum ( ref adt_def, substs) => {
751- for field in adt_def. all_fields ( ) {
752- let field_type = monomorphize:: apply_param_substs ( ccx. tcx ( ) ,
753- substs,
754- & field. unsubst_ty ( ) ) ;
755- visit_types_of_owned_components ( ccx, field_type, visited, f) ;
713+ ty:: TyStruct ( ref adt_def, substs) |
714+ ty:: TyEnum ( ref adt_def, substs) => {
715+ for field in adt_def. all_fields ( ) {
716+ let field_type = monomorphize:: apply_param_substs ( ccx. tcx ( ) ,
717+ substs,
718+ & field. unsubst_ty ( ) ) ;
719+ let field_type = glue:: get_drop_glue_type ( ccx, field_type) ;
720+
721+ if glue:: type_needs_drop ( ccx. tcx ( ) , field_type) {
722+ output. push ( TransItem :: DropGlue ( field_type) ) ;
756723 }
757724 }
758- ty:: TyClosure ( _, ref substs) => {
759- for upvar_ty in & substs. upvar_tys {
760- visit_types_of_owned_components ( ccx, upvar_ty, visited, f) ;
725+ }
726+ ty:: TyClosure ( _, ref substs) => {
727+ for upvar_ty in & substs. upvar_tys {
728+ let upvar_ty = glue:: get_drop_glue_type ( ccx, upvar_ty) ;
729+ if glue:: type_needs_drop ( ccx. tcx ( ) , upvar_ty) {
730+ output. push ( TransItem :: DropGlue ( upvar_ty) ) ;
761731 }
762732 }
763- ty:: TyBox ( inner_type) |
764- ty:: TyArray ( inner_type, _) => {
765- visit_types_of_owned_components ( ccx, inner_type, visited, f) ;
733+ }
734+ ty:: TyBox ( inner_type) |
735+ ty:: TyArray ( inner_type, _) => {
736+ let inner_type = glue:: get_drop_glue_type ( ccx, inner_type) ;
737+ if glue:: type_needs_drop ( ccx. tcx ( ) , inner_type) {
738+ output. push ( TransItem :: DropGlue ( inner_type) ) ;
766739 }
767- ty:: TyTuple ( ref args) => {
768- for arg in args {
769- visit_types_of_owned_components ( ccx, arg, visited, f) ;
740+ }
741+ ty:: TyTuple ( ref args) => {
742+ for arg in args {
743+ let arg = glue:: get_drop_glue_type ( ccx, arg) ;
744+ if glue:: type_needs_drop ( ccx. tcx ( ) , arg) {
745+ output. push ( TransItem :: DropGlue ( arg) ) ;
770746 }
771747 }
772- ty :: TyProjection ( _ ) |
773- ty:: TyParam ( _) |
774- ty:: TyInfer ( _) |
775- ty:: TyError => {
776- ccx . sess ( ) . bug ( "encountered unexpected type" ) ;
777- }
748+ }
749+ ty:: TyProjection ( _) |
750+ ty:: TyParam ( _) |
751+ ty:: TyInfer ( _ ) |
752+ ty :: TyError => {
753+ ccx . sess ( ) . bug ( "encountered unexpected type" ) ;
778754 }
779755 }
780756}
@@ -1086,10 +1062,8 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> {
10861062 self . ccx. tcx( ) . map. local_def_id( item. id) ,
10871063 None ) ) ;
10881064
1089- create_drop_glue_trans_items ( self . ccx ,
1090- ty,
1091- self . trans_empty_substs ,
1092- self . output ) ;
1065+ let ty = glue:: get_drop_glue_type ( self . ccx , ty) ;
1066+ self . output . push ( TransItem :: DropGlue ( ty) ) ;
10931067 }
10941068 }
10951069 }
0 commit comments