@@ -450,41 +450,57 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
450
450
451
451
let dtor_typescheme = ty:: lookup_item_type ( rcx. tcx ( ) , impl_did) ;
452
452
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
- } ;
480
453
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
+ }
484
500
}
485
501
486
- result
487
- } ) ;
502
+ seen_items . push ( item_def_id ) ;
503
+ }
488
504
489
505
// In `impl<'a> Drop ...`, we automatically assume
490
506
// `'a` is meaningful and thus represents a bound
0 commit comments