mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
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
This commit is contained in:
commit
89b6885529
@ -152,13 +152,20 @@ where
|
|||||||
let span = span.substitute_dummy(our_span);
|
let span = span.substitute_dummy(our_span);
|
||||||
let err = mk(span, frames);
|
let err = mk(span, frames);
|
||||||
let mut err = tcx.dcx().create_err(err);
|
let mut err = tcx.dcx().create_err(err);
|
||||||
|
let can_be_spurious = matches!(error, InterpErrorKind::ResourceExhaustion(_));
|
||||||
|
|
||||||
let msg = error.diagnostic_message();
|
let msg = error.diagnostic_message();
|
||||||
error.add_args(&mut err);
|
error.add_args(&mut err);
|
||||||
|
|
||||||
// Use *our* span to label the interp error
|
// Use *our* span to label the interp error
|
||||||
err.span_label(our_span, msg);
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -588,6 +588,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||||||
// const-eval will return "tainted" errors if e.g. the layout cannot
|
// const-eval will return "tainted" errors if e.g. the layout cannot
|
||||||
// be computed as the type references non-existing names.
|
// be computed as the type references non-existing names.
|
||||||
// See <https://github.com/rust-lang/rust/issues/124348>.
|
// 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 {
|
} else {
|
||||||
// Looks like the const is not captured by `required_consts`, that's bad.
|
// 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");
|
span_bug!(span, "interpret const eval failure of {val:?} which is not in required_consts");
|
||||||
|
@ -59,22 +59,33 @@ impl ErrorHandled {
|
|||||||
pub struct ReportedErrorInfo {
|
pub struct ReportedErrorInfo {
|
||||||
error: ErrorGuaranteed,
|
error: ErrorGuaranteed,
|
||||||
is_tainted_by_errors: bool,
|
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 {
|
impl ReportedErrorInfo {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn tainted_by_errors(error: ErrorGuaranteed) -> ReportedErrorInfo {
|
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 {
|
pub fn is_tainted_by_errors(&self) -> bool {
|
||||||
self.is_tainted_by_errors
|
self.is_tainted_by_errors
|
||||||
}
|
}
|
||||||
|
pub fn can_be_spurious(&self) -> bool {
|
||||||
|
self.can_be_spurious
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ErrorGuaranteed> for ReportedErrorInfo {
|
impl From<ErrorGuaranteed> for ReportedErrorInfo {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(error: ErrorGuaranteed) -> ReportedErrorInfo {
|
fn from(error: ErrorGuaranteed) -> ReportedErrorInfo {
|
||||||
ReportedErrorInfo { is_tainted_by_errors: false, error }
|
ReportedErrorInfo { is_tainted_by_errors: false, can_be_spurious: false, error }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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]);
|
|
@ -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() {}
|
@ -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`.
|
Loading…
Reference in New Issue
Block a user