about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_const_eval/src')
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs30
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs158
-rw-r--r--compiler/rustc_const_eval/src/interpret/mod.rs1
3 files changed, 73 insertions, 116 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index 569a07c3a01..8fddc7e3249 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -20,7 +20,7 @@ use crate::const_eval::CheckAlignment;
 use crate::interpret::{
     CtfeValidationMode, GlobalId, Immediate, InternKind, InternResult, InterpCx, InterpErrorKind,
     InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, StackPopCleanup, create_static_alloc,
-    eval_nullary_intrinsic, intern_const_alloc_recursive, interp_ok, throw_exhaust,
+    intern_const_alloc_recursive, interp_ok, throw_exhaust,
 };
 use crate::{CTRL_C_RECEIVED, errors};
 
@@ -280,34 +280,6 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
     tcx: TyCtxt<'tcx>,
     key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
 ) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> {
-    // We call `const_eval` for zero arg intrinsics, too, in order to cache their value.
-    // Catch such calls and evaluate them instead of trying to load a constant's MIR.
-    if let ty::InstanceKind::Intrinsic(def_id) = key.value.instance.def {
-        let ty = key.value.instance.ty(tcx, key.typing_env);
-        let ty::FnDef(_, args) = ty.kind() else {
-            bug!("intrinsic with type {:?}", ty);
-        };
-        return eval_nullary_intrinsic(tcx, key.typing_env, def_id, args).report_err().map_err(
-            |error| {
-                let span = tcx.def_span(def_id);
-
-                // FIXME(oli-obk): why don't we have any tests for this code path?
-                super::report(
-                    tcx,
-                    error.into_kind(),
-                    span,
-                    || (span, vec![]),
-                    |diag, span, _| {
-                        diag.span_label(
-                            span,
-                            crate::fluent_generated::const_eval_nullary_intrinsic_fail,
-                        );
-                    },
-                )
-            },
-        );
-    }
-
     tcx.eval_to_allocation_raw(key).map(|val| turn_into_const_value(tcx, val, key))
 }
 
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index b29c5c7c7d7..d7cede71293 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -6,10 +6,9 @@ use std::assert_matches::assert_matches;
 
 use rustc_abi::Size;
 use rustc_apfloat::ieee::{Double, Half, Quad, Single};
-use rustc_hir::def_id::DefId;
 use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic};
 use rustc_middle::ty::layout::{TyAndLayout, ValidityRequirement};
-use rustc_middle::ty::{GenericArgsRef, Ty, TyCtxt};
+use rustc_middle::ty::{Ty, TyCtxt};
 use rustc_middle::{bug, ty};
 use rustc_span::{Symbol, sym};
 use tracing::trace;
@@ -17,8 +16,8 @@ use tracing::trace;
 use super::memory::MemoryKind;
 use super::util::ensure_monomorphic_enough;
 use super::{
-    Allocation, CheckInAllocMsg, ConstAllocation, GlobalId, ImmTy, InterpCx, InterpResult, Machine,
-    OpTy, PlaceTy, Pointer, PointerArithmetic, Provenance, Scalar, err_inval, err_ub_custom,
+    Allocation, CheckInAllocMsg, ConstAllocation, ImmTy, InterpCx, InterpResult, Machine, OpTy,
+    PlaceTy, Pointer, PointerArithmetic, Provenance, Scalar, err_inval, err_ub_custom,
     err_unsup_format, interp_ok, throw_inval, throw_ub_custom, throw_ub_format,
 };
 use crate::fluent_generated as fluent;
@@ -30,73 +29,6 @@ pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAll
     tcx.mk_const_alloc(alloc)
 }
 
