From 0c71c9d74b92430847ee2f7534d0da3d9183ca34 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Wed, 1 May 2024 09:29:33 +0530 Subject: [PATCH] Handle normalization failure in `struct_tail_erasing_lifetimes` Fixes an ICE that occurred when the struct in question has an error --- compiler/rustc_middle/src/ty/layout.rs | 17 ++++++++++++++++- .../ice-struct-tail-normalization-113272.rs} | 3 ++- ...ce-struct-tail-normalization-113272.stderr | 19 +++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) rename tests/{crashes/113272.rs => ui/structs/ice-struct-tail-normalization-113272.rs} (66%) create mode 100644 tests/ui/structs/ice-struct-tail-normalization-113272.stderr diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 897d6f5662f..e5391ae9333 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -332,7 +332,22 @@ pub fn compute( match *ty.kind() { ty::Ref(_, pointee, _) | ty::RawPtr(pointee, _) => { let non_zero = !ty.is_unsafe_ptr(); - let tail = tcx.struct_tail_erasing_lifetimes(pointee, param_env); + + let tail = tcx.struct_tail_with_normalize( + pointee, + |ty| match tcx.try_normalize_erasing_regions(param_env, ty) { + Ok(ty) => ty, + Err(_e) => { + if let Some(guar) = tcx.dcx().has_errors() { + Ty::new_error(tcx, guar) + } else { + bug!("normalization failed, but no errors reported"); + } + } + }, + || {}, + ); + match tail.kind() { ty::Param(_) | ty::Alias(ty::Projection | ty::Inherent, _) => { debug_assert!(tail.has_non_region_param()); diff --git a/tests/crashes/113272.rs b/tests/ui/structs/ice-struct-tail-normalization-113272.rs similarity index 66% rename from tests/crashes/113272.rs rename to tests/ui/structs/ice-struct-tail-normalization-113272.rs index d161575c657..85d3d1b4886 100644 --- a/tests/crashes/113272.rs +++ b/tests/ui/structs/ice-struct-tail-normalization-113272.rs @@ -1,9 +1,10 @@ -//@ known-bug: #113272 trait Trait { type RefTarget; } impl Trait for () where Missing: Trait {} +//~^ ERROR cannot find type `Missing` in this scope +//~| ERROR not all trait items implemented, missing: `RefTarget` struct Other { data: <() as Trait>::RefTarget, diff --git a/tests/ui/structs/ice-struct-tail-normalization-113272.stderr b/tests/ui/structs/ice-struct-tail-normalization-113272.stderr new file mode 100644 index 00000000000..a205eb80f5c --- /dev/null +++ b/tests/ui/structs/ice-struct-tail-normalization-113272.stderr @@ -0,0 +1,19 @@ +error[E0412]: cannot find type `Missing` in this scope + --> $DIR/ice-struct-tail-normalization-113272.rs:5:25 + | +LL | impl Trait for () where Missing: Trait {} + | ^^^^^^^ not found in this scope + +error[E0046]: not all trait items implemented, missing: `RefTarget` + --> $DIR/ice-struct-tail-normalization-113272.rs:5:1 + | +LL | type RefTarget; + | -------------- `RefTarget` from trait +... +LL | impl Trait for () where Missing: Trait {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `RefTarget` in implementation + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0046, E0412. +For more information about an error, try `rustc --explain E0046`.