about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2021-11-23 14:12:14 -0500
committerRalf Jung <post@ralfj.de>2021-11-23 14:12:14 -0500
commit94c9c22b39d7d82021fe342d19b5248f19335b2f (patch)
tree49ff5dc600db54f71fc04626232291b1873adb74 /compiler/rustc_const_eval/src
parent311fa1f14dd8ffbbe83b229a94b17f7f1ecaf33b (diff)
downloadrust-94c9c22b39d7d82021fe342d19b5248f19335b2f.tar.gz
rust-94c9c22b39d7d82021fe342d19b5248f19335b2f.zip
explain why CTFE/Miri perform truncation on shift offset
Diffstat (limited to 'compiler/rustc_const_eval/src')
-rw-r--r--compiler/rustc_const_eval/src/interpret/operator.rs7
1 files changed, 6 insertions, 1 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs
index ac000b1bb56..a90582fc338 100644
--- a/compiler/rustc_const_eval/src/interpret/operator.rs
+++ b/compiler/rustc_const_eval/src/interpret/operator.rs
@@ -130,7 +130,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             let signed = left_layout.abi.is_signed();
             let size = u128::from(left_layout.size.bits());
             let overflow = r >= size;
-            let r = r % size; // mask to type size
+            // The shift offset is implicitly masked to the type size, to make sure this operation
+            // is always defined. This is the one MIR operator that does *not* directly map to a
+            // single LLVM operation. See
+            // <https://github.com/rust-lang/rust/blob/a3b9405ae7bb6ab4e8103b414e75c44598a10fd2/compiler/rustc_codegen_ssa/src/common.rs#L131-L158>
+            // for the corresponding truncation in our codegen backends.
+            let r = r % size;
             let r = u32::try_from(r).unwrap(); // we masked so this will always fit
             let result = if signed {
                 let l = self.sign_extend(l, left_layout) as i128;