Skip to content

Commit cebb9cf

Browse files
committed
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) #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`
2 parents b1575cb + 9ac8b36 commit cebb9cf

File tree

76 files changed

+386
-362
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+386
-362
lines changed

Diff for: compiler/rustc_codegen_cranelift/src/base.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,10 @@ pub(crate) fn verify_func(
250250
}
251251

252252
fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
253-
if !crate::constant::check_constants(fx) {
253+
if let Err(err) =
254+
fx.mir.post_mono_checks(fx.tcx, ty::ParamEnv::reveal_all(), |c| Ok(fx.monomorphize(c)))
255+
{
256+
err.emit_err(fx.tcx);
254257
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
255258
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
256259
// compilation should have been aborted

Diff for: compiler/rustc_codegen_cranelift/src/constant.rs

+7-29
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
33
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
44
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
5-
use rustc_middle::mir::interpret::{
6-
read_target_uint, AllocId, ConstValue, ErrorHandled, GlobalAlloc, Scalar,
7-
};
5+
use rustc_middle::mir::interpret::{read_target_uint, AllocId, ConstValue, GlobalAlloc, Scalar};
86

97
use cranelift_module::*;
108

@@ -33,16 +31,6 @@ impl ConstantCx {
3331
}
3432
}
3533

36-
pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool {
37-
let mut all_constants_ok = true;
38-
for constant in &fx.mir.required_consts {
39-
if eval_mir_constant(fx, constant).is_none() {
40-
all_constants_ok = false;
41-
}
42-
}
43-
all_constants_ok
44-
}
45-
4634
pub(crate) fn codegen_static(tcx: TyCtxt<'_>, module: &mut dyn Module, def_id: DefId) {
4735
let mut constants_cx = ConstantCx::new();
4836
constants_cx.todo.push(TodoItem::Static(def_id));
@@ -76,30 +64,20 @@ pub(crate) fn codegen_tls_ref<'tcx>(
7664
pub(crate) fn eval_mir_constant<'tcx>(
7765
fx: &FunctionCx<'_, '_, 'tcx>,
7866
constant: &Constant<'tcx>,
79-
) -> Option<(ConstValue<'tcx>, Ty<'tcx>)> {
67+
) -> (ConstValue<'tcx>, Ty<'tcx>) {
8068
let cv = fx.monomorphize(constant.literal);
69+
// This cannot fail because we checked all required_consts in advance.
8170
let val = cv
8271
.eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(constant.span))
83-
.map_err(|err| match err {
84-
ErrorHandled::Reported(_) => {
85-
fx.tcx.sess.span_err(constant.span, "erroneous constant encountered");
86-
}
87-
ErrorHandled::TooGeneric => {
88-
span_bug!(constant.span, "codegen encountered polymorphic constant: {:?}", err);
89-
}
90-
})
91-
.ok();
92-
val.map(|val| (val, cv.ty()))
72+
.expect("erroneous constant not captured by required_consts");
73+
(val, cv.ty())
9374
}
9475

9576
pub(crate) fn codegen_constant_operand<'tcx>(
9677
fx: &mut FunctionCx<'_, '_, 'tcx>,
9778
constant: &Constant<'tcx>,
9879
) -> CValue<'tcx> {
99-
let (const_val, ty) = eval_mir_constant(fx, constant).unwrap_or_else(|| {
100-
span_bug!(constant.span, "erroneous constant not captured by required_consts")
101-
});
102-
80+
let (const_val, ty) = eval_mir_constant(fx, constant);
10381
codegen_const_value(fx, const_val, ty)
10482
}
10583

