]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_mir/src/interpret/step.rs
CTFE/Miri engine Pointer type overhaul: make Scalar-to-Pointer conversion infallible
[rust.git] / compiler / rustc_mir / src / interpret / step.rs
index 5a10ffe6d6199c92032cf5ed3884147b19324352..2fbcfcfbe9087d4baed8acde7ac74daf32b86c11 100644 (file)
@@ -222,28 +222,34 @@ pub fn eval_rvalue_into_place(
             }
 
             Repeat(ref operand, _) => {
-                let op = self.eval_operand(operand, None)?;
+                let src = self.eval_operand(operand, None)?;
+                assert!(!src.layout.is_unsized());
                 let dest = self.force_allocation(&dest)?;
                 let length = dest.len(self)?;
 
-                if let Some(first_ptr) = self.check_mplace_access(&dest, None)? {
-                    // Write the first.
+                if length == 0 {
+                    // Nothing to copy... but let's still make sure that `dest` as a place is valid.
+                    self.get_alloc_mut(&dest)?;
+                } else {
+                    // Write the src to the first element.
                     let first = self.mplace_field(&dest, 0)?;
-                    self.copy_op(&op, &first.into())?;
-
-                    if length > 1 {
-                        let elem_size = first.layout.size;
-                        // Copy the rest. This is performance-sensitive code
-                        // for big static/const arrays!
-                        let rest_ptr = first_ptr.offset(elem_size, self)?;
-                        self.memory.copy_repeatedly(
-                            first_ptr,
-                            rest_ptr,
-                            elem_size,
-                            length - 1,
-                            /*nonoverlapping:*/ true,
-                        )?;
-                    }
+                    self.copy_op(&src, &first.into())?;
+
+                    // This is performance-sensitive code for big static/const arrays! So we
+                    // avoid writing each operand individually and instead just make many copies
+                    // of the first element.
+                    let elem_size = first.layout.size;
+                    let first_ptr = first.ptr;
+                    let rest_ptr = first_ptr.offset(elem_size, self)?;
+                    self.memory.copy_repeatedly(
+                        first_ptr,
+                        first.align,
+                        rest_ptr,
+                        first.align,
+                        elem_size,
+                        length - 1,
+                        /*nonoverlapping:*/ true,
+                    )?;
                 }
             }
 
@@ -258,11 +264,7 @@ pub fn eval_rvalue_into_place(
             AddressOf(_, place) | Ref(_, _, place) => {
                 let src = self.eval_place(place)?;
                 let place = self.force_allocation(&src)?;
-                if place.layout.size.bytes() > 0 {
-                    // definitely not a ZST
-                    assert!(place.ptr.is_ptr(), "non-ZST places should be normalized to `Pointer`");
-                }
-                self.write_immediate(place.to_ref(), &dest)?;
+                self.write_immediate(place.to_ref(self), &dest)?;
             }
 
             NullaryOp(mir::NullOp::Box, _) => {