about summary refs log tree commit diff
path: root/compiler/rustc_codegen_ssa/src/mir
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2021-01-24 12:12:08 +0100
committerRalf Jung <post@ralfj.de>2021-01-30 12:29:57 +0100
commit944237f6cd2b7e732b6875bf0956bf323cc3316b (patch)
treebc1c64c18793c4bdce42bd022ca6026cb9e02b2a /compiler/rustc_codegen_ssa/src/mir
parent4d0dd02ee07bddad9136f95c9f7846ebf3eb3fc5 (diff)
downloadrust-944237f6cd2b7e732b6875bf0956bf323cc3316b.tar.gz
rust-944237f6cd2b7e732b6875bf0956bf323cc3316b.zip
codegen: assume constants cannot fail to evaluate
also don't submit code to LLVM when the session has errors
Diffstat (limited to 'compiler/rustc_codegen_ssa/src/mir')
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs25
2 files changed, 12 insertions, 21 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 285140060be..d31ececf130 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -188,8 +188,11 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 
     fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut bx);
 
+    // Evaluate all required consts; codegen later assumes that CTFE will never fail.
+    let mut all_consts_ok = true;
     for const_ in &mir.required_consts {
         if let Err(err) = fx.eval_mir_constant(const_) {
+            all_consts_ok = false;
             match err {
                 // errored or at least linted
                 ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {}
@@ -199,6 +202,11 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
             }
         }
     }
+    if !all_consts_ok {
+        // We leave the IR in some half-built state here, and rely on this code not even being
+        // submitted to LLVM once an error was raised.
+        return;
+    }
 
     let memory_locals = analyze::non_ssa_locals(&fx);
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index 08a4ae3962b..25e84c38ed3 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -6,9 +6,8 @@ use crate::glue;
 use crate::traits::*;
 use crate::MemFlags;
 
-use rustc_errors::ErrorReported;
 use rustc_middle::mir;
-use rustc_middle::mir::interpret::{ConstValue, ErrorHandled, Pointer, Scalar};
+use rustc_middle::mir::interpret::{ConstValue, Pointer, Scalar};
 use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::ty::Ty;
 use rustc_target::abi::{Abi, Align, LayoutOf, Size};
@@ -439,25 +438,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             }
 
             mir::Operand::Constant(ref constant) => {
-                self.eval_mir_constant_to_operand(bx, constant).unwrap_or_else(|err| {
-                    match err {
-                        // errored or at least linted
-                        ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {}
-                        ErrorHandled::TooGeneric => {
-                            bug!("codegen encountered polymorphic constant")
-                        }
-                    }
-                    // Allow RalfJ to sleep soundly knowing that even refactorings that remove
-                    // the above error (or silence it under some conditions) will not cause UB.
-                    bx.abort();
-                    // We still have to return an operand but it doesn't matter,
-                    // this code is unreachable.
-                    let ty = self.monomorphize(constant.literal.ty);
-                    let layout = bx.cx().layout_of(ty);
-                    bx.load_operand(PlaceRef::new_sized(
-                        bx.cx().const_undef(bx.cx().type_ptr_to(bx.cx().backend_type(layout))),
-                        layout,
-                    ))
+                // This cannot fail because we checked all required_consts in advance.
+                self.eval_mir_constant_to_operand(bx, constant).unwrap_or_else(|_err| {
+                    span_bug!(constant.span, "erroneous constant not captured by required_consts")
                 })
             }
         }