@@ -459,7 +437,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
459437
operand: &Operand<'tcx>,
460438
) -> Option<ConstValue<'tcx>> {
461439
match operand {
462-
Operand::Constant(const_) => Some(eval_mir_constant(fx, const_).unwrap().0),
440+
Operand::Constant(const_) => Some(eval_mir_constant(fx, const_).0),
463441
// FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored
464442
// inside a temporary before being passed to the intrinsic requiring the const argument.
465443
// This code tries to find a single constant defining definition of the referenced local.

Diff for: compiler/rustc_codegen_cranelift/src/inline_asm.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
242242
}
243243
}
244244
InlineAsmOperand::Const { ref value } => {
245-
let (const_value, ty) = crate::constant::eval_mir_constant(fx, value)
246-
.unwrap_or_else(|| span_bug!(span, "asm const cannot be resolved"));
245+
let (const_value, ty) = crate::constant::eval_mir_constant(fx, value);
247246
let value = rustc_codegen_ssa::common::asm_const_to_str(
248247
fx.tcx,
249248
span,

Diff for: compiler/rustc_codegen_ssa/messages.ftl

-4
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ codegen_ssa_copy_path_buf = unable to copy {$source_file} to {$output_path}: {$e
1919
2020
codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error}
2121
22-
codegen_ssa_erroneous_constant = erroneous constant encountered
23-
2422
codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$error}
2523
2624
codegen_ssa_expected_coverage_symbol = expected `coverage(off)` or `coverage(on)`
@@ -174,8 +172,6 @@ codegen_ssa_no_natvis_directory = error enumerating natvis directory: {$error}
174172
175173
codegen_ssa_option_gcc_only = option `-Z gcc-ld` is used even though linker flavor is not gcc
176174
177-
codegen_ssa_polymorphic_constant_too_generic = codegen encountered polymorphic constant: TooGeneric
178-
179175
codegen_ssa_processing_dymutil_failed = processing debug info with `dsymutil` failed: {$status}
180176
.note = {$output}
181177

Diff for: compiler/rustc_codegen_ssa/src/errors.rs

-14
Original file line numberDiff line numberDiff line change
@@ -595,20 +595,6 @@ pub struct InvalidWindowsSubsystem {
595595
pub subsystem: Symbol,
596596
}
597597

598-
#[derive(Diagnostic)]
599-
#[diag(codegen_ssa_erroneous_constant)]
600-
pub struct ErroneousConstant {
601-
#[primary_span]
602-
pub span: Span,
603-
}
604-
605-
#[derive(Diagnostic)]
606-
#[diag(codegen_ssa_polymorphic_constant_too_generic)]
607-
pub struct PolymorphicConstantTooGeneric {
608-
#[primary_span]
609-
pub span: Span,
610-
}
611-
612598
#[derive(Diagnostic)]
613599
#[diag(codegen_ssa_shuffle_indices_evaluation)]
614600
pub struct ShuffleIndicesEvaluation {

Diff for: compiler/rustc_codegen_ssa/src/mir/block.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1088,9 +1088,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
10881088
InlineAsmOperandRef::InOut { reg, late, in_value, out_place }
10891089
}
10901090
mir::InlineAsmOperand::Const { ref value } => {
1091-
let const_value = self
1092-
.eval_mir_constant(value)
1093-
.unwrap_or_else(|_| span_bug!(span, "asm const cannot be resolved"));
1091+
let const_value = self.eval_mir_constant(value);
10941092
let string = common::asm_const_to_str(
10951093
bx.tcx(),
10961094
span,

Diff for: compiler/rustc_codegen_ssa/src/mir/constant.rs

+5-23
Original file line numberDiff line numberDiff line change
@@ -14,34 +14,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
1414
&self,
1515
bx: &mut Bx,
1616
constant: &mir::Constant<'tcx>,
17-
) -> Result<OperandRef<'tcx, Bx::Value>, ErrorHandled> {
18-
let val = self.eval_mir_constant(constant)?;
17+
) -> OperandRef<'tcx, Bx::Value> {
18+
let val = self.eval_mir_constant(constant);
1919
let ty = self.monomorphize(constant.ty());
20-
Ok(OperandRef::from_const(bx, val, ty))
20+
OperandRef::from_const(bx, val, ty)
2121
}
2222

