]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/transform/deaggregator.rs
Auto merge of #61506 - imbrem:mir_body_renaming, r=eddyb
[rust.git] / src / librustc_mir / transform / deaggregator.rs
1 use rustc::mir::*;
2 use rustc::ty::TyCtxt;
3 use crate::transform::{MirPass, MirSource};
4 use crate::util::expand_aggregate;
5
6 pub struct Deaggregator;
7
8 impl MirPass for Deaggregator {
9     fn run_pass<'a, 'tcx>(&self,
10                           tcx: TyCtxt<'a, 'tcx, 'tcx>,
11                           _source: MirSource<'tcx>,
12                           body: &mut Body<'tcx>) {
13         let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
14         let local_decls = &*local_decls;
15         for bb in basic_blocks {
16             bb.expand_statements(|stmt| {
17                 // FIXME(eddyb) don't match twice on `stmt.kind` (post-NLL).
18                 if let StatementKind::Assign(_, ref rhs) = stmt.kind {
19                     if let Rvalue::Aggregate(ref kind, _) = **rhs {
20                         // FIXME(#48193) Deaggregate arrays when it's cheaper to do so.
21                         if let AggregateKind::Array(_) = **kind {
22                             return None;
23                         }
24                     } else {
25                         return None;
26                     }
27                 } else {
28                     return None;
29                 }
30
31                 let stmt = stmt.replace_nop();
32                 let source_info = stmt.source_info;
33                 let (lhs, kind, operands) = match stmt.kind {
34                     StatementKind::Assign(lhs, box rvalue) => {
35                         match rvalue {
36                             Rvalue::Aggregate(kind, operands) => (lhs, kind, operands),
37                             _ => bug!()
38                         }
39                     }
40                     _ => bug!()
41                 };
42
43                 Some(expand_aggregate(
44                     lhs,
45                     operands.into_iter().map(|op| {
46                         let ty = op.ty(local_decls, tcx);
47                         (op, ty)
48                     }),
49                     *kind,
50                     source_info,
51                 ))
52             });
53         }
54     }
55 }