@@ -9,9 +9,10 @@ use rustc_middle::mir::{
99} ;
1010use rustc_middle:: ty:: util:: Discr ;
1111use rustc_middle:: ty:: { self , TyCtxt } ;
12+ use smallvec:: SmallVec ;
1213use tracing:: { debug, instrument} ;
1314
14- use crate :: drop_flag_effects:: DropFlagState ;
15+ use crate :: drop_flag_effects:: { DropFlagState , InactiveVariants } ;
1516use crate :: move_paths:: { HasMoveData , InitIndex , InitKind , LookupResult , MoveData , MovePathIndex } ;
1617use crate :: {
1718 Analysis , GenKill , MaybeReachable , drop_flag_effects, drop_flag_effects_for_function_entry,
@@ -26,6 +27,12 @@ pub struct MaybePlacesSwitchIntData<'tcx> {
2627}
2728
2829impl < ' tcx > MaybePlacesSwitchIntData < ' tcx > {
30+ /// Creates a `SmallVec` mapping each target in `targets` to its `VariantIdx`.
31+ fn variants ( & mut self , targets : & mir:: SwitchTargets ) -> SmallVec < [ VariantIdx ; 4 ] > {
32+ self . index = 0 ;
33+ targets. all_values ( ) . iter ( ) . map ( |value| self . next_discr ( value. get ( ) ) ) . collect ( )
34+ }
35+
2936 // The discriminant order in the `SwitchInt` targets should match the order yielded by
3037 // `AdtDef::discriminants`. We rely on this to match each discriminant in the targets to its
3138 // corresponding variant in linear time.
@@ -454,63 +461,24 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
454461 data : & mut Self :: SwitchIntData ,
455462 state : & mut Self :: Domain ,
456463 value : SwitchTargetValue ,
457- otherwise_state : Option < & mut Self :: Domain > ,
464+ targets : & mir :: SwitchTargets ,
458465 ) {
459- let SwitchTargetValue :: Normal ( value) = value else {
460- return ;
466+ let inactive_variants = match value {
467+ SwitchTargetValue :: Normal ( value) => InactiveVariants :: Active ( data. next_discr ( value) ) ,
468+ SwitchTargetValue :: Otherwise if self . exclude_inactive_in_otherwise => {
469+ InactiveVariants :: Inactives ( data. variants ( targets) )
470+ }
471+ _ => return ,
461472 } ;
462473
463- let handle_inactive_variant = |mpi| state. kill ( mpi) ;
464-
465474 // Kill all move paths that correspond to variants we know to be inactive along this
466475 // particular outgoing edge of a `SwitchInt`.
467- match otherwise_state {
468- Some ( otherwise_state) => {
469- drop_flag_effects:: on_all_variants (
470- self . move_data ,
471- data. enum_place ,
472- data. next_discr ( value) ,
473- handle_inactive_variant,
474- |mpi| otherwise_state. kill ( mpi) ,
475- ) ;
476- }
477- None => {
478- drop_flag_effects:: on_all_variants (
479- self . move_data ,
480- data. enum_place ,
481- data. next_discr ( value) ,
482- handle_inactive_variant,
483- |_mpi| { } ,
484- ) ;
485- }
486- }
487- }
488-
489- fn apply_switch_int_edge_effect_for_targets (
490- & mut self ,
491- targets : & mir:: SwitchTargets ,
492- mut data : Self :: SwitchIntData ,
493- state : & mut Self :: Domain ,
494- mut propagate : impl FnMut ( mir:: BasicBlock , & Self :: Domain ) ,
495- ) {
496- let analyze_otherwise = self . exclude_inactive_in_otherwise
497- && ( 1 ..data. discriminants . len ( ) ) . contains ( & targets. all_values ( ) . len ( ) ) ;
498-
499- let mut otherwise_state = if analyze_otherwise { Some ( state. clone ( ) ) } else { None } ;
500- let mut target_state = MaybeReachable :: Unreachable ;
501-
502- for ( value, target) in targets. iter ( ) {
503- target_state. clone_from ( & state) ;
504- self . apply_switch_int_edge_effect (
505- & mut data,
506- & mut target_state,
507- SwitchTargetValue :: Normal ( value) ,
508- otherwise_state. as_mut ( ) ,
509- ) ;
510- propagate ( target, & target_state) ;
511- }
512-
513- propagate ( targets. otherwise ( ) , otherwise_state. as_ref ( ) . unwrap_or ( state) ) ;
476+ drop_flag_effects:: on_all_inactive_variants (
477+ self . move_data ,
478+ data. enum_place ,
479+ & inactive_variants,
480+ |mpi| state. kill ( mpi) ,
481+ ) ;
514482 }
515483}
516484
@@ -613,63 +581,24 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
613581 data : & mut Self :: SwitchIntData ,
614582 state : & mut Self :: Domain ,
615583 value : SwitchTargetValue ,
616- otherwise_state : Option < & mut Self :: Domain > ,
584+ targets : & mir :: SwitchTargets ,
617585 ) {
618- let SwitchTargetValue :: Normal ( value) = value else {
619- return ;
586+ let inactive_variants = match value {
587+ SwitchTargetValue :: Normal ( value) => InactiveVariants :: Active ( data. next_discr ( value) ) ,
588+ SwitchTargetValue :: Otherwise if self . include_inactive_in_otherwise => {
589+ InactiveVariants :: Inactives ( data. variants ( targets) )
590+ }
591+ _ => return ,
620592 } ;
621593
622- let handle_inactive_variant = |mpi| state. gen_ ( mpi) ;
623-
624594 // Mark all move paths that correspond to variants other than this one as maybe
625595 // uninitialized (in reality, they are *definitely* uninitialized).
626- match otherwise_state {
627- Some ( otherwise_state) => {
628- drop_flag_effects:: on_all_variants (
629- self . move_data ,
630- data. enum_place ,
631- data. next_discr ( value) ,
632- handle_inactive_variant,
633- |mpi| otherwise_state. gen_ ( mpi) ,
634- ) ;
635- }
636- None => {
637- drop_flag_effects:: on_all_variants (
638- self . move_data ,
639- data. enum_place ,
640- data. next_discr ( value) ,
641- handle_inactive_variant,
642- |_mpi| { } ,
643- ) ;
644- }
645- }
646- }
647-
648- fn apply_switch_int_edge_effect_for_targets (
649- & mut self ,
650- targets : & mir:: SwitchTargets ,
651- mut data : Self :: SwitchIntData ,
652- state : & mut Self :: Domain ,
653- mut propagate : impl FnMut ( mir:: BasicBlock , & Self :: Domain ) ,
654- ) {
655- let analyze_otherwise = self . include_inactive_in_otherwise
656- && ( 1 ..data. discriminants . len ( ) ) . contains ( & targets. all_values ( ) . len ( ) ) ;
657-
658- let mut otherwise_state = if analyze_otherwise { Some ( state. clone ( ) ) } else { None } ;
659- let mut target_state = MixedBitSet :: new_empty ( self . move_data ( ) . move_paths . len ( ) ) ;
660-
661- for ( value, target) in targets. iter ( ) {
662- target_state. clone_from ( & state) ;
663- self . apply_switch_int_edge_effect (
664- & mut data,
665- & mut target_state,
666- SwitchTargetValue :: Normal ( value) ,
667- otherwise_state. as_mut ( ) ,
668- ) ;
669- propagate ( target, & target_state) ;
670- }
671-
672- propagate ( targets. otherwise ( ) , otherwise_state. as_ref ( ) . unwrap_or ( state) ) ;
596+ drop_flag_effects:: on_all_inactive_variants (
597+ self . move_data ,
598+ data. enum_place ,
599+ & inactive_variants,
600+ |mpi| state. gen_ ( mpi) ,
601+ ) ;
673602 }
674603}
675604
0 commit comments