Skip to content

Commit 8cf6c23

Browse files
committed
Cleanup const_prop() some
1 parent 2d22063 commit 8cf6c23

File tree

1 file changed

+75
-72
lines changed

1 file changed

+75
-72
lines changed

src/librustc_mir/transform/const_prop.rs

Lines changed: 75 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
118118
struct ConstPropMachine;
119119

120120
impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
121-
type MemoryKinds= !;
121+
type MemoryKinds = !;
122122
type PointerTag = ();
123123
type ExtraFnVal = !;
124124

@@ -435,79 +435,80 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
435435
let span = source_info.span;
436436

437437
// perform any special checking for specific Rvalue types
438-
if let Rvalue::UnaryOp(op, arg) = rvalue {
439-
trace!("checking UnaryOp(op = {:?}, arg = {:?})", op, arg);
440-
let overflow_check = self.tcx.sess.overflow_checks();
441-
442-
self.use_ecx(source_info, |this| {
443-
// We check overflow in debug mode already
444-
// so should only check in release mode.
445-
if *op == UnOp::Neg && !overflow_check {
446-
let ty = arg.ty(&this.local_decls, this.tcx);
447-
448-
if ty.is_integral() {
449-
let arg = this.ecx.eval_operand(arg, None)?;
450-
let prim = this.ecx.read_immediate(arg)?;
451-
// Need to do overflow check here: For actual CTFE, MIR
452-
// generation emits code that does this before calling the op.
453-
if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
454-
throw_panic!(OverflowNeg)
438+
match rvalue {
439+
Rvalue::UnaryOp(UnOp::Neg, arg) => {
440+
trace!("checking UnaryOp(op = Neg, arg = {:?})", arg);
441+
let overflow_check = self.tcx.sess.overflow_checks();
442+
443+
self.use_ecx(source_info, |this| {
444+
// We check overflow in debug mode already
445+
// so should only check in release mode.
446+
if !overflow_check {
447+
let ty = arg.ty(&this.local_decls, this.tcx);
448+
449+
if ty.is_integral() {
450+
let arg = this.ecx.eval_operand(arg, None)?;
451+
let prim = this.ecx.read_immediate(arg)?;
452+
// Need to do overflow check here: For actual CTFE, MIR
453+
// generation emits code that does this before calling the op.
454+
if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
455+
throw_panic!(OverflowNeg)
456+
}
455457
}
456458
}
457-
}
458459

459-
Ok(())
460-
})?;
461-
} else if let Rvalue::BinaryOp(op, left, right) = rvalue {
462-
trace!("checking BinaryOp(op = {:?}, left = {:?}, right = {:?})", op, left, right);
463-
464-
let r = self.use_ecx(source_info, |this| {
465-
this.ecx.read_immediate(this.ecx.eval_operand(right, None)?)
466-
})?;
467-
if *op == BinOp::Shr || *op == BinOp::Shl {
468-
let left_bits = place_layout.size.bits();
469-
let right_size = r.layout.size;
470-
let r_bits = r.to_scalar().and_then(|r| r.to_bits(right_size));
471-
if r_bits.ok().map_or(false, |b| b >= left_bits as u128) {
472-
let source_scope_local_data = match self.source_scope_local_data {
473-
ClearCrossCrate::Set(ref data) => data,
474-
ClearCrossCrate::Clear => return None,
475-
};
476-
let dir = if *op == BinOp::Shr {
477-
"right"
478-
} else {
479-
"left"
480-
};
481-
let hir_id = source_scope_local_data[source_info.scope].lint_root;
482-
self.tcx.lint_hir(
483-
::rustc::lint::builtin::EXCEEDING_BITSHIFTS,
484-
hir_id,
485-
span,
486-
&format!("attempt to shift {} with overflow", dir));
487-
return None;
488-
}
460+
Ok(())
461+
})?;
489462
}
490-
self.use_ecx(source_info, |this| {
491-
let l = this.ecx.read_immediate(this.ecx.eval_operand(left, None)?)?;
492-
let (_, overflow, _ty) = this.ecx.overflowing_binary_op(*op, l, r)?;
493-
494-
// We check overflow in debug mode already
495-
// so should only check in release mode.
496-
if !this.tcx.sess.overflow_checks() && overflow {
497-
let err = err_panic!(Overflow(*op)).into();
498-
return Err(err);
463+
464+
Rvalue::BinaryOp(op, left, right) => {
465+
trace!("checking BinaryOp(op = {:?}, left = {:?}, right = {:?})", op, left, right);
466+
467+
let r = self.use_ecx(source_info, |this| {
468+
this.ecx.read_immediate(this.ecx.eval_operand(right, None)?)
469+
})?;
470+
if *op == BinOp::Shr || *op == BinOp::Shl {
471+
let left_bits = place_layout.size.bits();
472+
let right_size = r.layout.size;
473+
let r_bits = r.to_scalar().and_then(|r| r.to_bits(right_size));
474+
if r_bits.ok().map_or(false, |b| b >= left_bits as u128) {
475+
let source_scope_local_data = match self.source_scope_local_data {
476+
ClearCrossCrate::Set(ref data) => data,
477+
ClearCrossCrate::Clear => return None,
478+
};
479+
let dir = if *op == BinOp::Shr {
480+
"right"
481+
} else {
482+
"left"
483+
};
484+
let hir_id = source_scope_local_data[source_info.scope].lint_root;
485+
self.tcx.lint_hir(
486+
::rustc::lint::builtin::EXCEEDING_BITSHIFTS,
487+
hir_id,
488+
span,
489+
&format!("attempt to shift {} with overflow", dir));
490+
return None;
491+
}
499492
}
493+
self.use_ecx(source_info, |this| {
494+
let l = this.ecx.read_immediate(this.ecx.eval_operand(left, None)?)?;
495+
let (_, overflow, _ty) = this.ecx.overflowing_binary_op(*op, l, r)?;
496+
497+
// We check overflow in debug mode already
498+
// so should only check in release mode.
499+
if !this.tcx.sess.overflow_checks() && overflow {
500+
let err = err_panic!(Overflow(*op)).into();
501+
return Err(err);
502+
}
500503

501-
Ok(())
502-
})?;
503-
} else if let Rvalue::Ref(_, _, place) = rvalue {
504-
trace!("checking Ref({:?})", place);
505-
// FIXME(wesleywiser) we don't currently handle the case where we try to make a ref
506-
// from a function argument that hasn't been assigned to in this function.
507-
if let Place {
508-
base: PlaceBase::Local(local),
509-
projection: box []
510-
} = place {
504+
Ok(())
505+
})?;
506+
}
507+
508+
Rvalue::Ref(_, _, Place { base: PlaceBase::Local(local), projection: box [] }) => {
509+
trace!("checking Ref({:?})", place);
510+
// FIXME(wesleywiser) we don't currently handle the case where we try to make a ref
511+
// from a function argument that hasn't been assigned to in this function.
511512
let alive =
512513
if let LocalValue::Live(_) = self.ecx.frame().locals[*local].value {
513514
true
@@ -518,12 +519,14 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
518519
return None;
519520
}
520521
}
521-
} else if let Rvalue::Aggregate(_, operands) = rvalue {
522-
// FIXME(wesleywiser): const eval will turn this into a `const Scalar(<ZST>)` that
523-
// `SimplifyLocals` doesn't know it can remove.
524-
if operands.len() == 0 {
522+
523+
Rvalue::Aggregate(_, operands) if operands.len() == 0 => {
524+
// FIXME(wesleywiser): const eval will turn this into a `const Scalar(<ZST>)` that
525+
// `SimplifyLocals` doesn't know it can remove.
525526
return None;
526527
}
528+
529+
_ => { }
527530
}
528531

529532
self.use_ecx(source_info, |this| {

0 commit comments

Comments
 (0)