refactor AbstractConstBuilder
This commit is contained in:
parent
c3a772f55f
commit
f24d532749
1 changed files with 69 additions and 60 deletions
|
@ -187,11 +187,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build(mut self) -> Option<&'tcx [Node<'tcx>]> {
|
fn build_statement(&mut self, stmt: &mir::Statement<'tcx>) -> Option<()> {
|
||||||
let mut block = &self.body.basic_blocks()[mir::START_BLOCK];
|
|
||||||
loop {
|
|
||||||
debug!("AbstractConstBuilder: block={:?}", block);
|
|
||||||
for stmt in block.statements.iter() {
|
|
||||||
debug!("AbstractConstBuilder: stmt={:?}", stmt);
|
debug!("AbstractConstBuilder: stmt={:?}", stmt);
|
||||||
match stmt.kind {
|
match stmt.kind {
|
||||||
StatementKind::Assign(box (ref place, ref rvalue)) => {
|
StatementKind::Assign(box (ref place, ref rvalue)) => {
|
||||||
|
@ -208,9 +204,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
||||||
bug!("unexpected unchecked checkable binary operation");
|
bug!("unexpected unchecked checkable binary operation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rvalue::CheckedBinaryOp(op, ref lhs, ref rhs)
|
Rvalue::CheckedBinaryOp(op, ref lhs, ref rhs) if Self::check_binop(op) => {
|
||||||
if Self::check_binop(op) =>
|
|
||||||
{
|
|
||||||
let lhs = self.operand_to_node(lhs)?;
|
let lhs = self.operand_to_node(lhs)?;
|
||||||
let rhs = self.operand_to_node(rhs)?;
|
let rhs = self.operand_to_node(rhs)?;
|
||||||
self.locals[local] = self.add_node(Node::Binop(op, lhs, rhs));
|
self.locals[local] = self.add_node(Node::Binop(op, lhs, rhs));
|
||||||
|
@ -221,17 +215,18 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
_ => return None,
|
_ => return None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("AbstractConstBuilder: terminator={:?}", block.terminator());
|
fn build_terminator(
|
||||||
match block.terminator().kind {
|
&mut self,
|
||||||
TerminatorKind::Goto { target } => {
|
terminator: &mir::Terminator<'tcx>,
|
||||||
block = &self.body.basic_blocks()[target];
|
) -> Option<Option<mir::BasicBlock>> {
|
||||||
}
|
debug!("AbstractConstBuilder: terminator={:?}", terminator);
|
||||||
TerminatorKind::Return => {
|
match terminator.kind {
|
||||||
warn!(?self.nodes);
|
TerminatorKind::Goto { target } => Some(Some(target)),
|
||||||
return { Some(self.tcx.arena.alloc_from_iter(self.nodes)) };
|
TerminatorKind::Return => Some(None),
|
||||||
}
|
|
||||||
TerminatorKind::Assert { ref cond, expected: false, target, .. } => {
|
TerminatorKind::Assert { ref cond, expected: false, target, .. } => {
|
||||||
let p = match cond {
|
let p = match cond {
|
||||||
mir::Operand::Copy(p) | mir::Operand::Move(p) => p,
|
mir::Operand::Copy(p) | mir::Operand::Move(p) => p,
|
||||||
|
@ -243,14 +238,28 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
||||||
if let &[mir::ProjectionElem::Field(ONE_FIELD, _)] = p.projection.as_ref() {
|
if let &[mir::ProjectionElem::Field(ONE_FIELD, _)] = p.projection.as_ref() {
|
||||||
// Only allow asserts checking the result of a checked operation.
|
// Only allow asserts checking the result of a checked operation.
|
||||||
if self.checked_op_locals.contains(p.local) {
|
if self.checked_op_locals.contains(p.local) {
|
||||||
block = &self.body.basic_blocks()[target];
|
return Some(Some(target));
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return None;
|
None
|
||||||
}
|
}
|
||||||
_ => return None,
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build(mut self) -> Option<&'tcx [Node<'tcx>]> {
|
||||||
|
let mut block = &self.body.basic_blocks()[mir::START_BLOCK];
|
||||||
|
loop {
|
||||||
|
debug!("AbstractConstBuilder: block={:?}", block);
|
||||||
|
for stmt in block.statements.iter() {
|
||||||
|
self.build_statement(stmt)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(next) = self.build_terminator(block.terminator())? {
|
||||||
|
block = &self.body.basic_blocks()[next];
|
||||||
|
} else {
|
||||||
|
return Some(self.tcx.arena.alloc_from_iter(self.nodes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,11 +270,11 @@ pub(super) fn mir_abstract_const<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def: ty::WithOptConstParam<LocalDefId>,
|
def: ty::WithOptConstParam<LocalDefId>,
|
||||||
) -> Option<&'tcx [Node<'tcx>]> {
|
) -> Option<&'tcx [Node<'tcx>]> {
|
||||||
if !tcx.features().const_evaluatable_checked {
|
if tcx.features().const_evaluatable_checked {
|
||||||
None
|
|
||||||
} else {
|
|
||||||
let body = tcx.mir_const(def).borrow();
|
let body = tcx.mir_const(def).borrow();
|
||||||
AbstractConstBuilder::new(tcx, &body)?.build()
|
AbstractConstBuilder::new(tcx, &body)?.build()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue