diff options
Diffstat (limited to 'compiler/rustc_mir_transform/src/deaggregator.rs')
-rw-r--r-- | compiler/rustc_mir_transform/src/deaggregator.rs | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/compiler/rustc_mir_transform/src/deaggregator.rs b/compiler/rustc_mir_transform/src/deaggregator.rs new file mode 100644 index 000000000..b93fe5879 --- /dev/null +++ b/compiler/rustc_mir_transform/src/deaggregator.rs @@ -0,0 +1,49 @@ +use crate::util::expand_aggregate; +use crate::MirPass; +use rustc_middle::mir::*; +use rustc_middle::ty::TyCtxt; + +pub struct Deaggregator; + +impl<'tcx> MirPass<'tcx> for Deaggregator { + fn phase_change(&self) -> Option<MirPhase> { + Some(MirPhase::Deaggregated) + } + + fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + let basic_blocks = body.basic_blocks.as_mut_preserves_cfg(); + for bb in basic_blocks { + bb.expand_statements(|stmt| { + // FIXME(eddyb) don't match twice on `stmt.kind` (post-NLL). + match stmt.kind { + // FIXME(#48193) Deaggregate arrays when it's cheaper to do so. + StatementKind::Assign(box ( + _, + Rvalue::Aggregate(box AggregateKind::Array(_), _), + )) => { + return None; + } + StatementKind::Assign(box (_, Rvalue::Aggregate(_, _))) => {} + _ => return None, + } + + let stmt = stmt.replace_nop(); + let source_info = stmt.source_info; + let StatementKind::Assign(box (lhs, Rvalue::Aggregate(kind, operands))) = stmt.kind else { + bug!(); + }; + + Some(expand_aggregate( + lhs, + operands.into_iter().map(|op| { + let ty = op.ty(&body.local_decls, tcx); + (op, ty) + }), + *kind, + source_info, + tcx, + )) + }); + } + } +} |