@@ -17,8 +17,8 @@ use rustc_middle::mir::*;
1717use  rustc_middle:: ty:: layout:: TyAndLayout ; 
1818use  rustc_middle:: ty:: { self ,  ParamEnv ,  Ty ,  TyCtxt } ; 
1919use  rustc_mir_dataflow:: lattice:: FlatSet ; 
20- use  rustc_mir_dataflow:: value_analysis:: { Map ,  ValueAnalysis } ; 
21- use  rustc_mir_dataflow:: { Analysis ,   AnalysisDomain } ; 
20+ use  rustc_mir_dataflow:: value_analysis:: { Map ,  ValueAnalysis ,   ValueOrPlace } ; 
21+ use  rustc_mir_dataflow:: AnalysisDomain ; 
2222use  rustc_span:: def_id:: DefId ; 
2323use  rustc_target:: abi:: { Align ,  Size } ; 
2424use  rustc_target:: spec:: abi:: Abi  as  CallAbi ; 
@@ -105,7 +105,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
105105        let  map = Map :: from_filter ( tcx,  body,  |local| ssa. is_ssa ( local) ,  place_limit) ; 
106106
107107        // Perform the actual dataflow analysis. 
108-         let  mut   analysis = ConstAnalysis :: new ( tcx,  body,  & map) . wrap ( ) ; 
108+         let  analysis = ConstAnalysis :: new ( tcx,  body,  & map) . wrap ( ) ; 
109109        let  mut  state = analysis. bottom_value ( body) ; 
110110        analysis. initialize_start_block ( body,  & mut  state) ; 
111111
@@ -120,23 +120,25 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
120120                OperandCollector  {  state :  & state,  visitor :  & mut  collector,  map :  & map } 
121121                    . visit_statement ( statement,  location) ; 
122122
123-                 if  let  Some ( ( place,  _) )  = statement. kind . as_assign ( ) 
124-                     && !place. is_indirect_first_projection ( ) 
125-                     && ssa. is_ssa ( place. local ) 
126-                 { 
127-                     analysis. apply_statement_effect ( & mut  state,  statement,  location) ; 
128-                 } 
129- 
130-                 match  statement. kind  { 
131-                     StatementKind :: Assign ( box ( _,  Rvalue :: Use ( Operand :: Constant ( _) ) ) )  => { 
132-                         // Don't overwrite the assignment if it already uses a constant (to keep the span). 
133-                     } 
134-                     StatementKind :: Assign ( box ( place,  _) )  => { 
135-                         if  let  FlatSet :: Elem ( value)  = state. get ( place. as_ref ( ) ,  & map)  { 
136-                             collector. assignments . insert ( location,  value) ; 
123+                 if  let  Some ( ( place,  rvalue) )  = statement. kind . as_assign ( )  { 
124+                     let  value = if  !place. is_indirect_first_projection ( )  && ssa. is_ssa ( place. local ) 
125+                     { 
126+                         // Use `handle_assign` here to handle the case where `place` is not scalar. 
127+                         analysis. 0 . handle_assign ( * place,  rvalue,  & mut  state) ; 
128+                         state. get ( place. as_ref ( ) ,  & map) 
129+                     }  else  if  place. ty ( & body. local_decls ,  tcx) . ty . is_scalar ( )  { 
130+                         let  value = analysis. 0 . handle_rvalue ( rvalue,  & mut  state) ; 
131+                         match  value { 
132+                             ValueOrPlace :: Value ( value)  => value, 
133+                             ValueOrPlace :: Place ( place)  => state. get_idx ( place,  & map) , 
137134                        } 
135+                     }  else  { 
136+                         FlatSet :: Top 
137+                     } ; 
138+ 
139+                     if  let  FlatSet :: Elem ( value)  = value { 
140+                         collector. assignments . insert ( location,  value) ; 
138141                    } 
139-                     _ => ( ) , 
140142                } 
141143            } 
142144
0 commit comments