Skip to content

Commit aeba7d5

Browse files
Rollup merge of #151773 - dianne:cleanup-division-promotion, r=oli-obk
clean up checks for constant promotion of integer division/remainder operations I found the old logic with matches on `Option`s returned by other matches to be kind of complicated, so I rewrote it with `let` chains. There should be no change in behavior.
2 parents 775abf4 + 5ddb7f6 commit aeba7d5

File tree

1 file changed

+24
-38
lines changed

1 file changed

+24
-38
lines changed

compiler/rustc_mir_transform/src/promote_consts.rs

Lines changed: 24 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -485,47 +485,33 @@ impl<'tcx> Validator<'_, 'tcx> {
485485
if lhs_ty.is_integral() {
486486
let sz = lhs_ty.primitive_size(self.tcx);
487487
// Integer division: the RHS must be a non-zero const.
488-
let rhs_val = match rhs {
489-
Operand::Constant(c)
490-
if self.should_evaluate_for_promotion_checks(c.const_) =>
491-
{
492-
c.const_.try_eval_scalar_int(self.tcx, self.typing_env)
493-
}
494-
_ => None,
495-
};
496-
match rhs_val.map(|x| x.to_uint(sz)) {
488+
let rhs_val = if let Operand::Constant(rhs_c) = rhs
489+
&& self.should_evaluate_for_promotion_checks(rhs_c.const_)
490+
&& let Some(rhs_val) =
491+
rhs_c.const_.try_eval_scalar_int(self.tcx, self.typing_env)
497492
// for the zero test, int vs uint does not matter
498-
Some(x) if x != 0 => {} // okay
499-
_ => return Err(Unpromotable), // value not known or 0 -- not okay
500-
}
493+
&& rhs_val.to_uint(sz) != 0
494+
{
495+
rhs_val
496+
} else {
497+
// value not known or 0 -- not okay
498+
return Err(Unpromotable);
499+
};
501500
// Furthermore, for signed division, we also have to exclude `int::MIN /
502501
// -1`.
503-
if lhs_ty.is_signed() {
504-
match rhs_val.map(|x| x.to_int(sz)) {
505-
Some(-1) | None => {
506-
// The RHS is -1 or unknown, so we have to be careful.
507-
// But is the LHS int::MIN?
508-
let lhs_val = match lhs {
509-
Operand::Constant(c)
510-
if self.should_evaluate_for_promotion_checks(
511-
c.const_,
512-
) =>
513-
{
514-
c.const_
515-
.try_eval_scalar_int(self.tcx, self.typing_env)
516-
}
517-
_ => None,
518-
};
519-
let lhs_min = sz.signed_int_min();
520-
match lhs_val.map(|x| x.to_int(sz)) {
521-
// okay
522-
Some(x) if x != lhs_min => {}
523-
524-
// value not known or int::MIN -- not okay
525-
_ => return Err(Unpromotable),
526-
}
527-
}
528-
_ => {}
502+
if lhs_ty.is_signed() && rhs_val.to_int(sz) == -1 {
503+
// The RHS is -1, so we have to be careful. But is the LHS int::MIN?
504+
if let Operand::Constant(lhs_c) = lhs
505+
&& self.should_evaluate_for_promotion_checks(lhs_c.const_)
506+
&& let Some(lhs_val) =
507+
lhs_c.const_.try_eval_scalar_int(self.tcx, self.typing_env)
508+
&& let lhs_min = sz.signed_int_min()
509+
&& lhs_val.to_int(sz) != lhs_min
510+
{
511+
// okay
512+
} else {
513+
// value not known or int::MIN -- not okay
514+
return Err(Unpromotable);
529515
}
530516
}
531517
}

0 commit comments

Comments
 (0)