From e7e17f9d1b008a1f06ad8b4ef06c443b4b879bc4 Mon Sep 17 00:00:00 2001
From: Dan Robertson <dan@dlrobertson.com>
Date: Mon, 17 Dec 2018 03:17:59 +0000
Subject: [PATCH] static eval: Do not ICE on layout size overflow

Layout size overflow and typeck eval errors are reported. Trigger a bug
only when the eval error is strictly labeled as TooGeneric.
---
 src/librustc_mir/const_eval.rs        | 12 ++++++++----
 src/test/ui/issues/issue-56762.rs     | 18 ++++++++++++++++++
 src/test/ui/issues/issue-56762.stderr |  4 ++++
 3 files changed, 30 insertions(+), 4 deletions(-)
 create mode 100644 src/test/ui/issues/issue-56762.rs
 create mode 100644 src/test/ui/issues/issue-56762.stderr

diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 248c5d2db4917..d5bc83aba7b99 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -692,12 +692,16 @@ pub fn const_eval_raw_provider<'a, 'tcx>(
         let err = error_to_const_error(&ecx, error);
         // errors in statics are always emitted as fatal errors
         if tcx.is_static(def_id).is_some() {
-            let err = err.report_as_error(ecx.tcx, "could not evaluate static initializer");
-            // check that a static never produces `TooGeneric`
+            let reported_err = err.report_as_error(ecx.tcx,
+                                                   "could not evaluate static initializer");
+            // Ensure that if the above error was either `TooGeneric` or `Reported`
+            // an error must be reported.
             if tcx.sess.err_count() == 0 {
-                span_bug!(ecx.tcx.span, "static eval failure didn't emit an error: {:#?}", err);
+                tcx.sess.delay_span_bug(err.span,
+                                        &format!("static eval failure did not emit an error: {:#?}",
+                                                 reported_err));
             }
-            err
+            reported_err
         } else if def_id.is_local() {
             // constant defined in this crate, we can figure out a lint level!
             match tcx.describe_def(def_id) {
diff --git a/src/test/ui/issues/issue-56762.rs b/src/test/ui/issues/issue-56762.rs
new file mode 100644
index 0000000000000..97b66b2c7c923
--- /dev/null
+++ b/src/test/ui/issues/issue-56762.rs
@@ -0,0 +1,18 @@
+// only-x86_64
+const HUGE_SIZE: usize = !0usize / 8;
+
+
+pub struct TooBigArray {
+    arr: [u8; HUGE_SIZE],
+}
+
+impl TooBigArray {
+    pub const fn new() -> Self {
+        TooBigArray { arr: [0x00; HUGE_SIZE], }
+    }
+}
+
+static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new();
+static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE];
+
+fn main() { }
diff --git a/src/test/ui/issues/issue-56762.stderr b/src/test/ui/issues/issue-56762.stderr
new file mode 100644
index 0000000000000..83d5dc62e6161
--- /dev/null
+++ b/src/test/ui/issues/issue-56762.stderr
@@ -0,0 +1,4 @@
+error: the type `[u8; 2305843009213693951]` is too big for the current architecture
+
+error: aborting due to previous error
+