@@ -31,55 +31,55 @@ impl<'tcx> MirPass<'tcx> for Deaggregator {
3131 None => { return ; } ,
3232 _ => { }
3333 } ;
34+
35+ // Do not trigger on constants. Could be revised in future
3436 if let MirSource :: Fn ( _) = source { } else { return ; }
3537
3638 let mut curr: usize = 0 ;
3739 for bb in mir. basic_blocks_mut ( ) {
38- while let Some ( idx) = get_aggregate_statement ( curr, & bb. statements ) {
39- // do the replacement
40- debug ! ( "removing statement {:?}" , idx) ;
41- let src_info = bb. statements [ idx] . source_info ;
42- let mut suffix_stmts = bb. statements . split_off ( idx) ;
43- let orig_stmt = suffix_stmts. remove ( 0 ) ;
44- let StatementKind :: Assign ( ref lhs, ref rhs) = orig_stmt. kind ;
45- if let & Rvalue :: Aggregate ( ref agg_kind, ref operands) = rhs {
46- if let & AggregateKind :: Adt ( adt_def, variant, substs) = agg_kind {
47- let n = bb. statements . len ( ) ;
48- bb. statements . reserve ( n + operands. len ( ) + suffix_stmts. len ( ) ) ;
49- for ( i, op) in operands. iter ( ) . enumerate ( ) {
50- let ref variant_def = adt_def. variants [ variant] ;
51- let ty = variant_def. fields [ variant] . ty ( tcx, substs) ;
52- let rhs = Rvalue :: Use ( op. clone ( ) ) ;
40+ let idx = match get_aggregate_statement ( curr, & bb. statements ) {
41+ Some ( idx) => idx,
42+ None => continue ,
43+ } ;
44+ // do the replacement
45+ debug ! ( "removing statement {:?}" , idx) ;
46+ let src_info = bb. statements [ idx] . source_info ;
47+ let suffix_stmts = bb. statements . split_off ( idx+1 ) ;
48+ let orig_stmt = bb. statements . pop ( ) . unwrap ( ) ;
49+ let StatementKind :: Assign ( ref lhs, ref rhs) = orig_stmt. kind ;
50+ let ( agg_kind, operands) = match rhs {
51+ & Rvalue :: Aggregate ( ref agg_kind, ref operands) => ( agg_kind, operands) ,
52+ _ => span_bug ! ( src_info. span, "expected aggregate, not {:?}" , rhs) ,
53+ } ;
54+ let ( adt_def, variant, substs) = match agg_kind {
55+ & AggregateKind :: Adt ( adt_def, variant, substs) => ( adt_def, variant, substs) ,
56+ _ => span_bug ! ( src_info. span, "expected struct, not {:?}" , rhs) ,
57+ } ;
58+ let n = bb. statements . len ( ) ;
59+ bb. statements . reserve ( n + operands. len ( ) + suffix_stmts. len ( ) ) ;
60+ for ( i, op) in operands. iter ( ) . enumerate ( ) {
61+ let ref variant_def = adt_def. variants [ variant] ;
62+ let ty = variant_def. fields [ variant] . ty ( tcx, substs) ;
63+ let rhs = Rvalue :: Use ( op. clone ( ) ) ;
5364
54- // since we don't handle enums, we don't need a cast
55- let lhs_cast = lhs. clone ( ) ;
65+ // since we don't handle enums, we don't need a cast
66+ let lhs_cast = lhs. clone ( ) ;
5667
57- // if we handled enums:
58- // let lhs_cast = if adt_def.variants.len() > 1 {
59- // Lvalue::Projection(Box::new(LvalueProjection {
60- // base: ai.lhs.clone(),
61- // elem: ProjectionElem::Downcast(ai.adt_def, ai.variant),
62- // }))
63- // } else {
64- // lhs_cast
65- // };
68+ // FIXME we cannot deaggregate enums issue: 35186
6669
67- let lhs_proj = Lvalue :: Projection ( Box :: new ( LvalueProjection {
68- base : lhs_cast,
69- elem : ProjectionElem :: Field ( Field :: new ( i) , ty) ,
70- } ) ) ;
71- let new_statement = Statement {
72- source_info : src_info,
73- kind : StatementKind :: Assign ( lhs_proj, rhs) ,
74- } ;
75- debug ! ( "inserting: {:?} @ {:?}" , new_statement, idx + i) ;
76- bb. statements . push ( new_statement) ;
77- }
78- curr = bb. statements . len ( ) ;
79- bb. statements . extend ( suffix_stmts) ;
80- }
81- }
70+ let lhs_proj = Lvalue :: Projection ( Box :: new ( LvalueProjection {
71+ base : lhs_cast,
72+ elem : ProjectionElem :: Field ( Field :: new ( i) , ty) ,
73+ } ) ) ;
74+ let new_statement = Statement {
75+ source_info : src_info,
76+ kind : StatementKind :: Assign ( lhs_proj, rhs) ,
77+ } ;
78+ debug ! ( "inserting: {:?} @ {:?}" , new_statement, idx + i) ;
79+ bb. statements . push ( new_statement) ;
8280 }
81+ curr = bb. statements . len ( ) ;
82+ bb. statements . extend ( suffix_stmts) ;
8383 }
8484 }
8585}
0 commit comments