about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-08-05 23:35:24 +0200
committerGitHub <noreply@github.com>2024-08-05 23:35:24 +0200
commitc53698b399125eccefc9a0a1db582d0739bf7969 (patch)
tree68c663a78c5a31b840d7c2213e93798adf0ba894
parent77f57cbcac3ee4986eef61cadc8c4a601c618cd9 (diff)
parent46896d6f667bad2307efe22a75fc39f040302ae5 (diff)
downloadrust-c53698b399125eccefc9a0a1db582d0739bf7969.tar.gz
rust-c53698b399125eccefc9a0a1db582d0739bf7969.zip
Rollup merge of #128697 - RalfJung:nullary-op, r=compiler-errors
interpret: move nullary-op evaluation into operator.rs

We call it an operator, so we might as well treat it like one. :)

Also use more consistent naming for the "evaluate intrinsic" functions. "emulate" is really the wrong term, this *is* a genuine implementation of the intrinsic semantics after all.
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/operator.rs37
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs43
-rw-r--r--src/tools/miri/src/intrinsics/mod.rs2
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-80742.stderr2
6 files changed, 49 insertions, 41 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index 901149825bf..79e8e212776 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -458,7 +458,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
         _unwind: mir::UnwindAction,
     ) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
         // Shared intrinsics.
-        if ecx.emulate_intrinsic(instance, args, dest, target)? {
+        if ecx.eval_intrinsic(instance, args, dest, target)? {
             return Ok(None);
         }
         let intrinsic_name = ecx.tcx.item_name(instance.def_id());
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 16a0a76a316..9210ec4e16f 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -97,7 +97,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
     /// Returns `true` if emulation happened.
     /// Here we implement the intrinsics that are common to all Miri instances; individual machines can add their own
     /// intrinsic handling.
-    pub fn emulate_intrinsic(
+    pub fn eval_intrinsic(
         &mut self,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx, M::Provenance>],
@@ -447,7 +447,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         Ok(true)
     }
 
-    pub(super) fn emulate_nondiverging_intrinsic(
+    pub(super) fn eval_nondiverging_intrinsic(
         &mut self,
         intrinsic: &NonDivergingIntrinsic<'tcx>,
     ) -> InterpResult<'tcx> {
diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs
index fe5869ad7fa..2f860f9f942 100644
--- a/compiler/rustc_const_eval/src/interpret/operator.rs
+++ b/compiler/rustc_const_eval/src/interpret/operator.rs
@@ -1,8 +1,9 @@
 use either::Either;
 use rustc_apfloat::{Float, FloatConvert};
 use rustc_middle::mir::interpret::{InterpResult, Scalar};
+use rustc_middle::mir::NullOp;
 use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
-use rustc_middle::ty::{self, FloatTy, ScalarInt};
+use rustc_middle::ty::{self, FloatTy, ScalarInt, Ty};
 use rustc_middle::{bug, mir, span_bug};
 use rustc_span::symbol::sym;
 use tracing::trace;
@@ -480,4 +481,38 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             }
         }
     }
+
+    pub fn nullary_op(
+        &self,
+        null_op: NullOp<'tcx>,
+        arg_ty: Ty<'tcx>,
+    ) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
+        use rustc_middle::mir::NullOp::*;
+
+        let layout = self.layout_of(arg_ty)?;
+        let usize_layout = || self.layout_of(self.tcx.types.usize).unwrap();
+
+        Ok(match null_op {
+            SizeOf => {
+                if !layout.abi.is_sized() {
+                    span_bug!(self.cur_span(), "unsized type for `NullaryOp::SizeOf`");
+                }
+                let val = layout.size.bytes();
+                ImmTy::from_uint(val, usize_layout())
+            }
+            AlignOf => {
+                if !layout.abi.is_sized() {
+                    span_bug!(self.cur_span(), "unsized type for `NullaryOp::AlignOf`");
+                }
+                let val = layout.align.abi.bytes();
+                ImmTy::from_uint(val, usize_layout())
+            }
+            OffsetOf(fields) => {
+                let val =
+                    self.tcx.offset_of_subfield(self.param_env, layout, fields.iter()).bytes();
+                ImmTy::from_uint(val, usize_layout())
+            }
+            UbChecks => ImmTy::from_bool(self.tcx.sess.ub_checks(), *self.tcx),
+        })
+    }
 }
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index 211a7b23002..28cf1068f40 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -4,8 +4,7 @@
 
 use either::Either;
 use rustc_index::IndexSlice;
