Auto merge of #115748 - RalfJung:post-mono, r=oli-obk
move required_consts check to general post-mono-check function This factors some code that is common between the interpreter and the codegen backends into shared helper functions. Also as a side-effect the interpreter now uses the same `eval` functions as everyone else to get the evaluated MIR constants. Also this is in preparation for another post-mono check that will be needed for (the current hackfix for) https://github.com/rust-lang/rust/issues/115709: ensuring that all locals are dynamically sized. I didn't expect this to change diagnostics, but it's just cycle errors that change. r? `@oli-obk`
This commit is contained in:
commit
46b55ae176
@ -250,7 +250,10 @@ pub(crate) fn verify_func(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
|
fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
|
||||||
if !crate::constant::check_constants(fx) {
|
if let Err(err) =
|
||||||
|
fx.mir.post_mono_checks(fx.tcx, ty::ParamEnv::reveal_all(), |c| Ok(fx.monomorphize(c)))
|
||||||
|
{
|
||||||
|
err.emit_err(fx.tcx);
|
||||||
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
|
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
|
||||||
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
|
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
|
||||||
// compilation should have been aborted
|
// compilation should have been aborted
|
||||||
|
@ -2,9 +2,7 @@
|
|||||||
|
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||||
use rustc_middle::mir::interpret::{
|
use rustc_middle::mir::interpret::{read_target_uint, AllocId, ConstValue, GlobalAlloc, Scalar};
|
||||||
read_target_uint, AllocId, ConstValue, ErrorHandled, GlobalAlloc, Scalar,
|
|
||||||
};
|
|
||||||
|
|
||||||
use cranelift_module::*;
|
use cranelift_module::*;
|
||||||
|
|
||||||
@ -33,16 +31,6 @@ pub(crate) fn finalize(mut self, tcx: TyCtxt<'_>, module: &mut dyn Module) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool {
|
|
||||||
let mut all_constants_ok = true;
|
|
||||||
for constant in &fx.mir.required_consts {
|
|
||||||
if eval_mir_constant(fx, constant).is_none() {
|
|
||||||
all_constants_ok = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
all_constants_ok
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn codegen_static(tcx: TyCtxt<'_>, module: &mut dyn Module, def_id: DefId) {
|
pub(crate) fn codegen_static(tcx: TyCtxt<'_>, module: &mut dyn Module, def_id: DefId) {
|
||||||
let mut constants_cx = ConstantCx::new();
|
let mut constants_cx = ConstantCx::new();
|
||||||
constants_cx.todo.push(TodoItem::Static(def_id));
|
constants_cx.todo.push(TodoItem::Static(def_id));
|
||||||
@ -76,30 +64,20 @@ pub(crate) fn codegen_tls_ref<'tcx>(
|
|||||||
pub(crate) fn eval_mir_constant<'tcx>(
|
pub(crate) fn eval_mir_constant<'tcx>(
|
||||||
fx: &FunctionCx<'_, '_, 'tcx>,
|
fx: &FunctionCx<'_, '_, 'tcx>,
|
||||||
constant: &Constant<'tcx>,
|
constant: &Constant<'tcx>,
|
||||||
) -> Option<(ConstValue<'tcx>, Ty<'tcx>)> {
|
) -> (ConstValue<'tcx>, Ty<'tcx>) {
|
||||||
let cv = fx.monomorphize(constant.literal);
|
let cv = fx.monomorphize(constant.literal);
|
||||||
|
// This cannot fail because we checked all required_consts in advance.
|
||||||
let val = cv
|
let val = cv
|
||||||
.eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(constant.span))
|
.eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(constant.span))
|
||||||
.map_err(|err| match err {
|
.expect("erroneous constant not captured by required_consts");
|
||||||
ErrorHandled::Reported(_) => {
|
(val, cv.ty())
|
||||||
fx.tcx.sess.span_err(constant.span, "erroneous constant encountered");
|
|
||||||
}
|
|
||||||
ErrorHandled::TooGeneric => {
|
|
||||||
span_bug!(constant.span, "codegen encountered polymorphic constant: {:?}", err);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
val.map(|val| (val, cv.ty()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn codegen_constant_operand<'tcx>(
|
pub(crate) fn codegen_constant_operand<'tcx>(
|
||||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||||
constant: &Constant<'tcx>,
|
constant: &Constant<'tcx>,
|
||||||
) -> CValue<'tcx> {
|
) -> CValue<'tcx> {
|
||||||
let (const_val, ty) = eval_mir_constant(fx, constant).unwrap_or_else(|| {
|
let (const_val, ty) = eval_mir_constant(fx, constant);
|
||||||
span_bug!(constant.span, "erroneous constant not captured by required_consts")
|
|
||||||
});
|
|
||||||
|
|
||||||
codegen_const_value(fx, const_val, ty)
|
codegen_const_value(fx, const_val, ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,7 +437,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
|
|||||||
operand: &Operand<'tcx>,
|
operand: &Operand<'tcx>,
|
||||||
) -> Option<ConstValue<'tcx>> {
|
) -> Option<ConstValue<'tcx>> {
|
||||||
match operand {
|
match operand {
|
||||||
Operand::Constant(const_) => Some(eval_mir_constant(fx, const_).unwrap().0),
|
Operand::Constant(const_) => Some(eval_mir_constant(fx, const_).0),
|
||||||
// FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored
|
// FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored
|
||||||
// inside a temporary before being passed to the intrinsic requiring the const argument.
|
// inside a temporary before being passed to the intrinsic requiring the const argument.
|
||||||
// This code tries to find a single constant defining definition of the referenced local.
|
// This code tries to find a single constant defining definition of the referenced local.
|
||||||
|
@ -242,8 +242,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
InlineAsmOperand::Const { ref value } => {
|
InlineAsmOperand::Const { ref value } => {
|
||||||
let (const_value, ty) = crate::constant::eval_mir_constant(fx, value)
|
let (const_value, ty) = crate::constant::eval_mir_constant(fx, value);
|
||||||
.unwrap_or_else(|| span_bug!(span, "asm const cannot be resolved"));
|
|
||||||
let value = rustc_codegen_ssa::common::asm_const_to_str(
|
let value = rustc_codegen_ssa::common::asm_const_to_str(
|
||||||
fx.tcx,
|
fx.tcx,
|
||||||
span,
|
span,
|
||||||
|
Loading…
Reference in New Issue
Block a user