@@ -18,7 +18,7 @@ use rustc_middle::ty::adjustment::PointerCoercion;
18
18
use rustc_middle:: ty:: { self , Instance , InstanceKind , Ty , TyCtxt , TypeVisitableExt } ;
19
19
use rustc_mir_dataflow:: impls:: MaybeStorageLive ;
20
20
use rustc_mir_dataflow:: storage:: always_storage_live_locals;
21
- use rustc_mir_dataflow:: { Analysis , ResultsCursor } ;
21
+ use rustc_mir_dataflow:: Analysis ;
22
22
use rustc_span:: { sym, Span , Symbol , DUMMY_SP } ;
23
23
use rustc_trait_selection:: error_reporting:: InferCtxtErrorExt ;
24
24
use rustc_trait_selection:: traits:: { self , ObligationCauseCode , ObligationCtxt } ;
@@ -275,40 +275,28 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
275
275
// A local is "transient" if it is guaranteed dead at all `Return`.
276
276
// So first compute the say of "maybe live" locals at each program point.
277
277
let always_live_locals = & always_storage_live_locals ( & ccx. body ) ;
278
- let maybe_storage_live = MaybeStorageLive :: new ( Cow :: Borrowed ( always_live_locals) )
279
- . into_engine ( ccx. tcx , & ccx. body )
280
- . iterate_to_fixpoint ( )
281
- . into_results_cursor ( & ccx. body ) ;
278
+ let mut maybe_storage_live =
279
+ MaybeStorageLive :: new ( Cow :: Borrowed ( always_live_locals) )
280
+ . into_engine ( ccx. tcx , & ccx. body )
281
+ . iterate_to_fixpoint ( )
282
+ . into_results_cursor ( & ccx. body ) ;
282
283
283
284
// And then check all `Return` in the MIR, and if a local is "maybe live" at a
284
285
// `Return` then it is definitely not transient.
285
- struct TransientLocalVisitor < ' a , ' tcx > {
286
- maybe_storage_live : ResultsCursor < ' a , ' tcx , MaybeStorageLive < ' a > > ,
287
- transient : BitSet < Local > ,
288
- }
289
- impl < ' a , ' tcx > Visitor < ' tcx > for TransientLocalVisitor < ' a , ' tcx > {
290
- fn visit_terminator (
291
- & mut self ,
292
- terminator : & Terminator < ' tcx > ,
293
- location : Location ,
294
- ) {
295
- if matches ! ( terminator. kind, TerminatorKind :: Return ) {
296
- self . maybe_storage_live . seek_after_primary_effect ( location) ;
297
- for local in self . maybe_storage_live . get ( ) . iter ( ) {
298
- // If a local may be live here, it is definitely not transient.
299
- self . transient . remove ( local) ;
300
- }
286
+ let mut transient = BitSet :: new_filled ( ccx. body . local_decls . len ( ) ) ;
287
+ // Make sure to only visit reachable blocks, the dataflow engine can ICE otherwise.
288
+ for ( bb, data) in traversal:: reachable ( & ccx. body ) {
289
+ if matches ! ( data. terminator( ) . kind, TerminatorKind :: Return ) {
290
+ let location = ccx. body . terminator_loc ( bb) ;
291
+ maybe_storage_live. seek_after_primary_effect ( location) ;
292
+ for local in maybe_storage_live. get ( ) . iter ( ) {
293
+ // If a local may be live here, it is definitely not transient.
294
+ transient. remove ( local) ;
301
295
}
302
296
}
303
297
}
304
298
305
- let mut v = TransientLocalVisitor {
306
- maybe_storage_live,
307
- transient : BitSet :: new_filled ( ccx. body . local_decls . len ( ) ) ,
308
- } ;
309
- v. visit_body ( & ccx. body ) ;
310
-
311
- v. transient
299
+ transient
312
300
} )
313
301
. contains ( local)
314
302
}
0 commit comments