Skip to content

Don't attempt to compute layout of type referencing error #113773

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

Merged
merged 3 commits into from
Jul 29, 2023
Merged
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
5 changes: 4 additions & 1 deletion compiler/rustc_const_eval/src/const_eval/error.rs
Original file line number Diff line number Diff line change
@@ -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
11 changes: 3 additions & 8 deletions compiler/rustc_hir_typeck/src/intrinsicck.rs
Original file line number Diff line number Diff line change
@@ -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();
}
}
3 changes: 3 additions & 0 deletions compiler/rustc_middle/messages.ftl
Original file line number Diff line number Diff line change
@@ -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}
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/error.rs
Original file line number Diff line number Diff line change
@@ -132,6 +132,9 @@ pub enum LayoutError<'tcx> {

#[diag(middle_cycle)]
Cycle,

#[diag(middle_layout_references_error)]
ReferencesError,
}

#[derive(Diagnostic)]
9 changes: 7 additions & 2 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
@@ -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),
};

2 changes: 1 addition & 1 deletion compiler/rustc_transmute/src/layout/tree.rs
Original file line number Diff line number Diff line change
@@ -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),
}
}
15 changes: 13 additions & 2 deletions compiler/rustc_ty_utils/src/layout.rs
Original file line number Diff line number Diff line change
@@ -96,6 +96,13 @@ fn layout_of_uncached<'tcx>(
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
ty: Ty<'tcx>,
) -> Result<Layout<'tcx>, &'tcx LayoutError<'tcx>> {
// Types that reference `ty::Error` pessimistically don't have a meaningful layout.
// The only side-effect of this is possibly worse diagnostics in case the layout
// was actually computable (like if the `ty::Error` showed up only in a `PhantomData`).
if let Err(guar) = ty.error_reported() {
return Err(error(cx, LayoutError::ReferencesError(guar)));
}

let tcx = cx.tcx;
let param_env = cx.param_env;
let dl = cx.data_layout();
@@ -564,11 +571,15 @@ fn layout_of_uncached<'tcx>(
return Err(error(cx, LayoutError::Unknown(ty)));
}

ty::Bound(..) | ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) | ty::Infer(_) => {
ty::Bound(..)
| ty::GeneratorWitness(..)
| ty::GeneratorWitnessMIR(..)
| ty::Infer(_)
| ty::Error(_) => {
bug!("Layout::compute: unexpected type `{}`", ty)
}

ty::Placeholder(..) | ty::Param(_) | ty::Error(_) => {
ty::Placeholder(..) | ty::Param(_) => {
return Err(error(cx, LayoutError::Unknown(ty)));
}
})
5 changes: 5 additions & 0 deletions src/librustdoc/html/templates/type_layout.html
Original file line number Diff line number Diff line change
@@ -44,6 +44,11 @@ <h2 id="layout" class="small-section-header"> {# #}
<strong>Note:</strong> Encountered an error during type layout; {#+ #}
the type was too big. {# #}
</p> {# #}
{% when Err(LayoutError::ReferencesError(_)) %}
<p> {# #}
<strong>Note:</strong> Encountered an error during type layout; {#+ #}
the type references errors. {# #}
</p> {# #}
{% when Err(LayoutError::NormalizationFailure(_, _)) %}
<p> {# #}
<strong>Note:</strong> Encountered an error during type layout; {#+ #}
8 changes: 8 additions & 0 deletions tests/ui/layout/malformed-unsized-type-in-union.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// issue: 113760

union W { s: dyn Iterator<Item = Missing> }
//~^ ERROR cannot find type `Missing` in this scope

static ONCE: W = todo!();

fn main() {}
9 changes: 9 additions & 0 deletions tests/ui/layout/malformed-unsized-type-in-union.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0412]: cannot find type `Missing` in this scope
--> $DIR/malformed-unsized-type-in-union.rs:3:34
|
LL | union W { s: dyn Iterator<Item = Missing> }
| ^^^^^^^ not found in this scope

error: aborting due to previous error

For more information about this error, try `rustc --explain E0412`.