Skip to content

Commit 7649099

Browse files
authored
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
2 parents cff3c4b + dbf638e commit 7649099

File tree

2 files changed

+42
-9
lines changed

2 files changed

+42
-9
lines changed

Diff for: compiler/rustc_const_eval/src/transform/validate.rs

+14-9
Original file line numberDiff line numberDiff line change
@@ -810,13 +810,18 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
810810
let adt_def = self.tcx.adt_def(def_id);
811811
assert!(adt_def.is_union());
812812
assert_eq!(idx, FIRST_VARIANT);
813-
let dest = adt_def.non_enum_variant().fields[field].ty(self.tcx, args);
814-
if fields.len() != 1 {
813+
let dest_ty = self.tcx.normalize_erasing_regions(
814+
self.param_env,
815+
adt_def.non_enum_variant().fields[field].ty(self.tcx, args),
816+
);
817+
if fields.len() == 1 {
818+
let src_ty = fields.raw[0].ty(self.body, self.tcx);
819+
if !self.mir_assign_valid_types(src_ty, dest_ty) {
820+
self.fail(location, "union field has the wrong type");
821+
}
822+
} else {
815823
self.fail(location, "unions should have one initialized field");
816824
}
817-
if !self.mir_assign_valid_types(fields.raw[0].ty(self.body, self.tcx), dest) {
818-
self.fail(location, "union field has the wrong type");
819-
}
820825
}
821826
AggregateKind::Adt(def_id, idx, args, _, None) => {
822827
let adt_def = self.tcx.adt_def(def_id);
@@ -826,10 +831,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
826831
self.fail(location, "adt has the wrong number of initialized fields");
827832
}
828833
for (src, dest) in std::iter::zip(fields, &variant.fields) {
829-
if !self.mir_assign_valid_types(
830-
src.ty(self.body, self.tcx),
831-
dest.ty(self.tcx, args),
832-
) {
834+
let dest_ty = self
835+
.tcx
836+
.normalize_erasing_regions(self.param_env, dest.ty(self.tcx, args));
837+
if !self.mir_assign_valid_types(src.ty(self.body, self.tcx), dest_ty) {
833838
self.fail(location, "adt field has the wrong type");
834839
}
835840
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// compile-flags: -Zvalidate-mir
2+
// check-pass
3+
4+
// Check that we don't cause cycle errors when validating pre-`Reveal::All` MIR
5+
// that assigns opaques through normalized projections.
6+
7+
#![feature(impl_trait_in_assoc_type)]
8+
9+
struct Bar;
10+
11+
trait Trait {
12+
type Assoc;
13+
fn foo() -> Foo;
14+
}
15+
16+
impl Trait for Bar {
17+
type Assoc = impl std::fmt::Debug;
18+
fn foo() -> Foo {
19+
let x: <Bar as Trait>::Assoc = ();
20+
Foo { field: () }
21+
}
22+
}
23+
24+
struct Foo {
25+
field: <Bar as Trait>::Assoc,
26+
}
27+
28+
fn main() {}

0 commit comments

Comments
 (0)