@@ -17,8 +17,8 @@ use rustc_middle::mir::*;
17
17
use rustc_middle:: ty:: layout:: TyAndLayout ;
18
18
use rustc_middle:: ty:: { self , ParamEnv , Ty , TyCtxt } ;
19
19
use 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 ;
22
22
use rustc_span:: def_id:: DefId ;
23
23
use rustc_target:: abi:: { Align , Size } ;
24
24
use rustc_target:: spec:: abi:: Abi as CallAbi ;
@@ -105,7 +105,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
105
105
let map = Map :: from_filter ( tcx, body, |local| ssa. is_ssa ( local) , place_limit) ;
106
106
107
107
// Perform the actual dataflow analysis.
108
- let mut analysis = ConstAnalysis :: new ( tcx, body, & map) . wrap ( ) ;
108
+ let analysis = ConstAnalysis :: new ( tcx, body, & map) . wrap ( ) ;
109
109
let mut state = analysis. bottom_value ( body) ;
110
110
analysis. initialize_start_block ( body, & mut state) ;
111
111
@@ -120,23 +120,25 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
120
120
OperandCollector { state : & state, visitor : & mut collector, map : & map }
121
121
. visit_statement ( statement, location) ;
122
122
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) ,
137
134
}
135
+ } else {
136
+ FlatSet :: Top
137
+ } ;
138
+
139
+ if let FlatSet :: Elem ( value) = value {
140
+ collector. assignments . insert ( location, value) ;
138
141
}
139
- _ => ( ) ,
140
142
}
141
143
}
142
144
0 commit comments