about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-01-26 23:15:51 +0100
committerGitHub <noreply@github.com>2024-01-26 23:15:51 +0100
commit8ec883856d73ccfc72ccf907cc8c361dc66e65f3 (patch)
treee1bfc096855572c30f9e4bf9d3b81a5a3a8d0303 /compiler
parent975a82b4e2f6faff274b9a4ae4a1f5fa9315d265 (diff)
parent866364cc5d79b26ec1ab58eca0cc4c3416b5a1bc (diff)
downloadrust-8ec883856d73ccfc72ccf907cc8c361dc66e65f3.tar.gz
rust-8ec883856d73ccfc72ccf907cc8c361dc66e65f3.zip
Rollup merge of #120277 - compiler-errors:normalize-before-validating, r=oli-obk
Normalize field types before checking validity

I forgot to normalize field types when checking ADT-like aggregates in the MIR validator.

This normalization is needed due to a crude check for opaque types in `mir_assign_valid_types` which prevents opaque type cycles -- if we pass in an unnormalized type, we may not detect that the destination type is an opaque, and therefore will call `type_of(opaque)` later on, which causes a cycle error -> ICE.

Fixes #120253
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs23
1 files changed, 14 insertions, 9 deletions
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 5564902396e..21bdb66a276 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -810,13 +810,18 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                     let adt_def = self.tcx.adt_def(def_id);
                     assert!(adt_def.is_union());
                     assert_eq!(idx, FIRST_VARIANT);
-                    let dest = adt_def.non_enum_variant().fields[field].ty(self.tcx, args);
-                    if fields.len() != 1 {
+                    let dest_ty = self.tcx.normalize_erasing_regions(
+                        self.param_env,
+                        adt_def.non_enum_variant().fields[field].ty(self.tcx, args),
+                    );
+                    if fields.len() == 1 {
+                        let src_ty = fields.raw[0].ty(self.body, self.tcx);
+                        if !self.mir_assign_valid_types(src_ty, dest_ty) {
+                            self.fail(location, "union field has the wrong type");
+                        }
+                    } else {
                         self.fail(location, "unions should have one initialized field");
                     }
-                    if !self.mir_assign_valid_types(fields.raw[0].ty(self.body, self.tcx), dest) {
-                        self.fail(location, "union field has the wrong type");
-                    }
                 }
                 AggregateKind::Adt(def_id, idx, args, _, None) => {
                     let adt_def = self.tcx.adt_def(def_id);
@@ -826,10 +831,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                         self.fail(location, "adt has the wrong number of initialized fields");
                     }
                     for (src, dest) in std::iter::zip(fields, &variant.fields) {
-                        if !self.mir_assign_valid_types(
-                            src.ty(self.body, self.tcx),
-                            dest.ty(self.tcx, args),
-                        ) {
+                        let dest_ty = self
+                            .tcx
+                            .normalize_erasing_regions(self.param_env, dest.ty(self.tcx, args));
+                        if !self.mir_assign_valid_types(src.ty(self.body, self.tcx), dest_ty) {
                             self.fail(location, "adt field has the wrong type");
                         }
                     }