diff options
| author | Ralf Jung <post@ralfj.de> | 2024-11-18 08:42:42 +0100 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2024-11-18 20:48:03 +0100 |
| commit | c6974344a5707c054ed808ea9c724dd93ec3c680 (patch) | |
| tree | 19a084178f1325d2e252df447af7bd3e3b7a163d /compiler | |
| parent | 3fb7e441aecc3c054d71eb4d752d06e7776e8888 (diff) | |
| download | rust-c6974344a5707c054ed808ea9c724dd93ec3c680.tar.gz rust-c6974344a5707c054ed808ea9c724dd93ec3c680.zip | |
interpret: do not ICE when a promoted fails with OOM
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_const_eval/src/const_eval/error.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/eval_context.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/error.rs | 15 |
3 files changed, 24 insertions, 3 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 ff6d5b28b3b..eb574bd5f77 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -596,6 +596,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 } } } |
