about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-06-15 12:38:17 +0000
committerbors <bors@rust-lang.org>2024-06-15 12:38:17 +0000
commit687a68d67953eddd0a4bd415b8f7fee679e66595 (patch)
tree1c6dad887e216af2bdf8722ef241a6a5b2381494 /compiler/rustc_const_eval/src
parent1d1356d0f67131f97b4f1631a24cd10d7dbcca42 (diff)
parent92ad0b1cd2cb96878d23d66def53506e38748afe (diff)
Auto merge of #126514 - matthiaskrgr:rollup-pnwi8ns, r=matthiaskrgr
Rollup of 9 pull requests

Successful merges:

 - #126354 (Use `Variance` glob imported variants everywhere)
 - #126367 (Point out failing never obligation for `DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK`)
 - #126469 (MIR Shl/Shr: the offset can be computed with rem_euclid)
 - #126471 (Use a consistent way to filter out bounds instead of splitting it into three places)
 - #126472 (build `libcxx-version` only when it doesn't exist)
 - #126497 (delegation: Fix hygiene for `self`)
 - #126501 (make bors ignore comments in PR template)
 - #126509 (std: suggest OnceLock over Once)
 - #126512 (Miri subtree update)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_const_eval/src')
-rw-r--r--compiler/rustc_const_eval/src/interpret/operator.rs19
1 files changed, 7 insertions, 12 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs
index a6eef9f5662..4d0f35618ef 100644
--- a/compiler/rustc_const_eval/src/interpret/operator.rs
+++ b/compiler/rustc_const_eval/src/interpret/operator.rs
@@ -112,25 +112,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
 
         // Shift ops can have an RHS with a different numeric type.
         if matches!(bin_op, Shl | ShlUnchecked | Shr | ShrUnchecked) {
-            let size = left.layout.size.bits();
+            let l_bits = left.layout.size.bits();
             // Compute the equivalent shift modulo `size` that is in the range `0..size`. (This is
             // the one MIR operator that does *not* directly map to a single LLVM operation.)
             let (shift_amount, overflow) = if right.layout.abi.is_signed() {
                 let shift_amount = r_signed();
-                let overflow = shift_amount < 0 || shift_amount >= i128::from(size);
-                // Deliberately wrapping `as` casts: shift_amount *can* be negative, but the result
-                // of the `as` will be equal modulo `size` (since it is a power of two).
-                let masked_amount = (shift_amount as u128) % u128::from(size);
-                assert_eq!(overflow, shift_amount != i128::try_from(masked_amount).unwrap());
-                (masked_amount, overflow)
+                let rem = shift_amount.rem_euclid(l_bits.into());
+                // `rem` is guaranteed positive, so the `unwrap` cannot fail
+                (u128::try_from(rem).unwrap(), rem != shift_amount)
             } else {
                 let shift_amount = r_unsigned();
-                let overflow = shift_amount >= u128::from(size);
-                let masked_amount = shift_amount % u128::from(size);
-                assert_eq!(overflow, shift_amount != masked_amount);
-                (masked_amount, overflow)
+                let rem = shift_amount.rem_euclid(l_bits.into());
+                (rem, rem != shift_amount)
             };
-            let shift_amount = u32::try_from(shift_amount).unwrap(); // we masked so this will always fit
+            let shift_amount = u32::try_from(shift_amount).unwrap(); // we brought this in the range `0..size` so this will always fit
             // Compute the shifted result.
             let result = if left.layout.abi.is_signed() {
                 let l = l_signed();