@@ -566,102 +566,25 @@ impl<'tcx> ty::ctxt<'tcx> {
566
566
}
567
567
}
568
568
569
- /// Returns true if this ADT is a dtorck type, i.e. whether it being
570
- /// safe for destruction requires it to be alive
569
+ /// Returns true if this ADT is a dtorck type, i.e. whether it
570
+ /// being safe for destruction requires all borrowed pointers
571
+ /// reachable by it to have lifetimes strictly greater than self.
571
572
pub fn is_adt_dtorck ( & self , adt : ty:: AdtDef < ' tcx > ) -> bool {
572
573
let dtor_method = match adt. destructor ( ) {
573
574
Some ( dtor) => dtor,
574
575
None => return false
575
576
} ;
576
- let impl_did = self . impl_of_method ( dtor_method) . unwrap_or_else ( || {
577
- self . sess . bug ( & format ! ( "no Drop impl for the dtor of `{:?}`" , adt) )
578
- } ) ;
579
- let generics = adt. type_scheme ( self ) . generics ;
580
577
581
578
// RFC 1238: if the destructor method is tagged with the
582
579
// attribute `unsafe_destructor_blind_to_params`, then the
583
580
// compiler is being instructed to *assume* that the
584
- // destructor will not access borrowed data via a type
585
- // parameter, even if such data is otherwise reachable.
586
- if self . has_attr ( dtor_method, "unsafe_destructor_blind_to_params" ) {
587
- debug ! ( "typ: {:?} assumed blind and thus is dtorck-safe" , adt) ;
588
- return false ;
589
- }
590
-
591
- // In `impl<'a> Drop ...`, we automatically assume
592
- // `'a` is meaningful and thus represents a bound
593
- // through which we could reach borrowed data.
581
+ // destructor will not access borrowed data,
582
+ // even if such data is otherwise reachable.
594
583
//
595
- // FIXME (pnkfelix): In the future it would be good to
596
- // extend the language to allow the user to express,
597
- // in the impl signature, that a lifetime is not
598
- // actually used (something like `where 'a: ?Live`).
599
- if generics. has_region_params ( subst:: TypeSpace ) {
600
- debug ! ( "typ: {:?} has interesting dtor due to region params" ,
601
- adt) ;
602
- return true ;
603
- }
604
-
605
- // RFC 1238: *any* type parameter at all makes this a dtor of
606
- // interest (i.e. cannot-assume-parametricity from RFC 1238.)
607
- if generics. has_type_params ( subst:: TypeSpace ) {
608
- debug ! ( "typ: {:?} has interesting dtor due to type params" ,
609
- adt) ;
610
- return true ;
611
- }
612
-
613
- let mut seen_items = Vec :: new ( ) ;
614
- let mut items_to_inspect = vec ! [ impl_did] ;
615
- while let Some ( item_def_id) = items_to_inspect. pop ( ) {
616
- if seen_items. contains ( & item_def_id) {
617
- continue ;
618
- }
619
-
620
- for pred in self . lookup_predicates ( item_def_id) . predicates {
621
- let result = match pred {
622
- ty:: Predicate :: Equate ( ..) |
623
- ty:: Predicate :: RegionOutlives ( ..) |
624
- ty:: Predicate :: TypeOutlives ( ..) |
625
- ty:: Predicate :: WellFormed ( ..) |
626
- ty:: Predicate :: ObjectSafe ( ..) |
627
- ty:: Predicate :: Projection ( ..) => {
628
- // For now, assume all these where-clauses
629
- // may give drop implementation capabilty
630
- // to access borrowed data.
631
- true
632
- }
633
-
634
- ty:: Predicate :: Trait ( ty:: Binder ( ref t_pred) ) => {
635
- let def_id = t_pred. trait_ref . def_id ;
636
- if self . trait_items ( def_id) . len ( ) != 0 {
637
- // If trait has items, assume it adds
638
- // capability to access borrowed data.
639
- true
640
- } else {
641
- // Trait without items is itself
642
- // uninteresting from POV of dropck.
643
- //
644
- // However, may have parent w/ items;
645
- // so schedule checking of predicates,
646
- items_to_inspect. push ( def_id) ;
647
- // and say "no capability found" for now.
648
- false
649
- }
650
- }
651
- } ;
652
-
653
- if result {
654
- debug ! ( "typ: {:?} has interesting dtor due to generic preds, e.g. {:?}" ,
655
- adt, pred) ;
656
- return true ;
657
- }
658
- }
659
-
660
- seen_items. push ( item_def_id) ;
661
- }
662
-
663
- debug ! ( "typ: {:?} is dtorck-safe" , adt) ;
664
- false
584
+ // Such access can be in plain sight (e.g. dereferencing
585
+ // `*foo.0` of `Foo<'a>(&'a u32)`) or indirectly hidden
586
+ // (e.g. calling `foo.0.clone()` of `Foo<T:Clone>`).
587
+ return !self . has_attr ( dtor_method, "unsafe_destructor_blind_to_params" ) ;
665
588
}
666
589
}
667
590
0 commit comments