diff options
| author | Jakob Degen <jakob.e.degen@gmail.com> | 2022-05-05 21:15:20 -0400 |
|---|---|---|
| committer | Jakob Degen <jakob.e.degen@gmail.com> | 2022-05-06 15:40:32 -0400 |
| commit | 5289bbece312fb6704febea1a95a601f0dd27b02 (patch) | |
| tree | f5803a3a8687624535cb82e118e86ce1fff89fb8 | |
| parent | e209e85e39b4851c3ec122a45ddeabe318b2d522 (diff) | |
| download | rust-5289bbece312fb6704febea1a95a601f0dd27b02.tar.gz rust-5289bbece312fb6704febea1a95a601f0dd27b02.zip | |
Expand validator to be more precise on checked binary ops
| -rw-r--r-- | compiler/rustc_const_eval/src/transform/validate.rs | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index f71bc586b48..a790a723305 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -291,7 +291,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ty::Array(..) | ty::Slice(..) ); } - Rvalue::BinaryOp(op, vals) | Rvalue::CheckedBinaryOp(op, vals) => { + Rvalue::BinaryOp(op, vals) => { use BinOp::*; let a = vals.0.ty(&self.body.local_decls, self.tcx); let b = vals.1.ty(&self.body.local_decls, self.tcx); @@ -355,17 +355,55 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { for x in [a, b] { check_kinds!( x, - "Cannot perform op on type {:?}", + "Cannot perform arithmetic on type {:?}", ty::Uint(..) | ty::Int(..) | ty::Float(..) ) } if a != b { self.fail( location, - format!("Cannot perform op on unequal types {:?} and {:?}", a, b), + format!( + "Cannot perform arithmetic on unequal types {:?} and {:?}", + a, b + ), + ); + } + } + } + } + Rvalue::CheckedBinaryOp(op, vals) => { + use BinOp::*; + let a = vals.0.ty(&self.body.local_decls, self.tcx); + let b = vals.1.ty(&self.body.local_decls, self.tcx); + match op { + Add | Sub | Mul => { + for x in [a, b] { + check_kinds!( + x, + "Cannot perform checked arithmetic on type {:?}", + ty::Uint(..) | ty::Int(..) + ) + } + if a != b { + self.fail( + location, + format!( + "Cannot perform checked arithmetic on unequal types {:?} and {:?}", + a, b + ), ); } } + Shl | Shr => { + for x in [a, b] { + check_kinds!( + x, + "Cannot perform checked shift on non-integer type {:?}", + ty::Uint(..) | ty::Int(..) + ) + } + } + _ => self.fail(location, format!("There is no checked version of {:?}", op)), } } Rvalue::UnaryOp(op, operand) => { |
