about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2023-07-25 09:47:19 +0200
committerRalf Jung <post@ralfj.de>2023-07-25 14:30:58 +0200
commitd1276005119341f381ce1ec04894b24a9275d5f0 (patch)
treed3389011d09588714e054fe71b4d9e6c1b6c4aa6 /compiler/rustc_const_eval/src
parent4ea2bd1c8f6fc5aba40af7b0421f2eea201ba147 (diff)
downloadrust-d1276005119341f381ce1ec04894b24a9275d5f0.tar.gz
rust-d1276005119341f381ce1ec04894b24a9275d5f0.zip
add some sanity checks in write_immediate_no_validate
Diffstat (limited to 'compiler/rustc_const_eval/src')
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs31
1 files changed, 28 insertions, 3 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index 9c492fb8b93..db1239c7136 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -577,7 +577,7 @@ where
         src: Immediate<M::Provenance>,
         dest: &PlaceTy<'tcx, M::Provenance>,
     ) -> InterpResult<'tcx> {
-        assert!(dest.layout.is_sized(), "Cannot write unsized data");
+        assert!(dest.layout.is_sized(), "Cannot write unsized immediate data");
         trace!("write_immediate: {:?} <- {:?}: {}", *dest, src, dest.layout.ty);
 
         // See if we can avoid an allocation. This is the counterpart to `read_immediate_raw`,
@@ -591,9 +591,34 @@ where
                     *self.force_allocation(dest)?
                 } else {
                     match M::access_local_mut(self, frame, local)? {
-                        Operand::Immediate(local) => {
+                        Operand::Immediate(local_val) => {
                             // Local can be updated in-place.
-                            *local = src;
+                            *local_val = src;
+                            // Double-check that the value we are storing and the local fit to each other.
+                            // (*After* doing the update for borrow checker reasons.)
+                            if cfg!(debug_assertions) {
+                                let local_layout =
+                                    self.layout_of_local(&self.stack()[frame], local, None)?;
+                                match (src, local_layout.abi) {
+                                    (Immediate::Scalar(scalar), Abi::Scalar(s)) => {
+                                        assert_eq!(scalar.size(), s.size(self))
+                                    }
+                                    (
+                                        Immediate::ScalarPair(a_val, b_val),
+                                        Abi::ScalarPair(a, b),
+                                    ) => {
+                                        assert_eq!(a_val.size(), a.size(self));
+                                        assert_eq!(b_val.size(), b.size(self));
+                                    }
+                                    (Immediate::Uninit, _) => {}
+                                    (src, abi) => {
+                                        bug!(
+                                            "value {src:?} cannot be written into local with type {} (ABI {abi:?})",
+                                            local_layout.ty
+                                        )
+                                    }
+                                };
+                            }
                             return Ok(());
                         }
                         Operand::Indirect(mplace) => {