Skip to content

Commit 9b32429

Browse files
committed
Auto merge of #81327 - RalfJung:codegen-no-const-fail, r=oli-obk
codegen: assume constants cannot fail to evaluate #80579 landed, so we can finally remove this old hack from codegen and instead assume that consts never fail to evaluate. :) r? `@oli-obk`
2 parents 7850c28 + 944237f commit 9b32429

File tree

4 files changed

+21
-21
lines changed

4 files changed

+21
-21
lines changed

compiler/rustc_codegen_ssa/src/base.rs

+5
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,11 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
626626
total_codegen_time += start_time.elapsed();
627627
module
628628
};
629+
// This will unwind if there are errors, which triggers our `AbortCodegenOnDrop`
630+
// guard. Unfortunately, just skipping the `submit_codegened_module_to_llvm` makes
631+
// compilation hang on post-monomorphization errors.
632+
tcx.sess.abort_if_errors();
633+
629634
submit_codegened_module_to_llvm(
630635
&backend,
631636
&ongoing_codegen.coordinator_send,

compiler/rustc_codegen_ssa/src/mir/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,11 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
188188

189189
fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut bx);
190190

191+
// Evaluate all required consts; codegen later assumes that CTFE will never fail.
192+
let mut all_consts_ok = true;
191193
for const_ in &mir.required_consts {
192194
if let Err(err) = fx.eval_mir_constant(const_) {
195+
all_consts_ok = false;
193196
match err {
194197
// errored or at least linted
195198
ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {}
@@ -199,6 +202,11 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
199202
}
200203
}
201204
}
205+
if !all_consts_ok {
206+
// We leave the IR in some half-built state here, and rely on this code not even being
207+
// submitted to LLVM once an error was raised.
208+
return;
209+
}
202210

203211
let memory_locals = analyze::non_ssa_locals(&fx);
204212

compiler/rustc_codegen_ssa/src/mir/operand.rs

+4-21
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ use crate::glue;
66
use crate::traits::*;
77
use crate::MemFlags;
88

9-
use rustc_errors::ErrorReported;
109
use rustc_middle::mir;
11-
use rustc_middle::mir::interpret::{ConstValue, ErrorHandled, Pointer, Scalar};
10+
use rustc_middle::mir::interpret::{ConstValue, Pointer, Scalar};
1211
use rustc_middle::ty::layout::TyAndLayout;
1312
use rustc_middle::ty::Ty;
1413
use rustc_target::abi::{Abi, Align, LayoutOf, Size};
@@ -439,25 +438,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
439438
}
440439

441440
mir::Operand::Constant(ref constant) => {
442-
self.eval_mir_constant_to_operand(bx, constant).unwrap_or_else(|err| {
443-
match err {
444-
// errored or at least linted
445-
ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {}
446-
ErrorHandled::TooGeneric => {
447-
bug!("codegen encountered polymorphic constant")
448-
}
449-
}
450-
// Allow RalfJ to sleep soundly knowing that even refactorings that remove
451-
// the above error (or silence it under some conditions) will not cause UB.
452-
bx.abort();
453-
// We still have to return an operand but it doesn't matter,
454-
// this code is unreachable.
455-
let ty = self.monomorphize(constant.literal.ty);
456-
let layout = bx.cx().layout_of(ty);
457-
bx.load_operand(PlaceRef::new_sized(
458-
bx.cx().const_undef(bx.cx().type_ptr_to(bx.cx().backend_type(layout))),
459-
layout,
460-
))
441+
// This cannot fail because we checked all required_consts in advance.
442+
self.eval_mir_constant_to_operand(bx, constant).unwrap_or_else(|_err| {
443+
span_bug!(constant.span, "erroneous constant not captured by required_consts")
461444
})
462445
}
463446
}

compiler/rustc_mir/src/interpret/operand.rs

+4
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
511511
Constant(ref constant) => {
512512
let val =
513513
self.subst_from_current_frame_and_normalize_erasing_regions(constant.literal);
514+
// This can still fail:
515+
// * During ConstProp, with `TooGeneric` or since the `requried_consts` were not all
516+
// checked yet.
517+
// * During CTFE, since promoteds in `const`/`static` initializer bodies can fail.
514518
self.const_to_op(val, layout)?
515519
}
516520
};

0 commit comments

Comments
 (0)