@@ -119,41 +119,49 @@ impl<'a, 'tcx> SigDropChecker<'a, 'tcx> {
119119 self . cx . typeck_results ( ) . expr_ty ( ex)
120120 }
121121
122- fn has_seen_type ( & mut self , ty : Ty < ' tcx > ) -> bool {
123- !self . seen_types . insert ( ty)
122+ fn has_sig_drop_attr ( & mut self , cx : & LateContext < ' tcx > , ty : Ty < ' tcx > ) -> bool {
123+ self . seen_types . clear ( ) ;
124+ self . has_sig_drop_attr_impl ( cx, ty)
124125 }
125126
126- fn has_sig_drop_attr ( & mut self , cx : & LateContext < ' tcx > , ty : Ty < ' tcx > ) -> bool {
127+ fn has_sig_drop_attr_impl ( & mut self , cx : & LateContext < ' tcx > , ty : Ty < ' tcx > ) -> bool {
127128 if let Some ( adt) = ty. ty_adt_def ( ) {
128129 if get_attr ( cx. sess ( ) , cx. tcx . get_attrs_unchecked ( adt. did ( ) ) , "has_significant_drop" ) . count ( ) > 0 {
129130 return true ;
130131 }
131132 }
132133
133- match ty. kind ( ) {
134- rustc_middle:: ty:: Adt ( a, b) => {
135- for f in a. all_fields ( ) {
136- let ty = f. ty ( cx. tcx , b) ;
137- if !self . has_seen_type ( ty) && self . has_sig_drop_attr ( cx, ty) {
138- return true ;
139- }
140- }
134+ if !self . seen_types . insert ( ty) {
135+ return false ;
136+ }
141137
142- for generic_arg in * b {
143- if let GenericArgKind :: Type ( ty) = generic_arg. unpack ( ) {
144- if self . has_sig_drop_attr ( cx, ty) {
145- return true ;
146- }
147- }
148- }
149- false
138+ let result = match ty. kind ( ) {
139+ rustc_middle:: ty:: Adt ( adt, args) => {
140+ // if some field has significant drop,
141+ adt. all_fields ( )
142+ . map ( |field| field. ty ( cx. tcx , args) )
143+ . any ( |ty| self . has_sig_drop_attr ( cx, ty) )
144+ // or if there is no generic lifetime and..
145+ // (to avoid false positive on `Ref<'a, MutexGuard<Foo>>`)
146+ || ( args
147+ . iter ( )
148+ . all ( |arg| !matches ! ( arg. unpack( ) , GenericArgKind :: Lifetime ( _) ) )
149+ // some generic parameter has significant drop
150+ // (to avoid false negative on `Box<MutexGuard<Foo>>`)
151+ && args
152+ . iter ( )
153+ . filter_map ( |arg| match arg. unpack ( ) {
154+ GenericArgKind :: Type ( ty) => Some ( ty) ,
155+ _ => None ,
156+ } )
157+ . any ( |ty| self . has_sig_drop_attr ( cx, ty) ) )
150158 } ,
151- rustc_middle:: ty:: Array ( ty, _)
152- | rustc_middle:: ty:: RawPtr ( ty, _)
153- | rustc_middle:: ty:: Ref ( _, ty, _)
154- | rustc_middle:: ty:: Slice ( ty) => self . has_sig_drop_attr ( cx, * ty) ,
159+ rustc_middle:: ty:: Tuple ( tys) => tys. iter ( ) . any ( |ty| self . has_sig_drop_attr ( cx, ty) ) ,
160+ rustc_middle:: ty:: Array ( ty, _) | rustc_middle:: ty:: Slice ( ty) => self . has_sig_drop_attr ( cx, * ty) ,
155161 _ => false ,
156- }
162+ } ;
163+
164+ result
157165 }
158166}
159167
0 commit comments