Rollup merge of #125173 - scottmcm:never-checked, r=davidtwco
Remove `Rvalue::CheckedBinaryOp` Zulip conversation: <https://rust-lang.zulipchat.com/#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/intrinsics.20vs.20binop.2Funop/near/438729996> cc `@RalfJung` While it's a draft, r? ghost
This commit is contained in:
commit
9987e900c0
61 changed files with 212 additions and 215 deletions
|
@ -971,9 +971,6 @@ impl<'tcx> Debug for Rvalue<'tcx> {
|
|||
with_no_trimmed_paths!(write!(fmt, "{place:?} as {ty} ({kind:?})"))
|
||||
}
|
||||
BinaryOp(ref op, box (ref a, ref b)) => write!(fmt, "{op:?}({a:?}, {b:?})"),
|
||||
CheckedBinaryOp(ref op, box (ref a, ref b)) => {
|
||||
write!(fmt, "Checked{op:?}({a:?}, {b:?})")
|
||||
}
|
||||
UnaryOp(ref op, ref a) => write!(fmt, "{op:?}({a:?})"),
|
||||
Discriminant(ref place) => write!(fmt, "discriminant({place:?})"),
|
||||
NullaryOp(ref op, ref t) => {
|
||||
|
|
|
@ -438,7 +438,6 @@ impl<'tcx> Rvalue<'tcx> {
|
|||
_,
|
||||
)
|
||||
| Rvalue::BinaryOp(_, _)
|
||||
| Rvalue::CheckedBinaryOp(_, _)
|
||||
| Rvalue::NullaryOp(_, _)
|
||||
| Rvalue::UnaryOp(_, _)
|
||||
| Rvalue::Discriminant(_)
|
||||
|
|
|
@ -1295,18 +1295,12 @@ pub enum Rvalue<'tcx> {
|
|||
/// truncated as needed.
|
||||
/// * The `Bit*` operations accept signed integers, unsigned integers, or bools with matching
|
||||
/// types and return a value of that type.
|
||||
/// * The `FooWithOverflow` are like the `Foo`, but returning `(T, bool)` instead of just `T`,
|
||||
/// where the `bool` is true if the result is not equal to the infinite-precision result.
|
||||
/// * The remaining operations accept signed integers, unsigned integers, or floats with
|
||||
/// matching types and return a value of that type.
|
||||
BinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>),
|
||||
|
||||
/// Same as `BinaryOp`, but yields `(T, bool)` with a `bool` indicating an error condition.
|
||||
///
|
||||
/// For addition, subtraction, and multiplication on integers the error condition is set when
|
||||
/// the infinite precision result would not be equal to the actual result.
|
||||
///
|
||||
/// Other combinations of types and operators are unsupported.
|
||||
CheckedBinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>),
|
||||
|
||||
/// Computes a value as described by the operation.
|
||||
NullaryOp(NullOp<'tcx>, Ty<'tcx>),
|
||||
|
||||
|
@ -1449,14 +1443,23 @@ pub enum BinOp {
|
|||
Add,
|
||||
/// Like `Add`, but with UB on overflow. (Integers only.)
|
||||
AddUnchecked,
|
||||
/// Like `Add`, but returns `(T, bool)` of both the wrapped result
|
||||
/// and a bool indicating whether it overflowed.
|
||||
AddWithOverflow,
|
||||
/// The `-` operator (subtraction)
|
||||
Sub,
|
||||
/// Like `Sub`, but with UB on overflow. (Integers only.)
|
||||
SubUnchecked,
|
||||
/// Like `Sub`, but returns `(T, bool)` of both the wrapped result
|
||||
/// and a bool indicating whether it overflowed.
|
||||
SubWithOverflow,
|
||||
/// The `*` operator (multiplication)
|
||||
Mul,
|
||||
/// Like `Mul`, but with UB on overflow. (Integers only.)
|
||||
MulUnchecked,
|
||||
/// Like `Mul`, but returns `(T, bool)` of both the wrapped result
|
||||
/// and a bool indicating whether it overflowed.
|
||||
MulWithOverflow,
|
||||
/// The `/` operator (division)
|
||||
///
|
||||
/// For integer types, division by zero is UB, as is `MIN / -1` for signed.
|
||||
|
|
|
@ -179,12 +179,6 @@ impl<'tcx> Rvalue<'tcx> {
|
|||
let rhs_ty = rhs.ty(local_decls, tcx);
|
||||
op.ty(tcx, lhs_ty, rhs_ty)
|
||||
}
|
||||
Rvalue::CheckedBinaryOp(op, box (ref lhs, ref rhs)) => {
|
||||
let lhs_ty = lhs.ty(local_decls, tcx);
|
||||
let rhs_ty = rhs.ty(local_decls, tcx);
|
||||
let ty = op.ty(tcx, lhs_ty, rhs_ty);
|
||||
Ty::new_tup(tcx, &[ty, tcx.types.bool])
|
||||
}
|
||||
Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, ref operand) => operand.ty(local_decls, tcx),
|
||||
Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx),
|
||||
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => {
|
||||
|
@ -263,6 +257,11 @@ impl<'tcx> BinOp {
|
|||
assert_eq!(lhs_ty, rhs_ty);
|
||||
lhs_ty
|
||||
}
|
||||
&BinOp::AddWithOverflow | &BinOp::SubWithOverflow | &BinOp::MulWithOverflow => {
|
||||
// these should be integers of the same size.
|
||||
assert_eq!(lhs_ty, rhs_ty);
|
||||
Ty::new_tup(tcx, &[lhs_ty, tcx.types.bool])
|
||||
}
|
||||
&BinOp::Shl
|
||||
| &BinOp::ShlUnchecked
|
||||
| &BinOp::Shr
|
||||
|
@ -315,6 +314,9 @@ impl BinOp {
|
|||
BinOp::Le => hir::BinOpKind::Le,
|
||||
BinOp::Ge => hir::BinOpKind::Ge,
|
||||
BinOp::Cmp
|
||||
| BinOp::AddWithOverflow
|
||||
| BinOp::SubWithOverflow
|
||||
| BinOp::MulWithOverflow
|
||||
| BinOp::AddUnchecked
|
||||
| BinOp::SubUnchecked
|
||||
| BinOp::MulUnchecked
|
||||
|
@ -325,4 +327,24 @@ impl BinOp {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// If this is a `FooWithOverflow`, return `Some(Foo)`.
|
||||
pub fn overflowing_to_wrapping(self) -> Option<BinOp> {
|
||||
Some(match self {
|
||||
BinOp::AddWithOverflow => BinOp::Add,
|
||||
BinOp::SubWithOverflow => BinOp::Sub,
|
||||
BinOp::MulWithOverflow => BinOp::Mul,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
/// If this is a `Foo`, return `Some(FooWithOverflow)`.
|
||||
pub fn wrapping_to_overflowing(self) -> Option<BinOp> {
|
||||
Some(match self {
|
||||
BinOp::Add => BinOp::AddWithOverflow,
|
||||
BinOp::Sub => BinOp::SubWithOverflow,
|
||||
BinOp::Mul => BinOp::MulWithOverflow,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -696,8 +696,7 @@ macro_rules! make_mir_visitor {
|
|||
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
||||
}
|
||||
|
||||
Rvalue::BinaryOp(_bin_op, box(lhs, rhs))
|
||||
| Rvalue::CheckedBinaryOp(_bin_op, box(lhs, rhs)) => {
|
||||
Rvalue::BinaryOp(_bin_op, box(lhs, rhs)) => {
|
||||
self.visit_operand(lhs, location);
|
||||
self.visit_operand(rhs, location);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue