Stop deaggregating enums in MIR.
This commit is contained in:
parent
b62a9da0c8
commit
6a0b218161
41 changed files with 166 additions and 440 deletions
|
|
@ -8,10 +8,10 @@ use rustc_middle::mir::interpret::Scalar;
|
|||
use rustc_middle::mir::visit::NonUseContext::VarDebugInfo;
|
||||
use rustc_middle::mir::visit::{PlaceContext, Visitor};
|
||||
use rustc_middle::mir::{
|
||||
traversal, AggregateKind, BasicBlock, BinOp, Body, BorrowKind, CastKind, CopyNonOverlapping,
|
||||
Local, Location, MirPass, MirPhase, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef,
|
||||
ProjectionElem, RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind,
|
||||
Terminator, TerminatorKind, UnOp, START_BLOCK,
|
||||
traversal, BasicBlock, BinOp, Body, BorrowKind, CastKind, CopyNonOverlapping, Local, Location,
|
||||
MirPass, MirPhase, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef, ProjectionElem,
|
||||
RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator,
|
||||
TerminatorKind, UnOp, START_BLOCK,
|
||||
};
|
||||
use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt};
|
||||
use rustc_mir_dataflow::impls::MaybeStorageLive;
|
||||
|
|
@ -423,19 +423,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
};
|
||||
}
|
||||
match rvalue {
|
||||
Rvalue::Use(_) | Rvalue::CopyForDeref(_) => {}
|
||||
Rvalue::Aggregate(agg_kind, _) => {
|
||||
let disallowed = match **agg_kind {
|
||||
AggregateKind::Array(..) => false,
|
||||
_ => self.mir_phase >= MirPhase::Runtime(RuntimePhase::PostCleanup),
|
||||
};
|
||||
if disallowed {
|
||||
self.fail(
|
||||
location,
|
||||
format!("{:?} have been lowered to field assignments", rvalue),
|
||||
)
|
||||
}
|
||||
}
|
||||
Rvalue::Use(_) | Rvalue::CopyForDeref(_) | Rvalue::Aggregate(..) => {}
|
||||
Rvalue::Ref(_, BorrowKind::Shallow, _) => {
|
||||
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
|
||||
self.fail(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use crate::util::expand_aggregate;
|
||||
use crate::MirPass;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
||||
|
|
@ -11,16 +12,19 @@ impl<'tcx> MirPass<'tcx> for Deaggregator {
|
|||
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 StatementKind::Assign(box (
|
||||
_, Rvalue::Aggregate(box ref kind, _))
|
||||
) = stmt.kind else { return None };
|
||||
|
||||
// FIXME(#48193) Deaggregate arrays when it's cheaper to do so.
|
||||
if let AggregateKind::Array(_) = kind {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let AggregateKind::Adt(def_id, ..) = kind
|
||||
&& matches!(tcx.def_kind(def_id), DefKind::Enum)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
let stmt = stmt.replace_nop();
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@
|
|||
|
||||
use crate::deref_separator::deref_finder;
|
||||
use crate::simplify;
|
||||
use crate::util::expand_aggregate;
|
||||
use crate::MirPass;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_errors::pluralize;
|
||||
|
|
@ -272,31 +271,26 @@ impl<'tcx> TransformVisitor<'tcx> {
|
|||
assert_eq!(self.state_adt_ref.variant(idx).fields.len(), 0);
|
||||
|
||||
// FIXME(swatinem): assert that `val` is indeed unit?
|
||||
statements.extend(expand_aggregate(
|
||||
Place::return_place(),
|
||||
std::iter::empty(),
|
||||
kind,
|
||||
statements.push(Statement {
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
Place::return_place(),
|
||||
Rvalue::Aggregate(Box::new(kind), vec![]),
|
||||
))),
|
||||
source_info,
|
||||
self.tcx,
|
||||
));
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// else: `Poll::Ready(x)`, `GeneratorState::Yielded(x)` or `GeneratorState::Complete(x)`
|
||||
assert_eq!(self.state_adt_ref.variant(idx).fields.len(), 1);
|
||||
|
||||
let ty = self
|
||||
.tcx
|
||||
.bound_type_of(self.state_adt_ref.variant(idx).fields[0].did)
|
||||
.subst(self.tcx, self.state_substs);
|
||||
|
||||
statements.extend(expand_aggregate(
|
||||
Place::return_place(),
|
||||
std::iter::once((val, ty)),
|
||||
kind,
|
||||
statements.push(Statement {
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
Place::return_place(),
|
||||
Rvalue::Aggregate(Box::new(kind), vec![val]),
|
||||
))),
|
||||
source_info,
|
||||
self.tcx,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
// Create a Place referencing a generator struct field
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ use rustc_target::spec::abi::Abi;
|
|||
use std::fmt;
|
||||
use std::iter;
|
||||
|
||||
use crate::util::expand_aggregate;
|
||||
use crate::{
|
||||
abort_unwinding_calls, add_call_guards, add_moves_for_packed_drops, deref_separator,
|
||||
pass_manager as pm, remove_noop_landing_pads, simplify,
|
||||
|
|
@ -831,19 +830,23 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> {
|
|||
// return;
|
||||
debug!("build_ctor: variant_index={:?}", variant_index);
|
||||
|
||||
let statements = expand_aggregate(
|
||||
Place::return_place(),
|
||||
adt_def.variant(variant_index).fields.iter().enumerate().map(|(idx, field_def)| {
|
||||
(Operand::Move(Place::from(Local::new(idx + 1))), field_def.ty(tcx, substs))
|
||||
}),
|
||||
AggregateKind::Adt(adt_def.did(), variant_index, substs, None, None),
|
||||
let kind = AggregateKind::Adt(adt_def.did(), variant_index, substs, None, None);
|
||||
let variant = adt_def.variant(variant_index);
|
||||
let statement = Statement {
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
Place::return_place(),
|
||||
Rvalue::Aggregate(
|
||||
Box::new(kind),
|
||||
(0..variant.fields.len())
|
||||
.map(|idx| Operand::Move(Place::from(Local::new(idx + 1))))
|
||||
.collect(),
|
||||
),
|
||||
))),
|
||||
source_info,
|
||||
tcx,
|
||||
)
|
||||
.collect();
|
||||
};
|
||||
|
||||
let start_block = BasicBlockData {
|
||||
statements,
|
||||
statements: vec![statement],
|
||||
terminator: Some(Terminator { source_info, kind: TerminatorKind::Return }),
|
||||
is_cleanup: false,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue