about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-11-19 13:24:09 +0000
committerbors <bors@rust-lang.org>2024-11-19 13:24:09 +0000
commit89b688552994bd8404b8fdab2cf96f00632af0ff (patch)
treee66f3e72be73c84a7655663acdd1ba4a4d9a4a13
parent7d40450b2df92bdc9dec414b30cf5f7a5979a92e (diff)
parentc6974344a5707c054ed808ea9c724dd93ec3c680 (diff)
downloadrust-89b688552994bd8404b8fdab2cf96f00632af0ff.tar.gz
rust-89b688552994bd8404b8fdab2cf96f00632af0ff.zip
Auto merge of #133164 - RalfJung:promoted-oom, r=jieyouxu
interpret: do not ICE when a promoted fails with OOM

Fixes https://github.com/rust-lang/rust/issues/130687

try-job: aarch64-apple
try-job: dist-x86_64-linux
-rw-r--r--compiler/rustc_const_eval/src/const_eval/error.rs9
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs3
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs15
-rw-r--r--tests/crashes/130687.rs4
-rw-r--r--tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs12
-rw-r--r--tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr15
6 files changed, 51 insertions, 7 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs
index 6686413bf02..1271d9d2d0d 100644
--- a/compiler/rustc_const_eval/src/const_eval/error.rs
+++ b/compiler/rustc_const_eval/src/const_eval/error.rs
@@ -152,13 +152,20 @@ where
             let span = span.substitute_dummy(our_span);
             let err = mk(span, frames);
             let mut err = tcx.dcx().create_err(err);
+            let can_be_spurious = matches!(error, InterpErrorKind::ResourceExhaustion(_));
 
             let msg = error.diagnostic_message();
             error.add_args(&mut err);
 
             // Use *our* span to label the interp error
             err.span_label(our_span, msg);
-            ErrorHandled::Reported(err.emit().into(), span)
+            let g = err.emit();
+            let reported = if can_be_spurious {
+                ReportedErrorInfo::spurious(g)
+            } else {
+                ReportedErrorInfo::from(g)
+            };
+            ErrorHandled::Reported(reported, span)
         }
     }
 }
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 70a696e3e3e..4f413c84615 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -588,6 +588,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                                 // const-eval will return "tainted" errors if e.g. the layout cannot
                                 // be computed as the type references non-existing names.
                                 // See <https://github.com/rust-lang/rust/issues/124348>.
+                            } else if reported.can_be_spurious() {
+                                // These errors can just sometimes happen, even when the expression
+                                // is nominally "infallible", e.g. when running out of memory.
                             } else {
                                 // Looks like the const is not captured by `required_consts`, that's bad.
                                 span_bug!(span, "interpret const eval failure of {val:?} which is not in required_consts");
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index 8ec7e1851a5..08afa33c6b4 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -59,22 +59,33 @@ impl ErrorHandled {
 pub struct ReportedErrorInfo {
     error: ErrorGuaranteed,
     is_tainted_by_errors: bool,
+    /// Whether this is the kind of error that can sometimes occur, and sometimes not.
+    /// Used for resource exhaustion errors.
+    can_be_spurious: bool,
 }
 
 impl ReportedErrorInfo {
     #[inline]
     pub fn tainted_by_errors(error: ErrorGuaranteed) -> ReportedErrorInfo {
-        ReportedErrorInfo { is_tainted_by_errors: true, error }
+        ReportedErrorInfo { is_tainted_by_errors: true, can_be_spurious: false, error }
     }
+    #[inline]
+    pub fn spurious(error: ErrorGuaranteed) -> ReportedErrorInfo {
+        ReportedErrorInfo { can_be_spurious: true, is_tainted_by_errors: false, error }
+    }
+
     pub fn is_tainted_by_errors(&self) -> bool {
         self.is_tainted_by_errors
     }
+    pub fn can_be_spurious(&self) -> bool {
+        self.can_be_spurious
+    }
 }
 
 impl From<ErrorGuaranteed> for ReportedErrorInfo {
     #[inline]
     fn from(error: ErrorGuaranteed) -> ReportedErrorInfo {
-        ReportedErrorInfo { is_tainted_by_errors: false, error }
+        ReportedErrorInfo { is_tainted_by_errors: false, can_be_spurious: false, error }
     }
 }
 
diff --git a/tests/crashes/130687.rs b/tests/crashes/130687.rs
deleted file mode 100644
index 361be0905df..00000000000
--- a/tests/crashes/130687.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-//@ known-bug: #130687
-//@ only-x86_64
-pub struct Data([u8; usize::MAX >> 16]);
-const _: &'static Data = &Data([0; usize::MAX >> 16]);
diff --git a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs
new file mode 100644
index 00000000000..b923a768cbf
--- /dev/null
+++ b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs
@@ -0,0 +1,12 @@
+//! Ensure we do not ICE when a promoted fails to evaluate due to running out of memory.
+//! Also see <https://github.com/rust-lang/rust/issues/130687>.
+
+// Needs the max type size to be much bigger than the RAM people typically have.
+//@ only-64bit
+
+pub struct Data([u8; (1 << 47) - 1]);
+const _: &'static Data = &Data([0; (1 << 47) - 1]);
+//~^ERROR: evaluation of constant value failed
+//~| tried to allocate more memory than available to compiler
+
+fn main() {}
diff --git a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr
new file mode 100644
index 00000000000..50e920f05f9
--- /dev/null
+++ b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr
@@ -0,0 +1,15 @@
+error[E0080]: evaluation of constant value failed
+  --> $DIR/promoted_running_out_of_memory_issue-130687.rs:8:32
+   |
+LL | const _: &'static Data = &Data([0; (1 << 47) - 1]);
+   |                                ^^^^^^^^^^^^^^^^^^ tried to allocate more memory than available to compiler
+
+note: erroneous constant encountered
+  --> $DIR/promoted_running_out_of_memory_issue-130687.rs:8:26
+   |
+LL | const _: &'static Data = &Data([0; (1 << 47) - 1]);
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0080`.