Normalize field types before checking validity
This commit is contained in:
parent
e7bbe8ce93
commit
866364cc5d
@ -810,13 +810,18 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
let adt_def = self.tcx.adt_def(def_id);
|
let adt_def = self.tcx.adt_def(def_id);
|
||||||
assert!(adt_def.is_union());
|
assert!(adt_def.is_union());
|
||||||
assert_eq!(idx, FIRST_VARIANT);
|
assert_eq!(idx, FIRST_VARIANT);
|
||||||
let dest = adt_def.non_enum_variant().fields[field].ty(self.tcx, args);
|
let dest_ty = self.tcx.normalize_erasing_regions(
|
||||||
if fields.len() != 1 {
|
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");
|
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) => {
|
AggregateKind::Adt(def_id, idx, args, _, None) => {
|
||||||
let adt_def = self.tcx.adt_def(def_id);
|
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");
|
self.fail(location, "adt has the wrong number of initialized fields");
|
||||||
}
|
}
|
||||||
for (src, dest) in std::iter::zip(fields, &variant.fields) {
|
for (src, dest) in std::iter::zip(fields, &variant.fields) {
|
||||||
if !self.mir_assign_valid_types(
|
let dest_ty = self
|
||||||
src.ty(self.body, self.tcx),
|
.tcx
|
||||||
dest.ty(self.tcx, args),
|
.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");
|
self.fail(location, "adt field has the wrong type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
31
tests/ui/type-alias-impl-trait/struct-assignment-validity.rs
Normal file
31
tests/ui/type-alias-impl-trait/struct-assignment-validity.rs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// compile-flags: -Zvalidate-mir
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
// Check that we don't cause cycle errors when validating pre-`Reveal::All` MIR
|
||||||
|
// that assigns opaques through normalized projections.
|
||||||
|
|
||||||
|
#![feature(impl_trait_in_assoc_type)]
|
||||||
|
|
||||||
|
struct Bar;
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
type Assoc;
|
||||||
|
fn foo() -> Foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait for Bar {
|
||||||
|
type Assoc = impl std::fmt::Debug;
|
||||||
|
fn foo() -> Foo
|
||||||
|
where
|
||||||
|
Self::Assoc:,
|
||||||
|
{
|
||||||
|
let x: <Bar as Trait>::Assoc = ();
|
||||||
|
Foo { field: () }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Foo {
|
||||||
|
field: <Bar as Trait>::Assoc,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
x
Reference in New Issue
Block a user