@@ -103,16 +103,18 @@ impl<'a, 'mir, 'tcx> DropsReachable<'a, 'mir, 'tcx> {
103103 // we will proceed with `succ`
104104 let dropped_local_there = match self . visited . entry ( succ) {
105105 hash_map:: Entry :: Occupied ( occupied_entry) => {
106- if !occupied_entry. get ( ) . borrow_mut ( ) . union ( & * dropped_local_here. borrow ( ) ) {
106+ if succ == block
107+ || !occupied_entry. get ( ) . borrow_mut ( ) . union ( & * dropped_local_here. borrow ( ) )
108+ {
107109 // `succ` has been visited but no new drops observed so far,
108110 // so we can bail on `succ` until new drop information arrives
109111 continue ;
110112 }
111113 occupied_entry. get ( ) . clone ( )
112114 }
113- hash_map:: Entry :: Vacant ( vacant_entry) => {
114- vacant_entry . insert ( dropped_local_here. clone ( ) ) . clone ( )
115- }
115+ hash_map:: Entry :: Vacant ( vacant_entry) => vacant_entry
116+ . insert ( Rc :: new ( RefCell :: new ( dropped_local_here. borrow ( ) . clone ( ) ) ) )
117+ . clone ( ) ,
116118 } ;
117119 if let Some ( terminator) = & target. terminator
118120 && let TerminatorKind :: Drop {
@@ -141,6 +143,61 @@ impl<'a, 'mir, 'tcx> DropsReachable<'a, 'mir, 'tcx> {
141143 }
142144}
143145
146+ fn true_significant_drop_ty < ' tcx > (
147+ tcx : TyCtxt < ' tcx > ,
148+ ty : Ty < ' tcx > ,
149+ ) -> Option < SmallVec < [ Ty < ' tcx > ; 2 ] > > {
150+ if let ty:: Adt ( def, args) = ty. kind ( ) {
151+ let mut did = def. did ( ) ;
152+ let mut name_rev = vec ! [ ] ;
153+ loop {
154+ let key = tcx. def_key ( did) ;
155+
156+ match key. disambiguated_data . data {
157+ rustc_hir:: definitions:: DefPathData :: CrateRoot => {
158+ name_rev. push ( tcx. crate_name ( did. krate ) )
159+ }
160+ rustc_hir:: definitions:: DefPathData :: TypeNs ( symbol) => name_rev. push ( symbol) ,
161+ _ => return None ,
162+ }
163+ if let Some ( parent) = key. parent {
164+ did = DefId { krate : did. krate , index : parent } ;
165+ } else {
166+ break ;
167+ }
168+ }
169+ let name_str: Vec < _ > = name_rev. iter ( ) . rev ( ) . map ( |x| x. as_str ( ) ) . collect ( ) ;
170+ debug ! ( ?name_str) ;
171+ match name_str[ ..] {
172+ // These are the types from Rust core ecosystem
173+ [ "sym" | "proc_macro2" , ..] | [ "core" | "std" , "task" , "RawWaker" ] => Some ( smallvec ! [ ] ) ,
174+ // These are important types from Rust ecosystem
175+ [ "tracing" , "instrument" , "Instrumented" ] | [ "bytes" , "Bytes" ] => Some ( smallvec ! [ ] ) ,
176+ [ "hashbrown" , "raw" , "RawTable" | "RawIntoIter" ] => {
177+ if let [ ty, ..] = & * * * args
178+ && let Some ( ty) = ty. as_type ( )
179+ {
180+ Some ( smallvec ! [ ty] )
181+ } else {
182+ None
183+ }
184+ }
185+ [ "hashbrown" , "raw" , "RawDrain" ] => {
186+ if let [ _, ty, ..] = & * * * args
187+ && let Some ( ty) = ty. as_type ( )
188+ {
189+ Some ( smallvec ! [ ty] )
190+ } else {
191+ None
192+ }
193+ }
194+ _ => None ,
195+ }
196+ } else {
197+ None
198+ }
199+ }
200+
144201#[ instrument( level = "debug" , skip( tcx, param_env) ) ]
145202fn extract_component_raw < ' tcx > (
146203 tcx : TyCtxt < ' tcx > ,
@@ -154,7 +211,14 @@ fn extract_component_raw<'tcx>(
154211 debug ! ( ?ty, "components" ) ;
155212 let mut out_tys = smallvec ! [ ] ;
156213 for ty in tys {
157- out_tys. push ( ty) ;
214+ if let Some ( tys) = true_significant_drop_ty ( tcx, ty) {
215+ // Some types can be further opened up because the drop is simply delegated
216+ for ty in tys {
217+ out_tys. extend ( extract_component_raw ( tcx, param_env, ty) ) ;
218+ }
219+ } else {
220+ out_tys. push ( ty) ;
221+ }
158222 }
159223 out_tys
160224}
0 commit comments