about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2022-05-10 13:24:39 +0200
committerRalf Jung <post@ralfj.de>2022-05-10 14:23:32 +0200
commit600d9602610d1e6a79f98a2a07a660e945e3d22a (patch)
treecfb4c984363d0fe2e6d927aa6726e3797204c678
parent79c169d5cfab584ac3f9b5c3264d876c9f95db71 (diff)
downloadrust-600d9602610d1e6a79f98a2a07a660e945e3d22a.tar.gz
rust-600d9602610d1e6a79f98a2a07a660e945e3d22a.zip
even tighter checks for layouts on immediate field projections
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs17
1 files changed, 11 insertions, 6 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 83fb83fd3c1..1b32d887367 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -398,22 +398,27 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         };
 
         let field_layout = base.layout.field(self, field);
-        if field_layout.is_zst() {
-            let immediate = Scalar::ZST.into();
-            return Ok(OpTy { op: Operand::Immediate(immediate), layout: field_layout });
-        }
-
         let offset = base.layout.fields.offset(field);
         // This makes several assumptions about what layouts we will encounter; we match what
         // codegen does as good as we can (see `extract_field` in `rustc_codegen_ssa/src/mir/operand.rs`).
-        let field_val = match (*base, base.layout.abi) {
+        let field_val: Immediate<_> = match (*base, base.layout.abi) {
+            // the field contains no information
+            _ if field_layout.is_zst() => {
+                Scalar::ZST.into()
+            }
             // the field covers the entire type
             _ if field_layout.size == base.layout.size => {
+                assert!(match (base.layout.abi, field_layout.abi) {
+                    (Abi::Scalar(..), Abi::Scalar(..)) => true,
+                    (Abi::ScalarPair(..), Abi::ScalarPair(..)) => true,
+                    _ => false,
+                });
                 assert!(offset.bytes() == 0);
                 *base
             }
             // extract fields from types with `ScalarPair` ABI
             (Immediate::ScalarPair(a_val, b_val), Abi::ScalarPair(a, b)) => {
+                assert!(matches!(field_layout.abi, Abi::Scalar(..)));
                 Immediate::from(if offset.bytes() == 0 {
                     assert_eq!(field_layout.size, a.size(self));
                     a_val