@@ -18,7 +18,7 @@ use rustc_middle::ty::adjustment::PointerCoercion;
1818use rustc_middle:: ty:: { self , Instance , InstanceKind , Ty , TyCtxt , TypeVisitableExt } ;
1919use rustc_mir_dataflow:: impls:: MaybeStorageLive ;
2020use rustc_mir_dataflow:: storage:: always_storage_live_locals;
21- use rustc_mir_dataflow:: { Analysis , ResultsCursor } ;
21+ use rustc_mir_dataflow:: Analysis ;
2222use rustc_span:: { sym, Span , Symbol , DUMMY_SP } ;
2323use rustc_trait_selection:: error_reporting:: InferCtxtErrorExt ;
2424use rustc_trait_selection:: traits:: { self , ObligationCauseCode , ObligationCtxt } ;
@@ -275,40 +275,28 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
275275 // A local is "transient" if it is guaranteed dead at all `Return`.
276276 // So first compute the say of "maybe live" locals at each program point.
277277 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 ) ;
282283
283284 // And then check all `Return` in the MIR, and if a local is "maybe live" at a
284285 // `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) ;
301295 }
302296 }
303297 }
304298
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
312300 } )
313301 . contains ( local)
314302 }
0 commit comments