-/// The logic for all nullary intrinsics is implemented here. These intrinsics don't get evaluated
-/// inside an `InterpCx` and instead have their value computed directly from rustc internal info.
-pub(crate) fn eval_nullary_intrinsic<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    typing_env: ty::TypingEnv<'tcx>,
-    def_id: DefId,
-    args: GenericArgsRef<'tcx>,
-) -> InterpResult<'tcx, ConstValue<'tcx>> {
-    let tp_ty = args.type_at(0);
-    let name = tcx.item_name(def_id);
-    interp_ok(match name {
-        sym::type_name => {
-            ensure_monomorphic_enough(tcx, tp_ty)?;
-            let alloc = alloc_type_name(tcx, tp_ty);
-            ConstValue::Slice { data: alloc, meta: alloc.inner().size().bytes() }
-        }
-        sym::needs_drop => {
-            ensure_monomorphic_enough(tcx, tp_ty)?;
-            ConstValue::from_bool(tp_ty.needs_drop(tcx, typing_env))
-        }
-        sym::type_id => {
-            ensure_monomorphic_enough(tcx, tp_ty)?;
-            ConstValue::from_u128(tcx.type_id_hash(tp_ty).as_u128())
-        }
-        sym::variant_count => match match tp_ty.kind() {
-            // Pattern types have the same number of variants as their base type.
-            // Even if we restrict e.g. which variants are valid, the variants are essentially just uninhabited.
-            // And `Result<(), !>` still has two variants according to `variant_count`.
-            ty::Pat(base, _) => *base,
-            _ => tp_ty,
-        }
-        .kind()
-        {
-            // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
-            ty::Adt(adt, _) => ConstValue::from_target_usize(adt.variants().len() as u64, &tcx),
-            ty::Alias(..) | ty::Param(_) | ty::Placeholder(_) | ty::Infer(_) => {
-                throw_inval!(TooGeneric)
-            }
-            ty::Pat(..) => unreachable!(),
-            ty::Bound(_, _) => bug!("bound ty during ctfe"),
-            ty::Bool
-            | ty::Char
-            | ty::Int(_)
-            | ty::Uint(_)
-            | ty::Float(_)
-            | ty::Foreign(_)
-            | ty::Str
-            | ty::Array(_, _)
-            | ty::Slice(_)
-            | ty::RawPtr(_, _)
-            | ty::Ref(_, _, _)
-            | ty::FnDef(_, _)
-            | ty::FnPtr(..)
-            | ty::Dynamic(_, _, _)
-            | ty::Closure(_, _)
-            | ty::CoroutineClosure(_, _)
-            | ty::Coroutine(_, _)
-            | ty::CoroutineWitness(..)
-            | ty::UnsafeBinder(_)
-            | ty::Never
-            | ty::Tuple(_)
-            | ty::Error(_) => ConstValue::from_target_usize(0u64, &tcx),
-        },
-        other => bug!("`{}` is not a zero arg intrinsic", other),
-    })
-}
-
 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
@@ -110,8 +42,77 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
     ) -> InterpResult<'tcx, bool> {
         let instance_args = instance.args;
         let intrinsic_name = self.tcx.item_name(instance.def_id());
