add comments explaining where post-mono const eval errors abort compilation

This commit is contained in:
Ralf Jung 2024-03-10 12:39:53 +01:00
parent 39db6a0972
commit d765fb8faf
5 changed files with 15 additions and 8 deletions

View file

@ -71,7 +71,7 @@ pub(crate) fn eval_mir_constant<'tcx>(
// This cannot fail because we checked all required_consts in advance. // 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))
.expect("erroneous constant not captured by required_consts"); .expect("erroneous constant missed by mono item collection");
(val, cv.ty()) (val, cv.ty())
} }

View file

@ -21,11 +21,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
} }
pub fn eval_mir_constant(&self, constant: &mir::ConstOperand<'tcx>) -> mir::ConstValue<'tcx> { pub fn eval_mir_constant(&self, constant: &mir::ConstOperand<'tcx>) -> mir::ConstValue<'tcx> {
// `MirUsedCollector` visited all constants before codegen began, so if we got here there // `MirUsedCollector` visited all required_consts before codegen began, so if we got here
// can be no more constants that fail to evaluate. // there can be no more constants that fail to evaluate.
self.monomorphize(constant.const_) self.monomorphize(constant.const_)
.eval(self.cx.tcx(), ty::ParamEnv::reveal_all(), Some(constant.span)) .eval(self.cx.tcx(), ty::ParamEnv::reveal_all(), Some(constant.span))
.expect("erroneous constant not captured by required_consts") .expect("erroneous constant missed by mono item collection")
} }
/// This is a convenience helper for `simd_shuffle_indices`. It has the precondition /// This is a convenience helper for `simd_shuffle_indices`. It has the precondition

View file

@ -211,7 +211,8 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
// It may seem like we should iterate over `required_consts` to ensure they all successfully // It may seem like we should iterate over `required_consts` to ensure they all successfully
// evaluate; however, the `MirUsedCollector` already did that during the collection phase of // evaluate; however, the `MirUsedCollector` already did that during the collection phase of
// monomorphization so we don't have to do it again. // monomorphization, and if there is an error during collection then codegen never starts -- so
// we don't have to do it again.
fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut start_bx); fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut start_bx);

View file

@ -814,13 +814,16 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
self.super_rvalue(rvalue, location); self.super_rvalue(rvalue, location);
} }
/// This does not walk the constant, as it has been handled entirely here and trying /// This does not walk the MIR of the constant as that is not needed for codegen, all we need is
/// to walk it would attempt to evaluate the `ty::Const` inside, which doesn't necessarily /// to ensure that the constant evaluates successfully and walk the result.
/// work, as some constants cannot be represented in the type system.
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "debug")]
fn visit_constant(&mut self, constant: &mir::ConstOperand<'tcx>, location: Location) { fn visit_constant(&mut self, constant: &mir::ConstOperand<'tcx>, location: Location) {
let const_ = self.monomorphize(constant.const_); let const_ = self.monomorphize(constant.const_);
let param_env = ty::ParamEnv::reveal_all(); let param_env = ty::ParamEnv::reveal_all();
// Evaluate the constant. This makes const eval failure a collection-time error (rather than
// a codegen-time error). rustc stops after collection if there was an error, so this
// ensures codegen never has to worry about failing consts.
// (codegen relies on this and ICEs will happen if this is violated.)
let val = match const_.eval(self.tcx, param_env, None) { let val = match const_.eval(self.tcx, param_env, None) {
Ok(v) => v, Ok(v) => v,
Err(ErrorHandled::Reported(..)) => return, Err(ErrorHandled::Reported(..)) => return,

View file

@ -1114,6 +1114,9 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co
let (items, usage_map) = collector::collect_crate_mono_items(tcx, collection_mode); let (items, usage_map) = collector::collect_crate_mono_items(tcx, collection_mode);
// If there was an error during collection (e.g. from one of the constants we evaluated),
// then we stop here. This way codegen does not have to worry about failing constants.
// (codegen relies on this and ICEs will happen if this is violated.)
tcx.dcx().abort_if_errors(); tcx.dcx().abort_if_errors();
let (codegen_units, _) = tcx.sess.time("partition_and_assert_distinct_symbols", || { let (codegen_units, _) = tcx.sess.time("partition_and_assert_distinct_symbols", || {