1
1
use crate :: cil_op:: { CILOp , FieldDescriptor } ;
2
- use crate :: r#type:: { DotnetTypeRef , Type } ;
2
+ use crate :: r#type:: { DotnetTypeRef , TyCache , Type } ;
3
3
use crate :: utilis:: { field_name, monomorphize} ;
4
4
use rustc_index:: IndexVec ;
5
5
use rustc_middle:: mir:: { AggregateKind , Operand , Place } ;
6
- use rustc_middle:: ty:: { AdtDef , AdtKind , GenericArg , Instance , List , ParamEnv , Ty , TyCtxt , TyKind } ;
6
+ use rustc_middle:: ty:: {
7
+ AdtDef , AdtKind , EarlyBinder , GenericArg , Instance , List , ParamEnv , Ty , TyCtxt , TyKind ,
8
+ } ;
7
9
use rustc_target:: abi:: FieldIdx ;
8
10
/// Returns the CIL ops to create the aggreagate value specifed by `aggregate_kind` at `target_location`. Uses indivlidual values specifed by `value_index`
9
11
pub fn handle_aggregate < ' tyctx > (
@@ -13,6 +15,7 @@ pub fn handle_aggregate<'tyctx>(
13
15
aggregate_kind : & AggregateKind < ' tyctx > ,
14
16
value_index : & IndexVec < FieldIdx , Operand < ' tyctx > > ,
15
17
method_instance : Instance < ' tyctx > ,
18
+ tycache : & mut TyCache ,
16
19
) -> Vec < CILOp > {
17
20
// Get CIL ops for each value
18
21
let values: Vec < _ > = value_index
@@ -21,14 +24,18 @@ pub fn handle_aggregate<'tyctx>(
21
24
. map ( |operand| {
22
25
(
23
26
operand. 0 as u32 ,
24
- crate :: operand:: handle_operand ( operand. 1 , tyctx, method, method_instance) ,
27
+ crate :: operand:: handle_operand ( operand. 1 , tyctx, method, method_instance, tycache ) ,
25
28
)
26
29
} )
27
30
. collect ( ) ;
28
31
match aggregate_kind {
29
32
AggregateKind :: Adt ( adt_def, variant_idx, subst, _utai, active_field) => {
30
- let penv = ParamEnv :: empty ( ) ;
31
- let adt_type = Instance :: resolve ( tyctx, penv, * adt_def, subst)
33
+ let penv = ParamEnv :: reveal_all ( ) ;
34
+ let subst = crate :: utilis:: monomorphize ( & method_instance, * subst, tyctx) ;
35
+ //eprintln!("Preparing to resolve {adt_def:?} {subst:?}");
36
+ let adt_type = Instance :: resolve ( tyctx, penv, * adt_def, subst) ;
37
+
38
+ let adt_type = adt_type
32
39
. expect ( "Could not resolve instance" )
33
40
. expect ( "Could not resolve instance" )
34
41
. ty ( tyctx, penv) ;
@@ -48,15 +55,22 @@ pub fn handle_aggregate<'tyctx>(
48
55
variant_idx. as_u32 ( ) ,
49
56
values,
50
57
method_instance,
51
- active_field,
58
+ & active_field,
59
+ tycache,
52
60
)
53
61
}
54
62
AggregateKind :: Array ( element) => {
55
- let element = Type :: from_ty ( * element, tyctx, & method_instance) ;
63
+ let element = crate :: utilis:: monomorphize ( & method_instance, * element, tyctx) ;
64
+ let element = tycache. type_from_cache ( element, tyctx, Some ( method_instance) ) ;
56
65
let array_type = DotnetTypeRef :: array ( element. clone ( ) , value_index. len ( ) ) ;
57
66
let mut ops: Vec < CILOp > = Vec :: with_capacity ( values. len ( ) * 2 ) ;
58
- let array_getter =
59
- super :: place:: place_adress ( target_location, tyctx, method, method_instance) ;
67
+ let array_getter = super :: place:: place_adress (
68
+ target_location,
69
+ tyctx,
70
+ method,
71
+ method_instance,
72
+ tycache,
73
+ ) ;
60
74
let sig = crate :: function_sig:: FnSig :: new (
61
75
& [ array_type. clone ( ) . into ( ) , Type :: USize , Type :: GenericArg ( 0 ) ] ,
62
76
& Type :: Void ,
@@ -75,19 +89,30 @@ pub fn handle_aggregate<'tyctx>(
75
89
tyctx,
76
90
method,
77
91
method_instance,
92
+ tycache,
78
93
) ) ;
79
94
ops
80
95
}
81
96
AggregateKind :: Tuple => {
82
97
if values. len ( ) > 8 {
83
98
todo ! ( "Tuples with more than 8 fields are not supported yet." ) ;
84
99
} else {
85
- let tuple_getter =
86
- super :: place:: place_adress ( target_location, tyctx, method, method_instance) ;
100
+ let tuple_getter = super :: place:: place_adress (
101
+ target_location,
102
+ tyctx,
103
+ method,
104
+ method_instance,
105
+ tycache,
106
+ ) ;
87
107
let types: Vec < _ > = value_index
88
108
. iter ( )
89
109
. map ( |operand| {
90
- Type :: from_ty ( operand. ty ( method, tyctx) , tyctx, & method_instance)
110
+ let operand_ty = crate :: utilis:: monomorphize (
111
+ & method_instance,
112
+ operand. ty ( method, tyctx) ,
113
+ tyctx,
114
+ ) ;
115
+ tycache. type_from_cache ( operand_ty, tyctx, Some ( method_instance) )
91
116
} )
92
117
. collect ( ) ;
93
118
let dotnet_tpe = crate :: r#type:: tuple_type ( & types) ;
@@ -107,6 +132,7 @@ pub fn handle_aggregate<'tyctx>(
107
132
tyctx,
108
133
method,
109
134
method_instance,
135
+ tycache,
110
136
) ) ;
111
137
ops
112
138
}
@@ -126,56 +152,54 @@ fn aggregate_adt<'tyctx>(
126
152
fields : Vec < ( u32 , Vec < CILOp > ) > ,
127
153
method_instance : Instance < ' tyctx > ,
128
154
_active_field : & Option < FieldIdx > ,
155
+ type_cache : & mut crate :: r#type:: TyCache ,
129
156
) -> Vec < CILOp > {
130
157
let adt_type = crate :: utilis:: monomorphize ( & method_instance, adt_type, tyctx) ;
131
- let adt_type_ref = Type :: from_ty ( adt_type, tyctx, & method_instance) ;
158
+ let adt_type_ref = type_cache . type_from_cache ( adt_type, tyctx, Some ( method_instance) ) ;
132
159
let adt_type_ref = if let Type :: DotnetType ( type_ref) = adt_type_ref {
133
160
type_ref. as_ref ( ) . clone ( )
134
161
} else {
135
162
panic ! ( "Can't get fields of type {adt_type:?}" ) ;
136
163
} ;
137
164
match adt. adt_kind ( ) {
138
165
AdtKind :: Struct => {
139
- let obj_getter =
140
- crate :: place:: place_adress ( target_location, tyctx, method, method_instance) ;
166
+ let obj_getter = crate :: place:: place_adress (
167
+ target_location,
168
+ tyctx,
169
+ method,
170
+ method_instance,
171
+ type_cache,
172
+ ) ;
141
173
let mut ops: Vec < CILOp > = Vec :: with_capacity ( fields. len ( ) * 2 ) ;
142
174
for field in fields {
143
175
ops. extend ( obj_getter. iter ( ) . cloned ( ) ) ;
144
176
ops. extend ( field. 1 ) ;
145
- let field_def = adt
146
- . all_fields ( )
147
- . nth ( field. 0 as usize )
148
- . expect ( "Could not find field!" ) ;
149
- let field_type = field_def. ty ( tyctx, subst) ;
150
-
151
- let field_type = if crate :: utilis:: is_ty_alias ( field_type) {
152
- Type :: from_ty (
153
- crate :: utilis:: monomorphize ( & method_instance, field_type, tyctx) ,
154
- tyctx,
155
- & method_instance,
156
- )
157
- } else {
158
- crate :: utilis:: generic_field_ty ( adt_type, field. 0 , tyctx, method_instance)
159
- } ;
160
- let field_name = field_name ( adt_type, field. 0 ) ;
161
- let field_desc = crate :: cil_op:: FieldDescriptor :: boxed (
162
- adt_type_ref. clone ( ) ,
163
- field_type,
164
- field_name,
177
+ let field_desc = crate :: utilis:: field_descrptor (
178
+ adt_type,
179
+ field. 0 ,
180
+ tyctx,
181
+ method_instance,
182
+ type_cache,
165
183
) ;
166
- ops. push ( CILOp :: STField ( field_desc) ) ;
184
+ ops. push ( CILOp :: STField ( field_desc. into ( ) ) ) ;
167
185
}
168
186
ops. extend ( crate :: place:: place_get (
169
187
target_location,
170
188
tyctx,
171
189
method,
172
190
method_instance,
191
+ type_cache,
173
192
) ) ;
174
193
ops
175
194
}
176
195
AdtKind :: Enum => {
177
- let adt_adress_ops =
178
- crate :: place:: place_adress ( target_location, tyctx, method, method_instance) ;
196
+ let adt_adress_ops = crate :: place:: place_adress (
197
+ target_location,
198
+ tyctx,
199
+ method,
200
+ method_instance,
201
+ type_cache,
202
+ ) ;
179
203
180
204
let mut variant_type = adt_type_ref. clone ( ) ; //adt_type.variant_type(variant).expect("Can't get variant index");
181
205
let variant_name = crate :: utilis:: variant_name ( adt_type, variant_idx) ;
@@ -203,16 +227,15 @@ fn aggregate_adt<'tyctx>(
203
227
ops. extend ( variant_address. clone ( ) ) ;
204
228
ops. extend ( field_value. 1 . clone ( ) ) ;
205
229
let field_name = field. name . to_string ( ) ;
206
- let field_name = crate :: type_def:: escape_field_name ( & field_name) ;
207
- let field = crate :: utilis:: generic_field_ty (
208
- adt_type,
209
- field_idx as u32 ,
230
+ let field_name = crate :: r#type:: escape_field_name ( & field_name) ;
231
+ let field_type = type_cache. type_from_cache (
232
+ field. ty ( tyctx, subst) ,
210
233
tyctx,
211
- method_instance,
234
+ Some ( method_instance) ,
212
235
) ;
213
236
ops. push ( CILOp :: STField ( Box :: new ( FieldDescriptor :: new (
214
237
variant_type. clone ( ) ,
215
- field ,
238
+ field_type ,
216
239
field_name,
217
240
) ) ) ) ;
218
241
}
@@ -233,12 +256,18 @@ fn aggregate_adt<'tyctx>(
233
256
tyctx,
234
257
method,
235
258
method_instance,
259
+ type_cache,
236
260
) ) ;
237
261
ops
238
262
}
239
263
AdtKind :: Union => {
240
- let obj_getter =
241
- crate :: place:: place_adress ( target_location, tyctx, method, method_instance) ;
264
+ let obj_getter = crate :: place:: place_adress (
265
+ target_location,
266
+ tyctx,
267
+ method,
268
+ method_instance,
269
+ type_cache,
270
+ ) ;
242
271
let mut ops: Vec < CILOp > = Vec :: with_capacity ( fields. len ( ) * 2 ) ;
243
272
for field in fields {
244
273
ops. extend ( obj_getter. iter ( ) . cloned ( ) ) ;
@@ -247,23 +276,25 @@ fn aggregate_adt<'tyctx>(
247
276
. all_fields ( )
248
277
. nth ( field. 0 as usize )
249
278
. expect ( "Could not find field!" ) ;
250
- let _field_type = field_def. ty ( tyctx, subst) ;
251
-
279
+ let field_type = field_def. ty ( tyctx, subst) ;
280
+ let field_type = crate :: utilis :: monomorphize ( & method_instance , field_type , tyctx ) ;
252
281
let field_type =
253
- crate :: utilis :: generic_field_ty ( adt_type , field . 0 , tyctx, method_instance) ;
282
+ type_cache . type_from_cache ( field_type , tyctx, Some ( method_instance) ) ;
254
283
let field_name = field_name ( adt_type, field. 0 ) ;
255
284
let field_desc = crate :: cil_op:: FieldDescriptor :: boxed (
256
285
adt_type_ref. clone ( ) ,
257
286
field_type,
258
287
field_name,
259
288
) ;
260
- ops. push ( CILOp :: STField ( field_desc) ) ;
289
+
290
+ ops. push ( CILOp :: STField ( field_desc. into ( ) ) ) ;
261
291
}
262
292
ops. extend ( crate :: place:: place_get (
263
293
target_location,
264
294
tyctx,
265
295
method,
266
296
method_instance,
297
+ type_cache,
267
298
) ) ;
268
299
ops
269
300
}
0 commit comments