@@ -119,12 +119,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
119119 variant
120120 }
121121 ty:: Adt ( adt_def, generics) => {
122- // TODO(type_info): Handle union
123- if !adt_def. is_struct ( ) && !adt_def. is_enum ( ) {
124- self . downcast ( & field_dest, sym:: Other ) ?. 0
125- } else {
126- self . write_adt_type_info ( & field_dest, ( ty, * adt_def) , generics) ?
127- }
122+ self . write_adt_type_info ( & field_dest, ( ty, * adt_def) , generics) ?
128123 }
129124 ty:: Bool => {
130125 let ( variant, _variant_place) =
@@ -389,13 +384,22 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
389384 ) ?;
390385 variant
391386 }
387+ AdtKind :: Union => {
388+ let ( variant, variant_place) = self . downcast ( place, sym:: Union ) ?;
389+ let place = self . project_field ( & variant_place, FieldIdx :: ZERO ) ?;
390+ self . write_union_type_info (
391+ place,
392+ ( adt_ty, adt_def. variant ( VariantIdx :: ZERO ) ) ,
393+ generics,
394+ ) ?;
395+ variant
396+ }
392397 AdtKind :: Enum => {
393398 let ( variant, variant_place) = self . downcast ( place, sym:: Enum ) ?;
394399 let place = self . project_field ( & variant_place, FieldIdx :: ZERO ) ?;
395400 self . write_enum_type_info ( place, adt, generics) ?;
396401 variant
397402 }
398- AdtKind :: Union => todo ! ( ) ,
399403 } ;
400404 interp_ok ( variant_idx)
401405 }
@@ -430,6 +434,36 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
430434 interp_ok ( ( ) )
431435 }
432436
437+ pub ( crate ) fn write_union_type_info (
438+ & mut self ,
439+ place : impl Writeable < ' tcx , CtfeProvenance > ,
440+ union_ : ( Ty < ' tcx > , & ' tcx VariantDef ) ,
441+ generics : & ' tcx GenericArgs < ' tcx > ,
442+ ) -> InterpResult < ' tcx > {
443+ let ( union_ty, union_def) = union_;
444+ let union_layout = self . layout_of ( union_ty) ?;
445+
446+ for ( field_idx, field) in
447+ place. layout ( ) . ty . ty_adt_def ( ) . unwrap ( ) . non_enum_variant ( ) . fields . iter_enumerated ( )
448+ {
449+ let field_place = self . project_field ( & place, field_idx) ?;
450+
451+ match field. name {
452+ sym:: generics => self . write_generics ( field_place, generics) ?,
453+ sym:: fields => {
454+ self . write_variant_fields ( field_place, union_def, union_layout, generics) ?
455+ }
456+ sym:: non_exhaustive => {
457+ let is_non_exhaustive = union_def. is_field_list_non_exhaustive ( ) ;
458+ self . write_scalar ( Scalar :: from_bool ( is_non_exhaustive) , & field_place) ?
459+ }
460+ other => span_bug ! ( self . tcx. def_span( field. did) , "unimplemented field {other}" ) ,
461+ }
462+ }
463+
464+ interp_ok ( ( ) )
465+ }
466+
433467 pub ( crate ) fn write_enum_type_info (
434468 & mut self ,
435469 place : impl Writeable < ' tcx , CtfeProvenance > ,
0 commit comments