Skip to content

Commit c3483a9

Browse files
authored
Unrolled build for rust-lang#120137
Rollup merge of rust-lang#120137 - compiler-errors:validate-aggregates, r=nnethercote Validate AggregateKind types in MIR Would have helped me catch some bugs when writing shims for async closures
2 parents 021861a + f26f52c commit c3483a9

File tree

1 file changed

+61
-1
lines changed

1 file changed

+61
-1
lines changed

compiler/rustc_const_eval/src/transform/validate.rs

+61-1
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,67 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
796796
};
797797
}
798798
match rvalue {
799-
Rvalue::Use(_) | Rvalue::CopyForDeref(_) | Rvalue::Aggregate(..) => {}
799+
Rvalue::Use(_) | Rvalue::CopyForDeref(_) => {}
800+
Rvalue::Aggregate(kind, fields) => match **kind {
801+
AggregateKind::Tuple => {}
802+
AggregateKind::Array(dest) => {
803+
for src in fields {
804+
if !self.mir_assign_valid_types(src.ty(self.body, self.tcx), dest) {
805+
self.fail(location, "array field has the wrong type");
806+
}
807+
}
808+
}
809+
AggregateKind::Adt(def_id, idx, args, _, Some(field)) => {
810+
let adt_def = self.tcx.adt_def(def_id);
811+
assert!(adt_def.is_union());
812+
assert_eq!(idx, FIRST_VARIANT);
813+
let dest = adt_def.non_enum_variant().fields[field].ty(self.tcx, args);
814+
if fields.len() != 1 {
815+
self.fail(location, "unions should have one initialized field");
816+
}
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+
}
820+
}
821+
AggregateKind::Adt(def_id, idx, args, _, None) => {
822+
let adt_def = self.tcx.adt_def(def_id);
823+
assert!(!adt_def.is_union());
824+
let variant = &adt_def.variants()[idx];
825+
if variant.fields.len() != fields.len() {
826+
self.fail(location, "adt has the wrong number of initialized fields");
827+
}
828+
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+
) {
833+
self.fail(location, "adt field has the wrong type");
834+
}
835+
}
836+
}
837+
AggregateKind::Closure(_, args) => {
838+
let upvars = args.as_closure().upvar_tys();
839+
if upvars.len() != fields.len() {
840+
self.fail(location, "closure has the wrong number of initialized fields");
841+
}
842+
for (src, dest) in std::iter::zip(fields, upvars) {
843+
if !self.mir_assign_valid_types(src.ty(self.body, self.tcx), dest) {
844+
self.fail(location, "closure field has the wrong type");
845+
}
846+
}
847+
}
848+
AggregateKind::Coroutine(_, args) => {
849+
let upvars = args.as_coroutine().upvar_tys();
850+
if upvars.len() != fields.len() {
851+
self.fail(location, "coroutine has the wrong number of initialized fields");
852+
}
853+
for (src, dest) in std::iter::zip(fields, upvars) {
854+
if !self.mir_assign_valid_types(src.ty(self.body, self.tcx), dest) {
855+
self.fail(location, "coroutine field has the wrong type");
856+
}
857+
}
858+
}
859+
},
800860
Rvalue::Ref(_, BorrowKind::Fake, _) => {
801861
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
802862
self.fail(

0 commit comments

Comments
 (0)