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

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

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

#[diag(middle_cycle)]
Cycle,

#[diag(middle_layout_references_error)]
ReferencesError,
}

#[derive(Diagnostic)]
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -212,6 +212,7 @@ pub enum LayoutError<'tcx> {
Unknown(Ty<'tcx>),
SizeOverflow(Ty<'tcx>),
NormalizationFailure(Ty<'tcx>, NormalizationError<'tcx>),
ReferencesError(ErrorGuaranteed),
Cycle,
}

Expand All @@ -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,
}
}

Expand All @@ -237,6 +239,7 @@ impl<'tcx> LayoutError<'tcx> {
E::NormalizationFailure { ty, failure_ty: e.get_type_for_failure() }
}
Cycle => E::Cycle,
ReferencesError(_) => E::ReferencesError,
}
}
}
Expand All @@ -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"),
}
}
}
Expand Down Expand Up @@ -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),
};

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_transmute/src/layout/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
}
Expand Down
15 changes: 13 additions & 2 deletions compiler/rustc_ty_utils/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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)));
}
})
Expand Down
5 changes: 5 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,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; {#+ #}
Expand Down
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`.