23-
pub fn eval_mir_constant(
24-
&self,
25-
constant: &mir::Constant<'tcx>,
26-
) -> Result<ConstValue<'tcx>, ErrorHandled> {
23+
pub fn eval_mir_constant(&self, constant: &mir::Constant<'tcx>) -> ConstValue<'tcx> {
2724
self.monomorphize(constant.literal)
2825
.eval(self.cx.tcx(), ty::ParamEnv::reveal_all(), Some(constant.span))
29-
.map_err(|err| {
30-
match err {
31-
ErrorHandled::Reported(_) => {
32-
self.cx
33-
.tcx()
34-
.sess
35-
.emit_err(errors::ErroneousConstant { span: constant.span });
36-
}
37-
ErrorHandled::TooGeneric => {
38-
self.cx.tcx().sess.diagnostic().emit_bug(
39-
errors::PolymorphicConstantTooGeneric { span: constant.span },
40-
);
41-
}
42-
}
43-
err
44-
})
26+
.expect("erroneous constant not captured by required_consts")
4527
}
4628

4729
/// This is a convenience helper for `simd_shuffle_indices`. It has the precondition

Diff for: compiler/rustc_codegen_ssa/src/mir/debuginfo.rs

+6-17
Original file line numberDiff line numberDiff line change
@@ -579,23 +579,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
579579
if let Some(dbg_var) = dbg_var {
580580
let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue };
581581

582-
if let Ok(operand) = self.eval_mir_constant_to_operand(bx, &c) {
583-
self.set_debug_loc(bx, var.source_info);
584-
let base = Self::spill_operand_to_stack(
585-
operand,
586-
Some(var.name.to_string()),
587-
bx,
588-
);
589-
590-
bx.dbg_var_addr(
591-
dbg_var,
592-
dbg_loc,
593-
base.llval,
594-
Size::ZERO,
595-
&[],
596-
fragment,
597-
);
598-
}
582+
let operand = self.eval_mir_constant_to_operand(bx, &c);
583+
self.set_debug_loc(bx, var.source_info);
584+
let base =
585+
Self::spill_operand_to_stack(operand, Some(var.name.to_string()), bx);
586+
587+
bx.dbg_var_addr(dbg_var, dbg_loc, base.llval, Size::ZERO, &[], fragment);
599588
}
600589
}
601590
}

Diff for: compiler/rustc_codegen_ssa/src/mir/mod.rs

+8-18
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use crate::traits::*;
33
use rustc_index::bit_set::BitSet;
44
use rustc_index::IndexVec;
55
use rustc_middle::mir;
6-
use rustc_middle::mir::interpret::ErrorHandled;
76
use rustc_middle::mir::traversal;
87
use rustc_middle::mir::UnwindTerminateReason;
98
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout};
@@ -212,23 +211,14 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
212211

213212
fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut start_bx);
214213

215-
// Evaluate all required consts; codegen later assumes that CTFE will never fail.
216-
let mut all_consts_ok = true;
217-
for const_ in &mir.required_consts {
218-
if let Err(err) = fx.eval_mir_constant(const_) {
219-
all_consts_ok = false;
220-
match err {
221-
// errored or at least linted
222-
ErrorHandled::Reported(_) => {}
223-
ErrorHandled::TooGeneric => {
224-
span_bug!(const_.span, "codegen encountered polymorphic constant: {:?}", err)
225-
}
226-
}
227-
}
228-
}
229-
if !all_consts_ok {
230-
// We leave the IR in some half-built state here, and rely on this code not even being
231-
// submitted to LLVM once an error was raised.
214+
// Rust post-monomorphization checks; we later rely on them.
215+
if let Err(err) =
216+
mir.post_mono_checks(cx.tcx(), ty::ParamEnv::reveal_all(), |c| Ok(fx.monomorphize(c)))
217+
{
218+
err.emit_err(cx.tcx());
219+
// This IR shouldn't ever be emitted, but let's try to guard against any of this code
220+
// ever running.
221+
start_bx.abort();
232222
return;
233223
}
234224

Diff for: compiler/rustc_codegen_ssa/src/mir/operand.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -575,12 +575,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
575575
self.codegen_consume(bx, place.as_ref())
576576
}
577577

