@@ -110,12 +110,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
110110 variant
111111 }
112112 ty:: Adt ( adt_def, generics) => {
113- // TODO(type_info): Handle union
114- if !adt_def. is_struct ( ) && !adt_def. is_enum ( ) {
115- self . downcast ( & field_dest, sym:: Other ) ?. 0
116- } else {
117- self . write_adt_type_info ( & field_dest, ( ty, * adt_def) , generics) ?
118- }
113+ self . write_adt_type_info ( & field_dest, ( ty, * adt_def) , generics) ?
119114 }
120115 ty:: Bool => {
121116 let ( variant, _variant_place) =
@@ -345,13 +340,22 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
345340 ) ?;
346341 variant
347342 }
343+ AdtKind :: Union => {
344+ let ( variant, variant_place) = self . downcast ( place, sym:: Union ) ?;
345+ let place = self . project_field ( & variant_place, FieldIdx :: ZERO ) ?;
346+ self . write_union_type_info (
347+ place,
348+ ( adt_ty, adt_def. variant ( VariantIdx :: ZERO ) ) ,
349+ generics,
350+ ) ?;
351+ variant
352+ }
348353 AdtKind :: Enum => {
349354 let ( variant, variant_place) = self . downcast ( place, sym:: Enum ) ?;
350355 let place = self . project_field ( & variant_place, FieldIdx :: ZERO ) ?;
351356 self . write_enum_type_info ( place, adt, generics) ?;
352357 variant
353358 }
354- AdtKind :: Union => todo ! ( ) ,
355359 } ;
356360 interp_ok ( variant_idx)
357361 }
@@ -386,6 +390,36 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
386390 interp_ok ( ( ) )
387391 }
388392
393+ pub ( crate ) fn write_union_type_info (
394+ & mut self ,
395+ place : impl Writeable < ' tcx , CtfeProvenance > ,
396+ union_ : ( Ty < ' tcx > , & ' tcx VariantDef ) ,
397+ generics : & ' tcx GenericArgs < ' tcx > ,
398+ ) -> InterpResult < ' tcx > {
399+ let ( union_ty, union_def) = union_;
400+ let union_layout = self . layout_of ( union_ty) ?;
401+
402+ for ( field_idx, field) in
403+ place. layout ( ) . ty . ty_adt_def ( ) . unwrap ( ) . non_enum_variant ( ) . fields . iter_enumerated ( )
404+ {
405+ let field_place = self . project_field ( & place, field_idx) ?;
406+
407+ match field. name {
408+ sym:: generics => self . write_generics ( field_place, generics) ?,
409+ sym:: fields => {
410+ self . write_variant_fields ( field_place, union_def, union_layout, generics) ?
411+ }
412+ sym:: non_exhaustive => {
413+ let is_non_exhaustive = union_def. is_field_list_non_exhaustive ( ) ;
414+ self . write_scalar ( Scalar :: from_bool ( is_non_exhaustive) , & field_place) ?
415+ }
416+ other => span_bug ! ( self . tcx. def_span( field. did) , "unimplemented field {other}" ) ,
417+ }
418+ }
419+
420+ interp_ok ( ( ) )
421+ }
422+
389423 pub ( crate ) fn write_enum_type_info (
390424 & mut self ,
391425 place : impl Writeable < ' tcx , CtfeProvenance > ,
0 commit comments