1
Fork 0

Avoid ICEing miri on layout query cycles

This commit is contained in:
Oli Scherer 2023-05-02 16:14:20 +00:00
parent 7b99493492
commit 7bc6d598f9
6 changed files with 119 additions and 44 deletions

View file

@ -32,6 +32,9 @@ middle_values_too_big =
middle_cannot_be_normalized =
unable to determine layout for `{$ty}` because `{$failure_ty}` cannot be normalized
middle_cycle =
a cycle occurred during layout computation
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

View file

@ -210,6 +210,7 @@ pub enum LayoutError<'tcx> {
Unknown(Ty<'tcx>),
SizeOverflow(Ty<'tcx>),
NormalizationFailure(Ty<'tcx>, NormalizationError<'tcx>),
Cycle,
}
impl IntoDiagnostic<'_, !> for LayoutError<'_> {
@ -230,6 +231,9 @@ impl IntoDiagnostic<'_, !> for LayoutError<'_> {
diag.set_arg("failure_ty", e.get_type_for_failure());
diag.set_primary_message(fluent::middle_cannot_be_normalized);
}
LayoutError::Cycle => {
diag.set_primary_message(fluent::middle_cycle);
}
}
diag
}
@ -250,6 +254,7 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
t,
e.get_type_for_failure()
),
LayoutError::Cycle => write!(f, "a cycle occurred during layout computation"),
}
}
}

View file

@ -106,6 +106,12 @@ impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::EarlyBinder<ty::Binder<'_, ty::F
}
}
impl<'tcx, T> Value<TyCtxt<'tcx>, DepKind> for Result<T, ty::layout::LayoutError<'_>> {
fn from_cycle_error(_tcx: TyCtxt<'tcx>, _cycle: &[QueryInfo<DepKind>]) -> Self {
Err(ty::layout::LayoutError::Cycle)
}
}
// item_and_field_ids should form a cycle where each field contains the
// type in the next element in the list
pub fn recursive_type_error(

View file

@ -49,5 +49,10 @@
<strong>Note:</strong> Encountered an error during type layout; {#+ #}
the type failed to be normalized. {# #}
</p> {# #}
{% when Err(LayoutError::Cycle) %}
<p> {# #}
<strong>Note:</strong> Encountered an error during type layout; {#+ #}
the type's layout depended on the type's layout itself. {# #}
</p> {# #}
{% endmatch %}
</div> {# #}

View file

@ -0,0 +1,28 @@
//@error-pattern: a cycle occurred during layout computation
//~^ ERROR: cycle detected when computing layout of
use std::mem;
pub struct S<T: Tr> {
pub f: <T as Tr>::I,
}
pub trait Tr {
type I: Tr;
}
impl<T: Tr> Tr for S<T> {
type I = S<S<T>>;
}
impl Tr for () {
type I = ();
}
fn foo<T: Tr>() -> usize {
mem::size_of::<S<T>>()
}
fn main() {
println!("{}", foo::<S<()>>());
}

View file

@ -0,0 +1,28 @@
error[E0391]: cycle detected when computing layout of `S<S<()>>`
|
= note: ...which requires computing layout of `<S<()> as Tr>::I`...
= note: ...which again requires computing layout of `S<S<()>>`, completing the cycle
error: post-monomorphization error: a cycle occurred during layout computation
--> RUSTLIB/core/src/mem/mod.rs:LL:CC
|
LL | intrinsics::size_of::<T>()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ a cycle occurred during layout computation
|
= note: inside `std::mem::size_of::<S<S<()>>>` at RUSTLIB/core/src/mem/mod.rs:LL:CC
note: inside `foo::<S<()>>`
--> $DIR/layout_cycle.rs:LL:CC
|
LL | mem::size_of::<S<T>>()
| ^^^^^^^^^^^^^^^^^^^^^^
note: inside `main`
--> $DIR/layout_cycle.rs:LL:CC
|
LL | println!("{}", foo::<S<()>>());
| ^^^^^^^^^^^^^^
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0391`.