@@ -32,6 +32,7 @@ use rustc_span::{
32
32
} ;
33
33
use serde:: { Serialize , Serializer } ;
34
34
use stable_mir:: {
35
+ abi:: LayoutShape ,
35
36
mir:: mono:: { Instance , InstanceKind , MonoItem } ,
36
37
mir:: { alloc:: AllocId , visit:: MirVisitor , Body , LocalDecl , Rvalue , Terminator , TerminatorKind } ,
37
38
ty:: { AdtDef , Allocation , ConstDef , ForeignItemKind , IndexedVal , RigidTy , TyKind } ,
@@ -566,19 +567,14 @@ impl Visitor for TyCollector<'_> {
566
567
. map ( rustc_internal:: stable)
567
568
. collect ( ) ;
568
569
569
- let mut control = ty. super_visit ( self ) ;
570
+ let control = ty. super_visit ( self ) ;
570
571
if matches ! ( control, ControlFlow :: Continue ( _) ) {
571
572
let maybe_layout_shape = ty. layout ( ) . ok ( ) . map ( |layout| layout. shape ( ) ) ;
572
573
self . types . insert ( * ty, ( ty. kind ( ) , maybe_layout_shape) ) ;
574
+ fields. super_visit ( self )
575
+ } else {
576
+ control
573
577
}
574
-
575
- for f_ty in fields {
576
- control = self . visit_ty ( & f_ty) ;
577
- if matches ! ( control, ControlFlow :: Break ( ( ) ) ) {
578
- break ;
579
- }
580
- }
581
- control
582
578
}
583
579
_ => {
584
580
let control = ty. super_visit ( self ) ;
@@ -1005,21 +1001,35 @@ pub enum TypeMetadata {
1005
1001
adt_def : AdtDef ,
1006
1002
discriminants : Vec < u128 > ,
1007
1003
fields : Vec < Vec < stable_mir:: ty:: Ty > > ,
1004
+ layout : Option < LayoutShape > ,
1008
1005
} ,
1009
1006
StructType {
1010
1007
name : String ,
1011
1008
adt_def : AdtDef ,
1012
1009
fields : Vec < stable_mir:: ty:: Ty > ,
1010
+ layout : Option < LayoutShape > ,
1013
1011
} ,
1014
1012
UnionType {
1015
1013
name : String ,
1016
1014
adt_def : AdtDef ,
1015
+ layout : Option < LayoutShape > ,
1016
+ } ,
1017
+ ArrayType {
1018
+ elem_type : stable_mir:: ty:: Ty ,
1019
+ size : Option < stable_mir:: ty:: TyConst > ,
1020
+ layout : Option < LayoutShape > ,
1021
+ } ,
1022
+ PtrType {
1023
+ pointee_type : stable_mir:: ty:: Ty ,
1024
+ layout : Option < LayoutShape > ,
1025
+ } ,
1026
+ RefType {
1027
+ pointee_type : stable_mir:: ty:: Ty ,
1028
+ layout : Option < LayoutShape > ,
1017
1029
} ,
1018
- ArrayType ( stable_mir:: ty:: Ty , Option < stable_mir:: ty:: TyConst > ) ,
1019
- PtrType ( stable_mir:: ty:: Ty ) ,
1020
- RefType ( stable_mir:: ty:: Ty ) ,
1021
1030
TupleType {
1022
1031
types : Vec < stable_mir:: ty:: Ty > ,
1032
+ layout : Option < LayoutShape > ,
1023
1033
} ,
1024
1034
FunType ( String ) ,
1025
1035
VoidType ,
@@ -1029,10 +1039,12 @@ fn mk_type_metadata(
1029
1039
tcx : TyCtxt < ' _ > ,
1030
1040
k : stable_mir:: ty:: Ty ,
1031
1041
t : TyKind ,
1042
+ layout : Option < LayoutShape > ,
1032
1043
) -> Option < ( stable_mir:: ty:: Ty , TypeMetadata ) > {
1033
1044
use stable_mir:: ty:: RigidTy :: * ;
1034
1045
use TyKind :: RigidTy as T ;
1035
1046
use TypeMetadata :: * ;
1047
+ let name = format ! ( "{k}" ) ; // prints name with type parameters
1036
1048
match t {
1037
1049
T ( prim_type) if t. is_primitive ( ) => Some ( ( k, PrimitiveType ( prim_type) ) ) ,
1038
1050
// for enums, we need a mapping of variantIdx to discriminant
@@ -1054,20 +1066,18 @@ fn mk_type_metadata(
1054
1066
. collect :: < Vec < stable_mir:: ty:: Ty > > ( )
1055
1067
} )
1056
1068
. collect ( ) ;
1057
- let name = adt_def. name ( ) ;
1058
1069
Some ( (
1059
1070
k,
1060
1071
EnumType {
1061
1072
name,
1062
1073
adt_def,
1063
1074
discriminants,
1064
1075
fields,
1076
+ layout,
1065
1077
} ,
1066
1078
) )
1067
1079
}
1068
- // for structs, we record the name for information purposes and the field types
1069
1080
T ( Adt ( adt_def, args) ) if t. is_struct ( ) => {
1070
- let name = adt_def. name ( ) ;
1071
1081
let fields = rustc_internal:: internal ( tcx, adt_def)
1072
1082
. all_fields ( ) // is_struct, so only one variant
1073
1083
. map ( move |f| f. ty ( tcx, rustc_internal:: internal ( tcx, & args) ) )
@@ -1079,26 +1089,56 @@ fn mk_type_metadata(
1079
1089
name,
1080
1090
adt_def,
1081
1091
fields,
1092
+ layout,
1082
1093
} ,
1083
1094
) )
1084
1095
}
1085
- // for unions, we only record the name
1086
- T ( Adt ( adt_def, _) ) if t. is_union ( ) => {
1087
- let name = adt_def. name ( ) ;
1088
- Some ( ( k, UnionType { name, adt_def } ) )
1089
- }
1096
+ T ( Adt ( adt_def, _) ) if t. is_union ( ) => Some ( (
1097
+ k,
1098
+ UnionType {
1099
+ name,
1100
+ adt_def,
1101
+ layout,
1102
+ } ,
1103
+ ) ) ,
1090
1104
// encode str together with primitive types
1091
1105
T ( Str ) => Some ( ( k, PrimitiveType ( Str ) ) ) ,
1092
1106
// for arrays and slices, record element type and optional size
1093
- T ( Array ( ty, ty_const) ) => Some ( ( k, ArrayType ( ty, Some ( ty_const) ) ) ) ,
1094
- T ( Slice ( ty) ) => Some ( ( k, ArrayType ( ty, None ) ) ) ,
1107
+ T ( Array ( elem_type, ty_const) ) => Some ( (
1108
+ k,
1109
+ ArrayType {
1110
+ elem_type,
1111
+ size : Some ( ty_const) ,
1112
+ layout,
1113
+ } ,
1114
+ ) ) ,
1115
+ T ( Slice ( elem_type) ) => Some ( (
1116
+ k,
1117
+ ArrayType {
1118
+ elem_type,
1119
+ size : None ,
1120
+ layout,
1121
+ } ,
1122
+ ) ) ,
1095
1123
// for raw pointers and references store the pointee type
1096
- T ( RawPtr ( ty, _) ) => Some ( ( k, PtrType ( ty) ) ) ,
1097
- T ( Ref ( _, ty, _) ) => Some ( ( k, RefType ( ty) ) ) ,
1124
+ T ( RawPtr ( pointee_type, _) ) => Some ( (
1125
+ k,
1126
+ PtrType {
1127
+ pointee_type,
1128
+ layout,
1129
+ } ,
1130
+ ) ) ,
1131
+ T ( Ref ( _, pointee_type, _) ) => Some ( (
1132
+ k,
1133
+ RefType {
1134
+ pointee_type,
1135
+ layout,
1136
+ } ,
1137
+ ) ) ,
1098
1138
// for tuples the element types are provided
1099
- T ( Tuple ( tys ) ) => Some ( ( k, TupleType { types : tys } ) ) ,
1139
+ T ( Tuple ( types ) ) => Some ( ( k, TupleType { types, layout } ) ) ,
1100
1140
// opaque function types (fun ptrs, closures, FnDef) are only provided to avoid dangling ty references
1101
- T ( FnDef ( _, _) ) | T ( FnPtr ( _) ) | T ( Closure ( _, _) ) => Some ( ( k, FunType ( format ! ( "{}" , k ) ) ) ) ,
1141
+ T ( FnDef ( _, _) ) | T ( FnPtr ( _) ) | T ( Closure ( _, _) ) => Some ( ( k, FunType ( name ) ) ) ,
1102
1142
// other types are not provided either
1103
1143
T ( Foreign ( _) )
1104
1144
| T ( Pat ( _, _) )
@@ -1203,8 +1243,7 @@ pub fn collect_smir(tcx: TyCtxt<'_>) -> SmirJson {
1203
1243
1204
1244
let mut types = visited_tys
1205
1245
. into_iter ( )
1206
- . map ( |( k, ( v, _) ) | ( k, v) )
1207
- . filter_map ( |( k, t) | mk_type_metadata ( tcx, k, t) )
1246
+ . filter_map ( |( k, ( t, l) ) | mk_type_metadata ( tcx, k, t, l) )
1208
1247
// .filter(|(_, v)| v.is_primitive())
1209
1248
. collect :: < Vec < _ > > ( ) ;
1210
1249
0 commit comments