@@ -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