diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2024-12-02 23:08:55 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-02 23:08:55 +0100 |
| commit | b1a643e599b68e568fe90790dfbe4acd3baa573d (patch) | |
| tree | 7f50bca4902aac3738367fdc8b8e5d73b5d30dfc /compiler | |
| parent | 65b0dad824afa54eb23aa9e3c333daaf9037249d (diff) | |
| parent | a17294dc0fe106f0a8f12f8bc61ab17eacf251ef (diff) | |
| download | rust-b1a643e599b68e568fe90790dfbe4acd3baa573d.tar.gz rust-b1a643e599b68e568fe90790dfbe4acd3baa573d.zip | |
Rollup merge of #133704 - RalfJung:promoted-size-overflow-ice, r=compiler-errors
fix ICE when promoted has layout size overflow Turns out there is no reason to distinguish `tainted_by_errors` and `can_be_spurious` here, we can just track whether we allow this even in "infallible" constants. Fixes https://github.com/rust-lang/rust/issues/125476
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_const_eval/src/const_eval/error.rs | 17 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/eval_context.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/error.rs | 26 |
3 files changed, 25 insertions, 29 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 1271d9d2d0d..3cb77d1dcb5 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -139,12 +139,14 @@ where match error { // Don't emit a new diagnostic for these errors, they are already reported elsewhere or // should remain silent. + err_inval!(AlreadyReported(info)) => ErrorHandled::Reported(info, span), err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => { ErrorHandled::TooGeneric(span) } - err_inval!(AlreadyReported(guar)) => ErrorHandled::Reported(guar, span), err_inval!(Layout(LayoutError::ReferencesError(guar))) => { - ErrorHandled::Reported(ReportedErrorInfo::tainted_by_errors(guar), span) + // This can occur in infallible promoteds e.g. when a non-existent type or field is + // encountered. + ErrorHandled::Reported(ReportedErrorInfo::allowed_in_infallible(guar), span) } // Report remaining errors. _ => { @@ -152,7 +154,12 @@ 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(_)); + // We allow invalid programs in infallible promoteds since invalid layouts can occur + // anyway (e.g. due to size overflow). And we allow OOM as that can happen any time. + let allowed_in_infallible = matches!( + error, + InterpErrorKind::ResourceExhaustion(_) | InterpErrorKind::InvalidProgram(_) + ); let msg = error.diagnostic_message(); error.add_args(&mut err); @@ -160,8 +167,8 @@ where // Use *our* span to label the interp error err.span_label(our_span, msg); let g = err.emit(); - let reported = if can_be_spurious { - ReportedErrorInfo::spurious(g) + let reported = if allowed_in_infallible { + ReportedErrorInfo::allowed_in_infallible(g) } else { ReportedErrorInfo::from(g) }; diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index fe93a48c2f2..241be5e175c 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -268,7 +268,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }; // do not continue if typeck errors occurred (can only occur in local crate) if let Some(err) = body.tainted_by_errors { - throw_inval!(AlreadyReported(ReportedErrorInfo::tainted_by_errors(err))); + throw_inval!(AlreadyReported(ReportedErrorInfo::from(err))); } interp_ok(body) } @@ -585,13 +585,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { match err { ErrorHandled::TooGeneric(..) => {}, ErrorHandled::Reported(reported, span) => { - if reported.is_tainted_by_errors() { - // 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() { + if reported.is_allowed_in_infallible() { // These errors can just sometimes happen, even when the expression - // is nominally "infallible", e.g. when running out of memory. + // is nominally "infallible", e.g. when running out of memory + // or when some layout could not be computed. } 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 08afa33c6b4..ad5d678178d 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -46,7 +46,7 @@ impl ErrorHandled { pub fn emit_note(&self, tcx: TyCtxt<'_>) { match self { &ErrorHandled::Reported(err, span) => { - if !err.is_tainted_by_errors && !span.is_dummy() { + if !err.allowed_in_infallible && !span.is_dummy() { tcx.dcx().emit_note(error::ErroneousConstant { span }); } } @@ -58,34 +58,26 @@ impl ErrorHandled { #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] 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, + /// Whether this error is allowed to show up even in otherwise "infallible" promoteds. + /// This is for things like overflows during size computation or resource exhaustion. + allowed_in_infallible: bool, } impl ReportedErrorInfo { #[inline] - pub fn tainted_by_errors(error: ErrorGuaranteed) -> ReportedErrorInfo { - 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 allowed_in_infallible(error: ErrorGuaranteed) -> ReportedErrorInfo { + ReportedErrorInfo { allowed_in_infallible: true, 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 + pub fn is_allowed_in_infallible(&self) -> bool { + self.allowed_in_infallible } } impl From<ErrorGuaranteed> for ReportedErrorInfo { #[inline] fn from(error: ErrorGuaranteed) -> ReportedErrorInfo { - ReportedErrorInfo { is_tainted_by_errors: false, can_be_spurious: false, error } + ReportedErrorInfo { allowed_in_infallible: false, error } } } |
