about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src/const_eval
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2023-12-16 16:24:25 +0100
committerRalf Jung <post@ralfj.de>2024-01-22 09:28:00 +0100
commit2f1a8e2d7a641a398e9e02c8c99e80f6e44dce87 (patch)
treee8e044a80ab5b723153703589e31aa24308e2a6e /compiler/rustc_const_eval/src/const_eval
parenta58ec8ff03b3269b20104eb7eae407be48ab95a7 (diff)
downloadrust-2f1a8e2d7a641a398e9e02c8c99e80f6e44dce87.tar.gz
rust-2f1a8e2d7a641a398e9e02c8c99e80f6e44dce87.zip
const-eval interner: from-scratch rewrite using mutability information from provenance rather than types
Diffstat (limited to 'compiler/rustc_const_eval/src/const_eval')
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs32
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs2
2 files changed, 20 insertions, 14 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 4236117d75b..6a92ed9717d 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -293,6 +293,9 @@ pub fn eval_in_interpreter<'mir, 'tcx>(
     cid: GlobalId<'tcx>,
     is_static: bool,
 ) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> {
+    // `is_static` just means "in static", it could still be a promoted!
+    debug_assert_eq!(is_static, ecx.tcx.static_mutability(cid.instance.def_id()).is_some());
+
     let res = ecx.load_mir(cid.instance.def, cid.promoted);
     match res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, body)) {
         Err(error) => {
@@ -330,8 +333,7 @@ pub fn eval_in_interpreter<'mir, 'tcx>(
         Ok(mplace) => {
             // Since evaluation had no errors, validate the resulting constant.
             // This is a separate `try` block to provide more targeted error reporting.
-            let validation =
-                const_validate_mplace(&ecx, &mplace, is_static, cid.promoted.is_some());
+            let validation = const_validate_mplace(&ecx, &mplace, cid);
 
             let alloc_id = mplace.ptr().provenance.unwrap().alloc_id();
 
@@ -350,22 +352,26 @@ pub fn eval_in_interpreter<'mir, 'tcx>(
 pub fn const_validate_mplace<'mir, 'tcx>(
     ecx: &InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>,
     mplace: &MPlaceTy<'tcx>,
-    is_static: bool,
-    is_promoted: bool,
+    cid: GlobalId<'tcx>,
 ) -> InterpResult<'tcx> {
     let mut ref_tracking = RefTracking::new(mplace.clone());
     let mut inner = false;
     while let Some((mplace, path)) = ref_tracking.todo.pop() {
-        let mode = if is_static {
-            if is_promoted {
-                // Promoteds in statics are allowed to point to statics.
-                CtfeValidationMode::Const { inner, allow_static_ptrs: true }
-            } else {
-                // a `static`
-                CtfeValidationMode::Regular
+        let mode = match ecx.tcx.static_mutability(cid.instance.def_id()) {
+            Some(_) if cid.promoted.is_some() => {
+                // Promoteds in statics are consts that re allowed to point to statics.
+                CtfeValidationMode::Const {
+                    allow_immutable_unsafe_cell: false,
+                    allow_static_ptrs: true,
+                }
+            }
+            Some(mutbl) => CtfeValidationMode::Static { mutbl }, // a `static`
+            None => {
+                // In normal `const` (not promoted), the outermost allocation is always only copied,
+                // so having `UnsafeCell` in there is okay despite them being in immutable memory.
+                let allow_immutable_unsafe_cell = cid.promoted.is_none() && !inner;
+                CtfeValidationMode::Const { allow_immutable_unsafe_cell, allow_static_ptrs: false }
             }
-        } else {
-            CtfeValidationMode::Const { inner, allow_static_ptrs: false }
         };
         ecx.const_validate_operand(&mplace.into(), path, &mut ref_tracking, mode)?;
         inner = true;
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index 6947ace17c5..6ee29063349 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -723,7 +723,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
             && ty.is_freeze(*ecx.tcx, ecx.param_env)
         {
             let place = ecx.ref_to_mplace(val)?;
-            let new_place = place.map_provenance(|p| p.map(CtfeProvenance::as_immutable));
+            let new_place = place.map_provenance(CtfeProvenance::as_immutable);
             Ok(ImmTy::from_immediate(new_place.to_ref(ecx), val.layout))
         } else {
             Ok(val.clone())