578-
mir::Operand::Constant(ref constant) => {
579-
// This cannot fail because we checked all required_consts in advance.
580-
self.eval_mir_constant_to_operand(bx, constant).unwrap_or_else(|_err| {
581-
span_bug!(constant.span, "erroneous constant not captured by required_consts")
582-
})
583-
}
578+
mir::Operand::Constant(ref constant) => self.eval_mir_constant_to_operand(bx, constant),
584579
}
585580
}
586581
}

Diff for: compiler/rustc_const_eval/messages.ftl

-3
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,6 @@ const_eval_dyn_call_vtable_mismatch =
8383
const_eval_dyn_star_call_vtable_mismatch =
8484
`dyn*` call on a pointer whose vtable does not match its type
8585
86-
const_eval_erroneous_constant =
87-
erroneous constant used
88-
8986
const_eval_error = {$error_kind ->
9087
[static] could not evaluate static initializer
9188
[const] evaluation of constant value failed

Diff for: compiler/rustc_const_eval/src/const_eval/error.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_errors::{DiagnosticArgValue, DiagnosticMessage, IntoDiagnostic, IntoDi
44
use rustc_middle::mir::AssertKind;
55
use rustc_middle::ty::TyCtxt;
66
use rustc_middle::ty::{layout::LayoutError, ConstInt};
7-
use rustc_span::{ErrorGuaranteed, Span, Symbol};
7+
use rustc_span::{ErrorGuaranteed, Span, Symbol, DUMMY_SP};
88

99
use super::InterpCx;
1010
use crate::errors::{self, FrameNote, ReportErrorExt};
@@ -134,11 +134,11 @@ where
134134
// Don't emit a new diagnostic for these errors, they are already reported elsewhere or
135135
// should remain silent.
136136
err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => {
137-
ErrorHandled::TooGeneric
137+
ErrorHandled::TooGeneric(span.unwrap_or(DUMMY_SP))
138138
}
139-
err_inval!(AlreadyReported(guar)) => ErrorHandled::Reported(guar),
139+
err_inval!(AlreadyReported(guar)) => ErrorHandled::Reported(guar, span.unwrap_or(DUMMY_SP)),
140140
err_inval!(Layout(LayoutError::ReferencesError(guar))) => {
141-
ErrorHandled::Reported(guar.into())
141+
ErrorHandled::Reported(guar.into(), span.unwrap_or(DUMMY_SP))
142142
}
143143
// Report remaining errors.
144144
_ => {
@@ -152,7 +152,7 @@ where
152152

153153
// Use *our* span to label the interp error
154154
err.span_label(our_span, msg);
155-
ErrorHandled::Reported(err.emit().into())
155+
ErrorHandled::Reported(err.emit().into(), span)
156156
}
157157
}
158158
}

Diff for: compiler/rustc_const_eval/src/const_eval/eval_queries.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
212212
key.param_env = key.param_env.with_user_facing();
213213
match tcx.eval_to_const_value_raw(key) {
214214
// try again with reveal all as requested
215-
Err(ErrorHandled::TooGeneric) => {}
215+
Err(ErrorHandled::TooGeneric(_)) => {}
216216
// deduplicate calls
217217
other => return other,
218218
}
@@ -259,7 +259,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
259259
key.param_env = key.param_env.with_user_facing();
260260
match tcx.eval_to_allocation_raw(key) {
261261
// try again with reveal all as requested
262-
Err(ErrorHandled::TooGeneric) => {}
262+
Err(ErrorHandled::TooGeneric(_)) => {}
263263
// deduplicate calls
264264
other => return other,
265265
}

Diff for: compiler/rustc_const_eval/src/errors.rs

-7
Original file line numberDiff line numberDiff line change
@@ -239,13 +239,6 @@ pub struct LongRunningWarn {
239239
pub item_span: Span,
240240
}
241241

242-
#[derive(Diagnostic)]
243-
#[diag(const_eval_erroneous_constant)]
244-
pub(crate) struct ErroneousConstUsed {
245-
#[primary_span]
246-
pub span: Span,
247-
}
248-
249242
#[derive(Subdiagnostic)]
250243
#[note(const_eval_non_const_impl)]
251244
pub(crate) struct NonConstImplNote {

0 commit comments

Comments
 (0)