@@ -35,6 +35,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
3535
3636 interp_ok ( ( variant_id, self . project_downcast ( & field_dest, variant_id) ?) )
3737 } ;
38+ let ptr_bit_width = || self . tcx . data_layout . pointer_size ( ) . bits ( ) ;
3839 match field. name {
3940 sym:: kind => {
4041 let variant_index = match ty. kind ( ) {
@@ -64,13 +65,60 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
6465
6566 variant
6667 }
67- // For now just merge all primitives into one `Leaf` variant with no data
68- ty:: Uint ( _) | ty:: Int ( _) | ty:: Float ( _) | ty:: Char | ty:: Bool => {
69- downcast ( sym:: Leaf ) ?. 0
68+ ty:: Bool => {
69+ let ( variant, variant_place) = downcast ( sym:: Bool ) ?;
70+ let place = self . project_field ( & variant_place, FieldIdx :: ZERO ) ?;
71+ self . write_primitive_type_info ( place, ty, None ) ?;
72+ variant
73+ }
74+ ty:: Char => {
75+ let ( variant, variant_place) = downcast ( sym:: Char ) ?;
76+ let place = self . project_field ( & variant_place, FieldIdx :: ZERO ) ?;
77+ self . write_primitive_type_info ( place, ty, None ) ?;
78+ variant
79+ }
80+ ty:: Int ( int_ty) => {
81+ let ( variant, variant_place) = downcast ( sym:: Int ) ?;
82+ let place = self . project_field ( & variant_place, FieldIdx :: ZERO ) ?;
83+ self . write_primitive_type_info (
84+ place,
85+ ty,
86+ Some (
87+ int_ty
88+ . bit_width ( )
89+ . unwrap_or_else ( /* isize */ ptr_bit_width) ,
90+ ) ,
91+ ) ?;
92+ variant
93+ }
94+ ty:: Uint ( uint_ty) => {
95+ let ( variant, variant_place) = downcast ( sym:: Uint ) ?;
96+ let place = self . project_field ( & variant_place, FieldIdx :: ZERO ) ?;
97+ self . write_primitive_type_info (
98+ place,
99+ ty,
100+ Some (
101+ uint_ty
102+ . bit_width ( )
103+ . unwrap_or_else ( /* usize */ ptr_bit_width) ,
104+ ) ,
105+ ) ?;
106+ variant
107+ }
108+ ty:: Float ( float_ty) => {
109+ let ( variant, variant_place) = downcast ( sym:: Float ) ?;
110+ let place = self . project_field ( & variant_place, FieldIdx :: ZERO ) ?;
111+ self . write_primitive_type_info ( place, ty, Some ( float_ty. bit_width ( ) ) ) ?;
112+ variant
113+ }
114+ ty:: Str => {
115+ let ( variant, variant_place) = downcast ( sym:: Str ) ?;
116+ let place = self . project_field ( & variant_place, FieldIdx :: ZERO ) ?;
117+ self . write_primitive_type_info ( place, ty, None ) ?;
118+ variant
70119 }
71120 ty:: Adt ( _, _)
72121 | ty:: Foreign ( _)
73- | ty:: Str
74122 | ty:: Pat ( _, _)
75123 | ty:: Slice ( _)
76124 | ty:: RawPtr ( ..)
@@ -203,4 +251,32 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
203251
204252 interp_ok ( ( ) )
205253 }
254+
255+ // This method always writes to field `ty`.
256+ // If field `bit_width` is present, it also writes to it (in which case parameter `write_bit_width` must be `Some`).
257+ fn write_primitive_type_info (
258+ & mut self ,
259+ place : impl Writeable < ' tcx , CtfeProvenance > ,
260+ ty : Ty < ' tcx > ,
261+ write_bit_width : Option < u64 > ,
262+ ) -> InterpResult < ' tcx > {
263+ for ( field_idx, field) in
264+ place. layout ( ) . ty . ty_adt_def ( ) . unwrap ( ) . non_enum_variant ( ) . fields . iter_enumerated ( )
265+ {
266+ let field_place = self . project_field ( & place, field_idx) ?;
267+ match field. name {
268+ sym:: ty => self . write_type_id ( ty, & field_place) ?,
269+ sym:: bit_width => {
270+ let bit_width = write_bit_width
271+ . expect ( "type info struct needs a `bit_width` but none was provided" ) ;
272+ self . write_scalar (
273+ ScalarInt :: try_from_target_usize ( bit_width, self . tcx . tcx ) . unwrap ( ) ,
274+ & field_place,
275+ ) ?
276+ }
277+ other => span_bug ! ( self . tcx. def_span( field. did) , "unimplemented field {other}" ) ,
278+ }
279+ }
280+ interp_ok ( ( ) )
281+ }
206282}
0 commit comments