const-eval interner: from-scratch rewrite using mutability information from provenance rather than types
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user