@@ -248,6 +248,7 @@ impl Direction for Backward {
248248 ) ;
249249 propagate ( pred, & tmp) ;
250250 }
251+
251252 mir:: TerminatorKind :: InlineAsm {
252253 destination : Some ( dest) , ref operands, ..
253254 } if dest == bb => {
@@ -266,6 +267,25 @@ impl Direction for Backward {
266267 propagate ( pred, & tmp) ;
267268 }
268269
270+ mir:: TerminatorKind :: SwitchInt { ref targets, ref discr, switch_ty : _ } => {
271+ let mut applier = BackwardSwitchIntEdgeEffectsApplier {
272+ pred,
273+ exit_state,
274+ targets,
275+ bb,
276+ propagate : & mut propagate,
277+ effects_applied : false ,
278+ } ;
279+
280+ analysis. apply_switch_int_edge_effects ( pred, discr, & mut applier) ;
281+
282+ let BackwardSwitchIntEdgeEffectsApplier { effects_applied, .. } = applier;
283+
284+ if !effects_applied {
285+ propagate ( pred, exit_state)
286+ }
287+ }
288+
269289 // Ignore dead unwinds.
270290 mir:: TerminatorKind :: Call { cleanup : Some ( unwind) , .. }
271291 | mir:: TerminatorKind :: Assert { cleanup : Some ( unwind) , .. }
@@ -286,6 +306,33 @@ impl Direction for Backward {
286306 }
287307}
288308
309+ struct BackwardSwitchIntEdgeEffectsApplier < ' a , D , F > {
310+ pred : BasicBlock ,
311+ exit_state : & ' a mut D ,
312+ targets : & ' a SwitchTargets ,
313+ bb : BasicBlock ,
314+ propagate : & ' a mut F ,
315+
316+ effects_applied : bool ,
317+ }
318+
319+ impl < D , F > super :: SwitchIntEdgeEffects < D > for BackwardSwitchIntEdgeEffectsApplier < ' _ , D , F >
320+ where
321+ D : Clone ,
322+ F : FnMut ( BasicBlock , & D ) ,
323+ {
324+ fn apply ( & mut self , mut apply_edge_effect : impl FnMut ( & mut D , SwitchIntTarget ) ) {
325+ assert ! ( !self . effects_applied) ;
326+
327+ let value =
328+ self . targets . iter ( ) . find_map ( |( value, target) | ( target == self . bb ) . then_some ( value) ) ;
329+ apply_edge_effect ( self . exit_state , SwitchIntTarget { value, target : self . bb } ) ;
330+ ( self . propagate ) ( self . pred , self . exit_state ) ;
331+
332+ self . effects_applied = true ;
333+ }
334+ }
335+
289336/// Dataflow that runs from the entry of a block (the first statement), to its exit (terminator).
290337pub struct Forward ;
291338
@@ -528,7 +575,7 @@ impl Direction for Forward {
528575 }
529576
530577 SwitchInt { ref targets, ref discr, switch_ty : _ } => {
531- let mut applier = SwitchIntEdgeEffectApplier {
578+ let mut applier = ForwardSwitchIntEdgeEffectsApplier {
532579 exit_state,
533580 targets,
534581 propagate,
@@ -537,8 +584,11 @@ impl Direction for Forward {
537584
538585 analysis. apply_switch_int_edge_effects ( bb, discr, & mut applier) ;
539586
540- let SwitchIntEdgeEffectApplier {
541- exit_state, mut propagate, effects_applied, ..
587+ let ForwardSwitchIntEdgeEffectsApplier {
588+ exit_state,
589+ mut propagate,
590+ effects_applied,
591+ ..
542592 } = applier;
543593
544594 if !effects_applied {
@@ -551,15 +601,15 @@ impl Direction for Forward {
551601 }
552602}
553603
554- struct SwitchIntEdgeEffectApplier < ' a , D , F > {
604+ struct ForwardSwitchIntEdgeEffectsApplier < ' a , D , F > {
555605 exit_state : & ' a mut D ,
556606 targets : & ' a SwitchTargets ,
557607 propagate : F ,
558608
559609 effects_applied : bool ,
560610}
561611
562- impl < D , F > super :: SwitchIntEdgeEffects < D > for SwitchIntEdgeEffectApplier < ' _ , D , F >
612+ impl < D , F > super :: SwitchIntEdgeEffects < D > for ForwardSwitchIntEdgeEffectsApplier < ' _ , D , F >
563613where
564614 D : Clone ,
565615 F : FnMut ( BasicBlock , & D ) ,
0 commit comments