Skip to content

Commit ae341f7

Browse files
committed
add ZST fast path to valtree_to_const_value
also factor some repeated code into a helper function
1 parent 08b5813 commit ae341f7

File tree

1 file changed

+37
-51
lines changed

1 file changed

+37
-51
lines changed

compiler/rustc_const_eval/src/const_eval/valtrees.rs

Lines changed: 37 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,11 @@ fn reconstruct_place_meta<'tcx>(
189189
}
190190

191191
#[instrument(skip(ecx), level = "debug", ret)]
192-
fn create_pointee_place<'tcx>(
192+
fn create_valtree_place<'tcx>(
193193
ecx: &mut CompileTimeEvalContext<'tcx, 'tcx>,
194-
ty: Ty<'tcx>,
194+
layout: TyAndLayout<'tcx>,
195195
valtree: ty::ValTree<'tcx>,
196196
) -> MPlaceTy<'tcx> {
197-
let layout = ecx.layout_of(ty).unwrap();
198197
let meta = reconstruct_place_meta(layout, valtree, ecx.tcx.tcx);
199198
ecx.allocate_dyn(layout, MemoryKind::Stack, meta).unwrap()
200199
}
@@ -216,11 +215,6 @@ pub fn valtree_to_const_value<'tcx>(
216215
// FIXME Does this need an example?
217216

218217
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);
224218

225219
match ty.kind() {
226220
ty::FnDef(..) => {
@@ -233,33 +227,29 @@ pub fn valtree_to_const_value<'tcx>(
233227
"ValTrees for Bool, Int, Uint, Float or Char should have the form ValTree::Leaf"
234228
),
235229
},
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);
248247

249248
valtree_into_mplace(&mut ecx, &place, valtree);
250249
dump_place(&ecx, &place);
251250
intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &place).unwrap();
252251

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())
263253
}
264254
ty::Never
265255
| ty::Error(_)
@@ -283,6 +273,22 @@ pub fn valtree_to_const_value<'tcx>(
283273
}
284274
}
285275

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+
286292
#[instrument(skip(ecx), level = "debug")]
287293
fn valtree_into_mplace<'tcx>(
288294
ecx: &mut CompileTimeEvalContext<'tcx, 'tcx>,
@@ -292,7 +298,6 @@ fn valtree_into_mplace<'tcx>(
292298
// This will match on valtree and write the value(s) corresponding to the ValTree
293299
// inside the place recursively.
294300

295-
let tcx = ecx.tcx.tcx;
296301
let ty = place.layout.ty;
297302

298303
match ty.kind() {
@@ -305,27 +310,8 @@ fn valtree_into_mplace<'tcx>(
305310
ecx.write_immediate(Immediate::Scalar(scalar_int.into()), place).unwrap();
306311
}
307312
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);
327314
debug!(?imm);
328-
329315
ecx.write_immediate(imm, place).unwrap();
330316
}
331317
ty::Adt(_, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Str | ty::Slice(_) => {

0 commit comments

Comments
 (0)