@@ -36,71 +36,70 @@ impl<'tcx> MirPass<'tcx> for Deaggregator {
3636 // In fact, we might not want to trigger in other cases.
3737 // Ex: when we could use SROA. See issue #35259
3838
39- let mut curr: usize = 0 ;
4039 for bb in mir. basic_blocks_mut ( ) {
41- let idx = match get_aggregate_statement_index ( curr, & bb. statements ) {
42- Some ( idx) => idx,
43- None => continue ,
44- } ;
45- // do the replacement
46- debug ! ( "removing statement {:?}" , idx) ;
47- let src_info = bb. statements [ idx] . source_info ;
48- let suffix_stmts = bb. statements . split_off ( idx+1 ) ;
49- let orig_stmt = bb. statements . pop ( ) . unwrap ( ) ;
50- let ( lhs, rhs) = match orig_stmt. kind {
51- StatementKind :: Assign ( ref lhs, ref rhs) => ( lhs, rhs) ,
52- _ => span_bug ! ( src_info. span, "expected assign, not {:?}" , orig_stmt) ,
53- } ;
54- let ( agg_kind, operands) = match rhs {
55- & Rvalue :: Aggregate ( ref agg_kind, ref operands) => ( agg_kind, operands) ,
56- _ => span_bug ! ( src_info. span, "expected aggregate, not {:?}" , rhs) ,
57- } ;
58- let ( adt_def, variant, substs) = match agg_kind {
59- & AggregateKind :: Adt ( adt_def, variant, substs, None ) => ( adt_def, variant, substs) ,
60- _ => span_bug ! ( src_info. span, "expected struct, not {:?}" , rhs) ,
61- } ;
62- let n = bb. statements . len ( ) ;
63- bb. statements . reserve ( n + operands. len ( ) + suffix_stmts. len ( ) ) ;
64- for ( i, op) in operands. iter ( ) . enumerate ( ) {
65- let ref variant_def = adt_def. variants [ variant] ;
66- let ty = variant_def. fields [ i] . ty ( tcx, substs) ;
67- let rhs = Rvalue :: Use ( op. clone ( ) ) ;
68-
69- let lhs_cast = if adt_def. variants . len ( ) > 1 {
70- Lvalue :: Projection ( Box :: new ( LvalueProjection {
71- base : lhs. clone ( ) ,
72- elem : ProjectionElem :: Downcast ( adt_def, variant) ,
73- } ) )
74- } else {
75- lhs. clone ( )
40+ let mut curr: usize = 0 ;
41+ while let Some ( idx) = get_aggregate_statement_index ( curr, & bb. statements ) {
42+ // do the replacement
43+ debug ! ( "removing statement {:?}" , idx) ;
44+ let src_info = bb. statements [ idx] . source_info ;
45+ let suffix_stmts = bb. statements . split_off ( idx+1 ) ;
46+ let orig_stmt = bb. statements . pop ( ) . unwrap ( ) ;
47+ let ( lhs, rhs) = match orig_stmt. kind {
48+ StatementKind :: Assign ( ref lhs, ref rhs) => ( lhs, rhs) ,
49+ _ => span_bug ! ( src_info. span, "expected assign, not {:?}" , orig_stmt) ,
7650 } ;
77-
78- let lhs_proj = Lvalue :: Projection ( Box :: new ( LvalueProjection {
79- base : lhs_cast,
80- elem : ProjectionElem :: Field ( Field :: new ( i) , ty) ,
81- } ) ) ;
82- let new_statement = Statement {
83- source_info : src_info,
84- kind : StatementKind :: Assign ( lhs_proj, rhs) ,
51+ let ( agg_kind, operands) = match rhs {
52+ & Rvalue :: Aggregate ( ref agg_kind, ref operands) => ( agg_kind, operands) ,
53+ _ => span_bug ! ( src_info. span, "expected aggregate, not {:?}" , rhs) ,
8554 } ;
86- debug ! ( "inserting: {:?} @ {:?}" , new_statement, idx + i) ;
87- bb. statements . push ( new_statement) ;
88- }
55+ let ( adt_def, variant, substs) = match agg_kind {
56+ & AggregateKind :: Adt ( adt_def, variant, substs, None )
57+ => ( adt_def, variant, substs) ,
58+ _ => span_bug ! ( src_info. span, "expected struct, not {:?}" , rhs) ,
59+ } ;
60+ let n = bb. statements . len ( ) ;
61+ bb. statements . reserve ( n + operands. len ( ) + suffix_stmts. len ( ) ) ;
62+ for ( i, op) in operands. iter ( ) . enumerate ( ) {
63+ let ref variant_def = adt_def. variants [ variant] ;
64+ let ty = variant_def. fields [ i] . ty ( tcx, substs) ;
65+ let rhs = Rvalue :: Use ( op. clone ( ) ) ;
8966
90- // if the aggregate was an enum, we need to set the discriminant
91- if adt_def. variants . len ( ) > 1 {
92- let set_discriminant = Statement {
93- kind : StatementKind :: SetDiscriminant {
94- lvalue : lhs. clone ( ) ,
95- variant_index : variant,
96- } ,
97- source_info : src_info,
67+ let lhs_cast = if adt_def. variants . len ( ) > 1 {
68+ Lvalue :: Projection ( Box :: new ( LvalueProjection {
69+ base : lhs. clone ( ) ,
70+ elem : ProjectionElem :: Downcast ( adt_def, variant) ,
71+ } ) )
72+ } else {
73+ lhs. clone ( )
74+ } ;
75+
76+ let lhs_proj = Lvalue :: Projection ( Box :: new ( LvalueProjection {
77+ base : lhs_cast,
78+ elem : ProjectionElem :: Field ( Field :: new ( i) , ty) ,
79+ } ) ) ;
80+ let new_statement = Statement {
81+ source_info : src_info,
82+ kind : StatementKind :: Assign ( lhs_proj, rhs) ,
83+ } ;
84+ debug ! ( "inserting: {:?} @ {:?}" , new_statement, idx + i) ;
85+ bb. statements . push ( new_statement) ;
86+ }
87+
88+ // if the aggregate was an enum, we need to set the discriminant
89+ if adt_def. variants . len ( ) > 1 {
90+ let set_discriminant = Statement {
91+ kind : StatementKind :: SetDiscriminant {
92+ lvalue : lhs. clone ( ) ,
93+ variant_index : variant,
94+ } ,
95+ source_info : src_info,
96+ } ;
97+ bb. statements . push ( set_discriminant) ;
9898 } ;
99- bb. statements . push ( set_discriminant) ;
100- } ;
10199
102- curr = bb. statements . len ( ) ;
103- bb. statements . extend ( suffix_stmts) ;
100+ curr = bb. statements . len ( ) ;
101+ bb. statements . extend ( suffix_stmts) ;
102+ }
104103 }
105104 }
106105}
0 commit comments