+        let tcx = self.tcx.tcx;
 
         match intrinsic_name {
+            sym::type_name => {
+                let tp_ty = instance.args.type_at(0);
+                ensure_monomorphic_enough(tcx, tp_ty)?;
+                let alloc = alloc_type_name(tcx, tp_ty);
+                let val = ConstValue::Slice { data: alloc, meta: alloc.inner().size().bytes() };
+                let val = self.const_val_to_op(val, dest.layout.ty, Some(dest.layout))?;
+                self.copy_op(&val, dest)?;
+            }
+            sym::needs_drop => {
+                let tp_ty = instance.args.type_at(0);
+                ensure_monomorphic_enough(tcx, tp_ty)?;
+                let val = ConstValue::from_bool(tp_ty.needs_drop(tcx, self.typing_env));
+                let val = self.const_val_to_op(val, tcx.types.bool, Some(dest.layout))?;
+                self.copy_op(&val, dest)?;
+            }
+            sym::type_id => {
+                let tp_ty = instance.args.type_at(0);
+                ensure_monomorphic_enough(tcx, tp_ty)?;
+                let val = ConstValue::from_u128(tcx.type_id_hash(tp_ty).as_u128());
+                let val = self.const_val_to_op(val, dest.layout.ty, Some(dest.layout))?;
+                self.copy_op(&val, dest)?;
+            }
+            sym::variant_count => {
+                let tp_ty = instance.args.type_at(0);
+                let ty = match tp_ty.kind() {
+                    // Pattern types have the same number of variants as their base type.
+                    // Even if we restrict e.g. which variants are valid, the variants are essentially just uninhabited.
+                    // And `Result<(), !>` still has two variants according to `variant_count`.
+                    ty::Pat(base, _) => *base,
+                    _ => tp_ty,
+                };
+                let val = match ty.kind() {
+                    // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
+                    ty::Adt(adt, _) => {
+                        ConstValue::from_target_usize(adt.variants().len() as u64, &tcx)
+                    }
+                    ty::Alias(..) | ty::Param(_) | ty::Placeholder(_) | ty::Infer(_) => {
+                        throw_inval!(TooGeneric)
+                    }
+                    ty::Pat(..) => unreachable!(),
+                    ty::Bound(_, _) => bug!("bound ty during ctfe"),
+                    ty::Bool
+                    | ty::Char
+                    | ty::Int(_)
+                    | ty::Uint(_)
+                    | ty::Float(_)
+                    | ty::Foreign(_)
+                    | ty::Str
+                    | ty::Array(_, _)
+                    | ty::Slice(_)
+                    | ty::RawPtr(_, _)
+                    | ty::Ref(_, _, _)
+                    | ty::FnDef(_, _)
+                    | ty::FnPtr(..)
+                    | ty::Dynamic(_, _, _)
+                    | ty::Closure(_, _)
+                    | ty::CoroutineClosure(_, _)
+                    | ty::Coroutine(_, _)
+                    | ty::CoroutineWitness(..)
+                    | ty::UnsafeBinder(_)
+                    | ty::Never
+                    | ty::Tuple(_)
+                    | ty::Error(_) => ConstValue::from_target_usize(0u64, &tcx),
+                };
+                let val = self.const_val_to_op(val, dest.layout.ty, Some(dest.layout))?;
+                self.copy_op(&val, dest)?;
+            }
+
             sym::caller_location => {
                 let span = self.find_closest_untracked_caller_location();
                 let val = self.tcx.span_as_caller_location(span);
@@ -137,21 +138,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 self.write_scalar(Scalar::from_target_usize(result, self), dest)?;
             }
 
-            sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => {
-                let gid = GlobalId { instance, promoted: None };
-                let ty = self
-                    .tcx
-                    .fn_sig(instance.def_id())
-                    .instantiate(self.tcx.tcx, instance.args)
-                    .output()
-                    .no_bound_vars()
-                    .unwrap();
-                let val = self
-                    .ctfe_query(|tcx| tcx.const_eval_global_id(self.typing_env, gid, tcx.span))?;
-                let val = self.const_val_to_op(val, ty, Some(dest.layout))?;
-                self.copy_op(&val, dest)?;
-            }
-
             sym::fadd_algebraic
             | sym::fsub_algebraic
             | sym::fmul_algebraic
diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs
index f5792aba207..f8b3c92debb 100644
--- a/compiler/rustc_const_eval/src/interpret/mod.rs
+++ b/compiler/rustc_const_eval/src/interpret/mod.rs
@@ -29,7 +29,6 @@ pub use self::intern::{
     HasStaticRootDefId, InternKind, InternResult, intern_const_alloc_for_constprop,
     intern_const_alloc_recursive,
 };
-pub(crate) use self::intrinsics::eval_nullary_intrinsic;
 pub use self::machine::{AllocMap, Machine, MayLeak, ReturnAction, compile_time_machine};
 pub use self::memory::{AllocInfo, AllocKind, AllocRef, AllocRefMut, FnVal, Memory, MemoryKind};
 use self::operand::Operand;