diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs
index ffeff8d079aa2..d39a7e8a19250 100644
--- a/compiler/rustc_const_eval/src/const_eval/error.rs
+++ b/compiler/rustc_const_eval/src/const_eval/error.rs
@@ -138,7 +138,10 @@ where
err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => {
ErrorHandled::TooGeneric
}
- err_inval!(AlreadyReported(error_reported)) => ErrorHandled::Reported(error_reported),
+ err_inval!(AlreadyReported(guar)) => ErrorHandled::Reported(guar),
+ err_inval!(Layout(LayoutError::ReferencesError(guar))) => {
+ ErrorHandled::Reported(guar.into())
+ }
err_inval!(Layout(layout_error @ LayoutError::SizeOverflow(_))) => {
// We must *always* hard error on these, even if the caller wants just a lint.
// The `message` makes little sense here, this is a more serious error than the
diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs
index 2cd18c4c3fcb4..4e65182f15806 100644
--- a/compiler/rustc_hir_typeck/src/intrinsicck.rs
+++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs
@@ -122,14 +122,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else {
err.note(format!("source type: `{}` ({})", from, skeleton_string(from, sk_from)))
.note(format!("target type: `{}` ({})", to, skeleton_string(to, sk_to)));
- let mut should_delay_as_bug = false;
- if let Err(LayoutError::Unknown(bad_from)) = sk_from && bad_from.references_error() {
- should_delay_as_bug = true;
- }
- if let Err(LayoutError::Unknown(bad_to)) = sk_to && bad_to.references_error() {
- should_delay_as_bug = true;
- }
- if should_delay_as_bug {
+ if let Err(LayoutError::ReferencesError(_)) = sk_from {
+ err.delay_as_bug();
+ } else if let Err(LayoutError::ReferencesError(_)) = sk_to {
err.delay_as_bug();
}
}
diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl
index bb7147ac80fbe..108a10b506beb 100644
--- a/compiler/rustc_middle/messages.ftl
+++ b/compiler/rustc_middle/messages.ftl
@@ -52,6 +52,9 @@ middle_drop_check_overflow =
overflow while adding drop-check rules for {$ty}
.note = overflowed on {$overflow_ty}
+middle_layout_references_error =
+ the type has an unknown layout
+
middle_limit_invalid =
`limit` must be a non-negative integer
.label = {$error_str}
diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs
index 57b2de84b47f7..b346cd4539144 100644
--- a/compiler/rustc_middle/src/error.rs
+++ b/compiler/rustc_middle/src/error.rs
@@ -132,6 +132,9 @@ pub enum LayoutError<'tcx> {
#[diag(middle_cycle)]
Cycle,
+
+ #[diag(middle_layout_references_error)]
+ ReferencesError,
}
#[derive(Diagnostic)]
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 81e7dc3728ab0..93dabb973e384 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -10,7 +10,7 @@ use rustc_hir::def_id::DefId;
use rustc_index::IndexVec;
use rustc_session::config::OptLevel;
use rustc_span::symbol::{sym, Symbol};
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
use rustc_target::abi::call::FnAbi;
use rustc_target::abi::*;
use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec, PanicStrategy, Target};
@@ -212,6 +212,7 @@ pub enum LayoutError<'tcx> {
Unknown(Ty<'tcx>),
SizeOverflow(Ty<'tcx>),
NormalizationFailure(Ty<'tcx>, NormalizationError<'tcx>),
+ ReferencesError(ErrorGuaranteed),
Cycle,
}
@@ -224,6 +225,7 @@ impl<'tcx> LayoutError<'tcx> {
SizeOverflow(_) => middle_values_too_big,
NormalizationFailure(_, _) => middle_cannot_be_normalized,
Cycle => middle_cycle,
+ ReferencesError(_) => middle_layout_references_error,
}
}
@@ -237,6 +239,7 @@ impl<'tcx> LayoutError<'tcx> {
E::NormalizationFailure { ty, failure_ty: e.get_type_for_failure() }
}
Cycle => E::Cycle,
+ ReferencesError(_) => E::ReferencesError,
}
}
}
@@ -257,6 +260,7 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
e.get_type_for_failure()
),
LayoutError::Cycle => write!(f, "a cycle occurred during layout computation"),
+ LayoutError::ReferencesError(_) => write!(f, "the type has an unknown layout"),
}
}
}
@@ -323,7 +327,8 @@ impl<'tcx> SizeSkeleton<'tcx> {
Err(
e @ LayoutError::Cycle
| e @ LayoutError::SizeOverflow(_)
- | e @ LayoutError::NormalizationFailure(..),
+ | e @ LayoutError::NormalizationFailure(..)
+ | e @ LayoutError::ReferencesError(_),
) => return Err(e),
};
diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs
index 8bd268182560a..e8ddb0a43962f 100644
--- a/compiler/rustc_transmute/src/layout/tree.rs
+++ b/compiler/rustc_transmute/src/layout/tree.rs
@@ -195,7 +195,7 @@ pub(crate) mod rustc {
impl<'tcx> From<&LayoutError<'tcx>> for Err {
fn from(err: &LayoutError<'tcx>) -> Self {
match err {
- LayoutError::Unknown(..) => Self::UnknownLayout,
+ LayoutError::Unknown(..) | LayoutError::ReferencesError(..) => Self::UnknownLayout,
err => unimplemented!("{:?}", err),
}
}
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index b840ff184e0b7..3500c2cc37003 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -96,6 +96,13 @@ fn layout_of_uncached<'tcx>(
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
ty: Ty<'tcx>,
) -> Result {# #}
Note: Encountered an error during type layout; {#+ #}
the type was too big. {# #}
{# #} + Note: Encountered an error during type layout; {#+ #} + the type references errors. {# #} +
{# #} {% when Err(LayoutError::NormalizationFailure(_, _)) %} {# #}
Note: Encountered an error during type layout; {#+ #}
diff --git a/tests/ui/layout/malformed-unsized-type-in-union.rs b/tests/ui/layout/malformed-unsized-type-in-union.rs
new file mode 100644
index 0000000000000..5d8ec576cf01b
--- /dev/null
+++ b/tests/ui/layout/malformed-unsized-type-in-union.rs
@@ -0,0 +1,8 @@
+// issue: 113760
+
+union W { s: dyn Iterator