@@ -450,41 +450,57 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
450450
451451 let dtor_typescheme = ty:: lookup_item_type ( rcx. tcx ( ) , impl_did) ;
452452 let dtor_generics = dtor_typescheme. generics ;
453- let dtor_predicates = ty:: lookup_predicates ( rcx. tcx ( ) , impl_did) ;
454-
455- let has_pred_of_interest = dtor_predicates. predicates . iter ( ) . any ( |pred| {
456- // In `impl<T> Drop where ...`, assume most predicates
457- // represent capability on `T` via which a destructor
458- // could access borrowed data. But some bounds (Sized,
459- // Copy, etc), have no items, i.e. no added capabilty
460- // for such type-specific access.
461-
462- let result = match * pred {
463- ty:: Predicate :: Trait ( ty:: Binder ( ref t_pred) ) => {
464- let def_id = t_pred. trait_ref . def_id ;
465- // A OIBIT (or even a normal builtin) trait
466- // defines no associated items, and is
467- // uninteresting from point of view of dropck.
468- ty:: trait_items ( rcx. tcx ( ) , def_id) . len ( ) != 0
469- }
470- ty:: Predicate :: Equate ( ..) |
471- ty:: Predicate :: RegionOutlives ( ..) |
472- ty:: Predicate :: TypeOutlives ( ..) |
473- ty:: Predicate :: Projection ( ..) => {
474- // for now, assume all other where-clauses may
475- // give the drop implementation the capabilty
476- // to access borrowed data.
477- true
478- }
479- } ;
480453
481- if result {
482- debug ! ( "typ: {} has interesting dtor due to generic preds, e.g. {}" ,
483- typ. repr( rcx. tcx( ) ) , pred. repr( rcx. tcx( ) ) ) ;
454+ let mut has_pred_of_interest = false ;
455+
456+ let mut seen_items = Vec :: new ( ) ;
457+ let mut items_to_inspect = vec ! [ impl_did] ;
458+ ' items: while let Some ( item_def_id) = items_to_inspect. pop ( ) {
459+ if seen_items. contains ( & item_def_id) {
460+ continue ;
461+ }
462+
463+ for pred in ty:: lookup_predicates ( rcx. tcx ( ) , item_def_id) . predicates {
464+ let result = match pred {
465+ ty:: Predicate :: Equate ( ..) |
466+ ty:: Predicate :: RegionOutlives ( ..) |
467+ ty:: Predicate :: TypeOutlives ( ..) |
468+ ty:: Predicate :: Projection ( ..) => {
469+ // For now, assume all these where-clauses
470+ // may give drop implementation capabilty
471+ // to access borrowed data.
472+ true
473+ }
474+
475+ ty:: Predicate :: Trait ( ty:: Binder ( ref t_pred) ) => {
476+ let def_id = t_pred. trait_ref . def_id ;
477+ if ty:: trait_items ( rcx. tcx ( ) , def_id) . len ( ) != 0 {
478+ // If trait has items, assume it adds
479+ // capability to access borrowed data.
480+ true
481+ } else {
482+ // Trait without items is itself
483+ // uninteresting from POV of dropck.
484+ //
485+ // However, may have parent w/ items;
486+ // so schedule checking of predicates,
487+ items_to_inspect. push ( def_id) ;
488+ // and say "no capability found" for now.
489+ false
490+ }
491+ }
492+ } ;
493+
494+ if result {
495+ has_pred_of_interest = true ;
496+ debug ! ( "typ: {} has interesting dtor due to generic preds, e.g. {}" ,
497+ typ. repr( rcx. tcx( ) ) , pred. repr( rcx. tcx( ) ) ) ;
498+ break ' items;
499+ }
484500 }
485501
486- result
487- } ) ;
502+ seen_items . push ( item_def_id ) ;
503+ }
488504
489505 // In `impl<'a> Drop ...`, we automatically assume
490506 // `'a` is meaningful and thus represents a bound
0 commit comments