@@ -189,12 +189,11 @@ fn reconstruct_place_meta<'tcx>(
189
189
}
190
190
191
191
#[ instrument( skip( ecx) , level = "debug" , ret) ]
192
- fn create_pointee_place < ' tcx > (
192
+ fn create_valtree_place < ' tcx > (
193
193
ecx : & mut CompileTimeEvalContext < ' tcx , ' tcx > ,
194
- ty : Ty < ' tcx > ,
194
+ layout : TyAndLayout < ' tcx > ,
195
195
valtree : ty:: ValTree < ' tcx > ,
196
196
) -> MPlaceTy < ' tcx > {
197
- let layout = ecx. layout_of ( ty) . unwrap ( ) ;
198
197
let meta = reconstruct_place_meta ( layout, valtree, ecx. tcx . tcx ) ;
199
198
ecx. allocate_dyn ( layout, MemoryKind :: Stack , meta) . unwrap ( )
200
199
}
@@ -216,11 +215,6 @@ pub fn valtree_to_const_value<'tcx>(
216
215
// FIXME Does this need an example?
217
216
218
217
let ( param_env, ty) = param_env_ty. into_parts ( ) ;
219
- let mut ecx: crate :: interpret:: InterpCx <
220
- ' _ ,
221
- ' _ ,
222
- crate :: const_eval:: CompileTimeInterpreter < ' _ , ' _ > ,
223
- > = mk_eval_cx ( tcx, DUMMY_SP , param_env, CanAccessStatics :: No ) ;
224
218
225
219
match ty. kind ( ) {
226
220
ty:: FnDef ( ..) => {
@@ -233,33 +227,29 @@ pub fn valtree_to_const_value<'tcx>(
233
227
"ValTrees for Bool, Int, Uint, Float or Char should have the form ValTree::Leaf"
234
228
) ,
235
229
} ,
236
- ty:: Ref ( _, _, _) | ty:: Tuple ( _) | ty:: Array ( _, _) | ty:: Adt ( ..) => {
237
- let place = match ty. kind ( ) {
238
- ty:: Ref ( _, inner_ty, _) => {
239
- // Need to create a place for the pointee (the reference itself will be an immediate)
240
- create_pointee_place ( & mut ecx, * inner_ty, valtree)
241
- }
242
- _ => {
243
- // Need to create a place for this valtree.
244
- create_pointee_place ( & mut ecx, ty, valtree)
245
- }
246
- } ;
247
- debug ! ( ?place) ;
230
+ ty:: Ref ( _, inner_ty, _) => {
231
+ let mut ecx = mk_eval_cx ( tcx, DUMMY_SP , param_env, CanAccessStatics :: No ) ;
232
+ let imm = valtree_to_ref ( & mut ecx, valtree, * inner_ty) ;
233
+ let imm = ImmTy :: from_immediate ( imm, tcx. layout_of ( param_env_ty) . unwrap ( ) ) ;
234
+ op_to_const ( & ecx, & imm. into ( ) )
235
+ }
236
+ ty:: Tuple ( _) | ty:: Array ( _, _) | ty:: Adt ( ..) => {
237
+ let layout = tcx. layout_of ( param_env_ty) . unwrap ( ) ;
238
+ if layout. is_zst ( ) {
239
+ // Fast path to avoid some allocations.
240
+ return ConstValue :: ZeroSized ;
241
+ }
242
+
243
+ let mut ecx = mk_eval_cx ( tcx, DUMMY_SP , param_env, CanAccessStatics :: No ) ;
244
+
245
+ // Need to create a place for this valtree.
246
+ let place = create_valtree_place ( & mut ecx, layout, valtree) ;
248
247
249
248
valtree_into_mplace ( & mut ecx, & place, valtree) ;
250
249
dump_place ( & ecx, & place) ;
251
250
intern_const_alloc_recursive ( & mut ecx, InternKind :: Constant , & place) . unwrap ( ) ;
252
251
253
- match ty. kind ( ) {
254
- ty:: Ref ( _, _, _) => {
255
- let ref_place = place. to_ref ( & tcx) ;
256
- let imm =
257
- ImmTy :: from_immediate ( ref_place, tcx. layout_of ( param_env_ty) . unwrap ( ) ) ;
258
-
259
- op_to_const ( & ecx, & imm. into ( ) )
260
- }
261
- _ => op_to_const ( & ecx, & place. into ( ) ) ,
262
- }
252
+ op_to_const ( & ecx, & place. into ( ) )
263
253
}
264
254
ty:: Never
265
255
| ty:: Error ( _)
@@ -283,6 +273,22 @@ pub fn valtree_to_const_value<'tcx>(
283
273
}
284
274
}
285
275
276
+ /// Put a valtree into memory and return a reference to that.
277
+ fn valtree_to_ref < ' tcx > (
278
+ ecx : & mut CompileTimeEvalContext < ' tcx , ' tcx > ,
279
+ valtree : ty:: ValTree < ' tcx > ,
280
+ pointee_ty : Ty < ' tcx > ,
281
+ ) -> Immediate {
282
+ let pointee_place = create_valtree_place ( ecx, ecx. layout_of ( pointee_ty) . unwrap ( ) , valtree) ;
283
+ debug ! ( ?pointee_place) ;
284
+
285
+ valtree_into_mplace ( ecx, & pointee_place, valtree) ;
286
+ dump_place ( ecx, & pointee_place) ;
287
+ intern_const_alloc_recursive ( ecx, InternKind :: Constant , & pointee_place) . unwrap ( ) ;
288
+
289
+ pointee_place. to_ref ( & ecx. tcx )
290
+ }
291
+
286
292
#[ instrument( skip( ecx) , level = "debug" ) ]
287
293
fn valtree_into_mplace < ' tcx > (
288
294
ecx : & mut CompileTimeEvalContext < ' tcx , ' tcx > ,
@@ -292,7 +298,6 @@ fn valtree_into_mplace<'tcx>(
292
298
// This will match on valtree and write the value(s) corresponding to the ValTree
293
299
// inside the place recursively.
294
300
295
- let tcx = ecx. tcx . tcx ;
296
301
let ty = place. layout . ty ;
297
302
298
303
match ty. kind ( ) {
@@ -305,27 +310,8 @@ fn valtree_into_mplace<'tcx>(
305
310
ecx. write_immediate ( Immediate :: Scalar ( scalar_int. into ( ) ) , place) . unwrap ( ) ;
306
311
}
307
312
ty:: Ref ( _, inner_ty, _) => {
308
- let pointee_place = create_pointee_place ( ecx, * inner_ty, valtree) ;
309
- debug ! ( ?pointee_place) ;
310
-
311
- valtree_into_mplace ( ecx, & pointee_place, valtree) ;
312
- dump_place ( ecx, & pointee_place) ;
313
- intern_const_alloc_recursive ( ecx, InternKind :: Constant , & pointee_place) . unwrap ( ) ;
314
-
315
- let imm = match inner_ty. kind ( ) {
316
- ty:: Slice ( _) | ty:: Str => {
317
- let len = valtree. unwrap_branch ( ) . len ( ) ;
318
- let len_scalar = Scalar :: from_target_usize ( len as u64 , & tcx) ;
319
-
320
- Immediate :: ScalarPair (
321
- Scalar :: from_maybe_pointer ( pointee_place. ptr ( ) , & tcx) ,
322
- len_scalar,
323
- )
324
- }
325
- _ => pointee_place. to_ref ( & tcx) ,
326
- } ;
313
+ let imm = valtree_to_ref ( ecx, valtree, * inner_ty) ;
327
314
debug ! ( ?imm) ;
328
-
329
315
ecx. write_immediate ( imm, place) . unwrap ( ) ;
330
316
}
331
317
ty:: Adt ( _, _) | ty:: Tuple ( _) | ty:: Array ( _, _) | ty:: Str | ty:: Slice ( _) => {
0 commit comments