-use rustc_middle::ty::layout::LayoutOf;
-use rustc_middle::{bug, mir, span_bug};
+use rustc_middle::{bug, mir};
 use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
 use tracing::{info, instrument, trace};
 
@@ -94,7 +93,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 M::retag_place_contents(self, *kind, &dest)?;
             }
 
-            Intrinsic(box intrinsic) => self.emulate_nondiverging_intrinsic(intrinsic)?,
+            Intrinsic(box intrinsic) => self.eval_nondiverging_intrinsic(intrinsic)?,
 
             // Evaluate the place expression, without reading from it.
             PlaceMention(box place) => {
@@ -179,6 +178,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 self.write_immediate(*result, &dest)?;
             }
 
+            NullaryOp(null_op, ty) => {
+                let ty = self.instantiate_from_current_frame_and_normalize_erasing_regions(ty)?;
+                let val = self.nullary_op(null_op, ty)?;
+                self.write_immediate(*val, &dest)?;
+            }
+
             Aggregate(box ref kind, ref operands) => {
                 self.write_aggregate(kind, operands, &dest)?;
             }
@@ -230,38 +235,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 self.write_immediate(*val, &dest)?;
             }
 
-            NullaryOp(ref null_op, ty) => {
-                let ty = self.instantiate_from_current_frame_and_normalize_erasing_regions(ty)?;
-                let layout = self.layout_of(ty)?;
-                if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op
-                    && layout.is_unsized()
-                {
-                    span_bug!(
-                        self.frame().current_span(),
-                        "{null_op:?} MIR operator called for unsized type {ty}",
-                    );
-                }
-                let val = match null_op {
-                    mir::NullOp::SizeOf => {
-                        let val = layout.size.bytes();
-                        Scalar::from_target_usize(val, self)
-                    }
-                    mir::NullOp::AlignOf => {
-                        let val = layout.align.abi.bytes();
-                        Scalar::from_target_usize(val, self)
-                    }
-                    mir::NullOp::OffsetOf(fields) => {
-                        let val = self
-                            .tcx
-                            .offset_of_subfield(self.param_env, layout, fields.iter())
-                            .bytes();
-                        Scalar::from_target_usize(val, self)
-                    }
-                    mir::NullOp::UbChecks => Scalar::from_bool(self.tcx.sess.ub_checks()),
-                };
-                self.write_scalar(val, &dest)?;
-            }
-
             ShallowInitBox(ref operand, _) => {
                 let src = self.eval_operand(operand, None)?;
                 let v = self.read_immediate(&src)?;
diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs
index d60119e75f1..18b22827bdb 100644
--- a/src/tools/miri/src/intrinsics/mod.rs
+++ b/src/tools/miri/src/intrinsics/mod.rs
@@ -33,7 +33,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let this = self.eval_context_mut();
 
         // See if the core engine can handle this intrinsic.
-        if this.emulate_intrinsic(instance, args, dest, ret)? {
+        if this.eval_intrinsic(instance, args, dest, ret)? {
             return Ok(None);
         }
         let intrinsic_name = this.tcx.item_name(instance.def_id());
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr
index 8d59235e2f4..01529599d37 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr
@@ -1,4 +1,4 @@
-error: internal compiler error: compiler/rustc_const_eval/src/interpret/step.rs:LL:CC: SizeOf MIR operator called for unsized type dyn Debug
+error: internal compiler error: compiler/rustc_const_eval/src/interpret/operator.rs:LL:CC: unsized type for `NullaryOp::SizeOf`
   --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
 
 Box<dyn Any>