about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGurinder Singh <frederick.the.fool@gmail.com>2024-05-01 09:29:33 +0530
committerGurinder Singh <frederick.the.fool@gmail.com>2024-05-01 09:29:33 +0530
commit0c71c9d74b92430847ee2f7534d0da3d9183ca34 (patch)
tree610647c057ed55a1f98537de79934ec01b6557f9
parent90846015cc99aa90290c1f4ee95c571fff6901ef (diff)
downloadrust-0c71c9d74b92430847ee2f7534d0da3d9183ca34.tar.gz
rust-0c71c9d74b92430847ee2f7534d0da3d9183ca34.zip
Handle normalization failure in `struct_tail_erasing_lifetimes`
Fixes an ICE that occurred when the struct in question has an error
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs17
-rw-r--r--tests/ui/structs/ice-struct-tail-normalization-113272.rs (renamed from tests/crashes/113272.rs)3
-rw-r--r--tests/ui/structs/ice-struct-tail-normalization-113272.stderr19
3 files changed, 37 insertions, 2 deletions
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 @@ impl<'tcx> SizeSkeleton<'tcx> {
         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
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`.