Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix two ICEs by introducing a new layout error variant #135158

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/const_eval/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ where
// 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) => {
err_inval!(Layout(LayoutError::TooGeneric(_))) | err_inval!(TooGeneric) => {
ErrorHandled::TooGeneric(span)
}
err_inval!(Layout(LayoutError::ReferencesError(guar))) => {
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ fn should_emit_generic_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError
use LayoutError::*;

match layout_err {
Unknown(ty) => {
TooGeneric(ty) => {
match abi {
ExternAbi::CCmseNonSecureCall => {
// prevent double reporting of this error
Expand All @@ -211,7 +211,11 @@ fn should_emit_generic_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError
_ => bug!("invalid ABI: {abi}"),
}
}
SizeOverflow(..) | NormalizationFailure(..) | ReferencesError(..) | Cycle(..) => {
Unknown(..)
| SizeOverflow(..)
| NormalizationFailure(..)
| ReferencesError(..)
| Cycle(..) => {
false // not our job to report these
}
}
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_middle/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,15 @@ middle_strict_coherence_needs_negative_coherence =
to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled
.label = due to this attribute

middle_too_generic =
cannot determine the layout of the type `{$ty}`; too generic

middle_type_length_limit = reached the type-length limit while instantiating `{$shrunk}`

middle_unknown_layout =
the type `{$ty}` has an unknown layout

middle_values_too_big =
values of the type `{$ty}` are too big for the target architecture

middle_written_to_path = the full type name has been written to '{$path}'
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ pub enum LayoutError<'tcx> {
#[diag(middle_unknown_layout)]
Unknown { ty: Ty<'tcx> },

#[diag(middle_too_generic)]
TooGeneric { ty: Ty<'tcx> },

#[diag(middle_values_too_big)]
Overflow { ty: Ty<'tcx> },

Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ impl fmt::Display for ValidityRequirement {
pub enum LayoutError<'tcx> {
Unknown(Ty<'tcx>),
SizeOverflow(Ty<'tcx>),
TooGeneric(Ty<'tcx>),
NormalizationFailure(Ty<'tcx>, NormalizationError<'tcx>),
ReferencesError(ErrorGuaranteed),
Cycle(ErrorGuaranteed),
Expand All @@ -244,6 +245,7 @@ impl<'tcx> LayoutError<'tcx> {
match self {
Unknown(_) => middle_unknown_layout,
SizeOverflow(_) => middle_values_too_big,
TooGeneric(_) => middle_too_generic,
NormalizationFailure(_, _) => middle_cannot_be_normalized,
Cycle(_) => middle_cycle,
ReferencesError(_) => middle_layout_references_error,
Expand All @@ -257,6 +259,7 @@ impl<'tcx> LayoutError<'tcx> {
match self {
Unknown(ty) => E::Unknown { ty },
SizeOverflow(ty) => E::Overflow { ty },
TooGeneric(ty) => E::TooGeneric { ty },
NormalizationFailure(ty, e) => {
E::NormalizationFailure { ty, failure_ty: e.get_type_for_failure() }
}
Expand All @@ -272,6 +275,9 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
LayoutError::Unknown(ty) => write!(f, "the type `{ty}` has an unknown layout"),
LayoutError::TooGeneric(ty) => {
write!(f, "cannot determine the layout for the type `{ty}`; too generic")
}
LayoutError::SizeOverflow(ty) => {
write!(f, "values of the type `{ty}` are too big for the target architecture")
}
Expand Down Expand Up @@ -350,10 +356,11 @@ impl<'tcx> SizeSkeleton<'tcx> {
return Err(tcx.arena.alloc(LayoutError::Unknown(ty)));
}
}
Err(err @ LayoutError::Unknown(_)) => err,
Err(err @ LayoutError::TooGeneric(_)) => err,
// We can't extract SizeSkeleton info from other layout errors
Err(
e @ LayoutError::Cycle(_)
| e @ LayoutError::Unknown(_)
| e @ LayoutError::SizeOverflow(_)
| e @ LayoutError::NormalizationFailure(..)
| e @ LayoutError::ReferencesError(_),
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_transmute/src/layout/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ pub(crate) mod rustc {
match err {
LayoutError::Unknown(..)
| LayoutError::ReferencesError(..)
| LayoutError::TooGeneric(..)
| LayoutError::NormalizationFailure(..) => Self::UnknownLayout,
LayoutError::SizeOverflow(..) => Self::SizeOverflow,
LayoutError::Cycle(err) => Self::TypeError(*err),
Expand Down
13 changes: 10 additions & 3 deletions compiler/rustc_ty_utils/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ fn map_error<'tcx>(
// This is sometimes not a compile error if there are trivially false where clauses.
// See `tests/ui/layout/trivial-bounds-sized.rs` for an example.
assert!(field.layout.is_unsized(), "invalid layout error {err:#?}");
if !field.ty.is_sized(cx.tcx(), cx.typing_env) {
FedericoBruzzone marked this conversation as resolved.
Show resolved Hide resolved
if cx.typing_env.param_env.caller_bounds().is_empty() {
cx.tcx().dcx().delayed_bug(format!(
"encountered unexpected unsized field in layout of {ty:?}: {field:#?}"
));
Expand Down Expand Up @@ -323,7 +323,7 @@ fn layout_of_uncached<'tcx>(

let count = count
.try_to_target_usize(tcx)
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
.ok_or_else(|| error(cx, LayoutError::TooGeneric(ty)))?;
let element = cx.layout_of(element)?;
let size = element
.size
Expand Down Expand Up @@ -673,6 +673,9 @@ fn layout_of_uncached<'tcx>(

// Types with no meaningful known layout.
ty::Alias(..) => {
if ty.has_param() {
return Err(error(cx, LayoutError::TooGeneric(ty)));
}
// NOTE(eddyb) `layout_of` query should've normalized these away,
// if that was possible, so there's no reason to try again here.
return Err(error(cx, LayoutError::Unknown(ty)));
Expand All @@ -682,7 +685,11 @@ fn layout_of_uncached<'tcx>(
bug!("Layout::compute: unexpected type `{}`", ty)
}

ty::Placeholder(..) | ty::Param(_) => {
ty::Param(_) => {
return Err(error(cx, LayoutError::TooGeneric(ty)));
}

ty::Placeholder(..) => {
return Err(error(cx, LayoutError::Unknown(ty)));
}
})
Expand Down
8 changes: 8 additions & 0 deletions src/librustdoc/html/templates/type_layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ <h2 id="layout" class="section-header"> {# #}
<strong>Note:</strong> Encountered an error during type layout; {#+ #}
the type was too big. {# #}
</p>
{# This kind of error probably can't happen with valid code, but we don't
want to panic and prevent the docs from building, so we just let the
user know that we couldn't compute the layout. #}
{% when Err(LayoutError::TooGeneric(_)) %}
<p> {# #}
<strong>Note:</strong> Encountered an error during type layout; {#+ #}
the type was too generic. {# #}
</p>
{% when Err(LayoutError::ReferencesError(_)) %}
<p> {# #}
<strong>Note:</strong> Encountered an error during type layout; {#+ #}
Expand Down
11 changes: 0 additions & 11 deletions tests/crashes/135020.rs

This file was deleted.

7 changes: 7 additions & 0 deletions tests/ui/layout/unexpected-unsized-field-issue-135020.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//@ check-pass

fn problem_thingy(items: &mut impl Iterator<Item = str>) {
items.peekable();
}

fn main() {}
Loading