summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src/interpret
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2021-12-11 23:31:48 +0100
committerGitHub <noreply@github.com>2021-12-11 23:31:48 +0100
commit9383a49cd470d6456199cf1900a4bfbdb95ffa02 (patch)
tree0b89271c1e86b8714d8e405d1a2c87dbc2e764f9 /compiler/rustc_const_eval/src/interpret
parent928783de663bd855a96f14b2d38c1061603587c6 (diff)
parent89b2e0c9d5a4cf87769d2bd51fe6753bbdf6448f (diff)
downloadrust-9383a49cd470d6456199cf1900a4bfbdb95ffa02.tar.gz
rust-9383a49cd470d6456199cf1900a4bfbdb95ffa02.zip
Rollup merge of #90081 - woppopo:const_write_bytes, r=oli-obk
Make `intrinsics::write_bytes` const

This is required to constify `MaybeUninit::zeroed` and `(*mut T)::write_bytes`.

Tracking issue: #86302
Diffstat (limited to 'compiler/rustc_const_eval/src/interpret')
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs24
1 files changed, 24 insertions, 0 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 025d2998b00..18dde3bc34e 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -322,6 +322,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             sym::copy => {
                 self.copy_intrinsic(&args[0], &args[1], &args[2], /*nonoverlapping*/ false)?;
             }
+            sym::write_bytes => {
+                self.write_bytes_intrinsic(&args[0], &args[1], &args[2])?;
+            }
             sym::offset => {
                 let ptr = self.read_pointer(&args[0])?;
                 let offset_count = self.read_scalar(&args[1])?.to_machine_isize(self)?;
@@ -567,6 +570,27 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         self.memory.copy(src, align, dst, align, size, nonoverlapping)
     }
 
+    pub(crate) fn write_bytes_intrinsic(
+        &mut self,
+        dst: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::PointerTag>,
+        byte: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::PointerTag>,
+        count: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::PointerTag>,
+    ) -> InterpResult<'tcx> {
+        let layout = self.layout_of(dst.layout.ty.builtin_deref(true).unwrap().ty)?;
+
+        let dst = self.read_pointer(&dst)?;
+        let byte = self.read_scalar(&byte)?.to_u8()?;
+        let count = self.read_scalar(&count)?.to_machine_usize(self)?;
+
+        let len = layout
+            .size
+            .checked_mul(count, self)
+            .ok_or_else(|| err_ub_format!("overflow computing total size of `write_bytes`"))?;
+
+        let bytes = std::iter::repeat(byte).take(len.bytes_usize());
+        self.memory.write_bytes(dst, bytes)
+    }
+
     pub(crate) fn raw_eq_intrinsic(
         &mut self,
         lhs: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::PointerTag>,