diff options
| author | Ralf Jung <post@ralfj.de> | 2023-12-16 16:24:25 +0100 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2024-01-22 09:28:00 +0100 |
| commit | 2f1a8e2d7a641a398e9e02c8c99e80f6e44dce87 (patch) | |
| tree | e8e044a80ab5b723153703589e31aa24308e2a6e /compiler/rustc_const_eval/src/const_eval | |
| parent | a58ec8ff03b3269b20104eb7eae407be48ab95a7 (diff) | |
| download | rust-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.rs | 32 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/const_eval/machine.rs | 2 |
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()) |
