Skip to content

Commit 6e0dfc8

Browse files
Refactor using the type-level constant value ty::Value
Signed-off-by: FedericoBruzzone <[email protected]>
1 parent 9e48dfe commit 6e0dfc8

File tree

5 files changed

+62
-59
lines changed

5 files changed

+62
-59
lines changed

compiler/rustc_const_eval/src/const_eval/valtrees.rs

+23-19
Original file line numberDiff line numberDiff line change
@@ -273,59 +273,63 @@ pub(crate) fn eval_to_valtree<'tcx>(
273273
/// Converts a `ValTree` to a `ConstValue`, which is needed after mir
274274
/// construction has finished.
275275
// FIXME(valtrees): Merge `valtree_to_const_value` and `valtree_into_mplace` into one function
276-
// FIXME(valtrees): Accept `ty::Value` instead of `Ty` and `ty::ValTree` separately.
277276
#[instrument(skip(tcx), level = "debug", ret)]
278277
pub fn valtree_to_const_value<'tcx>(
279278
tcx: TyCtxt<'tcx>,
280279
typing_env: ty::TypingEnv<'tcx>,
281-
ty: Ty<'tcx>,
282-
valtree: ty::ValTree<'tcx>,
280+
cv: ty::Value<'tcx>,
283281
) -> mir::ConstValue<'tcx> {
284282
// Basic idea: We directly construct `Scalar` values from trivial `ValTree`s
285283
// (those for constants with type bool, int, uint, float or char).
286284
// For all other types we create an `MPlace` and fill that by walking
287285
// the `ValTree` and using `place_projection` and `place_field` to
288286
// create inner `MPlace`s which are filled recursively.
289-
// FIXME Does this need an example?
290-
match *ty.kind() {
287+
// FIXME: Does this need an example?
288+
match *cv.ty.kind() {
291289
ty::FnDef(..) => {
292-
assert!(valtree.unwrap_branch().is_empty());
290+
assert!(cv.valtree.unwrap_branch().is_empty());
293291
mir::ConstValue::ZeroSized
294292
}
295293
ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char | ty::RawPtr(_, _) => {
296-
match valtree {
294+
match cv.valtree {
297295
ty::ValTree::Leaf(scalar_int) => mir::ConstValue::Scalar(Scalar::Int(scalar_int)),
298296
ty::ValTree::Branch(_) => bug!(
299297
"ValTrees for Bool, Int, Uint, Float, Char or RawPtr should have the form ValTree::Leaf"
300298
),
301299
}
302300
}
303-
ty::Pat(ty, _) => valtree_to_const_value(tcx, typing_env, ty, valtree),
301+
ty::Pat(ty, _) => {
302+
let cv = ty::Value { valtree: cv.valtree, ty };
303+
valtree_to_const_value(tcx, typing_env, cv)
304+
}
304305
ty::Ref(_, inner_ty, _) => {
305306
let mut ecx =
306307
mk_eval_cx_to_read_const_val(tcx, DUMMY_SP, typing_env, CanAccessMutGlobal::No);
307-
let imm = valtree_to_ref(&mut ecx, valtree, inner_ty);
308-
let imm =
309-
ImmTy::from_immediate(imm, tcx.layout_of(typing_env.as_query_input(ty)).unwrap());
308+
let imm = valtree_to_ref(&mut ecx, cv.valtree, inner_ty);
309+
let imm = ImmTy::from_immediate(
310+
imm,
311+
tcx.layout_of(typing_env.as_query_input(cv.ty)).unwrap(),
312+
);
310313
op_to_const(&ecx, &imm.into(), /* for diagnostics */ false)
311314
}
312315
ty::Tuple(_) | ty::Array(_, _) | ty::Adt(..) => {
313-
let layout = tcx.layout_of(typing_env.as_query_input(ty)).unwrap();
316+
let layout = tcx.layout_of(typing_env.as_query_input(cv.ty)).unwrap();
314317
if layout.is_zst() {
315318
// Fast path to avoid some allocations.
316319
return mir::ConstValue::ZeroSized;
317320
}
318321
if layout.backend_repr.is_scalar()
319-
&& (matches!(ty.kind(), ty::Tuple(_))
320-
|| matches!(ty.kind(), ty::Adt(def, _) if def.is_struct()))
322+
&& (matches!(cv.ty.kind(), ty::Tuple(_))
323+
|| matches!(cv.ty.kind(), ty::Adt(def, _) if def.is_struct()))
321324
{
322325
// A Scalar tuple/struct; we can avoid creating an allocation.
323-
let branches = valtree.unwrap_branch();
326+
let branches = cv.valtree.unwrap_branch();
324327
// Find the non-ZST field. (There can be aligned ZST!)
325328
for (i, &inner_valtree) in branches.iter().enumerate() {
326329
let field = layout.field(&LayoutCx::new(tcx, typing_env), i);
327330
if !field.is_zst() {
328-
return valtree_to_const_value(tcx, typing_env, field.ty, inner_valtree);
331+
let cv = ty::Value { valtree: inner_valtree, ty: field.ty };
332+
return valtree_to_const_value(tcx, typing_env, cv);
329333
}
330334
}
331335
bug!("could not find non-ZST field during in {layout:#?}");
@@ -335,9 +339,9 @@ pub fn valtree_to_const_value<'tcx>(
335339
mk_eval_cx_to_read_const_val(tcx, DUMMY_SP, typing_env, CanAccessMutGlobal::No);
336340

337341
// Need to create a place for this valtree.
338-
let place = create_valtree_place(&mut ecx, layout, valtree);
342+
let place = create_valtree_place(&mut ecx, layout, cv.valtree);
339343

340-
valtree_into_mplace(&mut ecx, &place, valtree);
344+
valtree_into_mplace(&mut ecx, &place, cv.valtree);
341345
dump_place(&ecx, &place);
342346
intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &place).unwrap();
343347

@@ -362,7 +366,7 @@ pub fn valtree_to_const_value<'tcx>(
362366
| ty::Slice(_)
363367
| ty::Dynamic(..)
364368
| ty::UnsafeBinder(_) => {
365-
bug!("no ValTree should have been created for type {:?}", ty.kind())
369+
bug!("no ValTree should have been created for type {:?}", cv.ty.kind())
366370
}
367371
}
368372
}

compiler/rustc_const_eval/src/lib.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,8 @@ pub fn provide(providers: &mut Providers) {
4646
};
4747
providers.hooks.try_destructure_mir_constant_for_user_output =
4848
const_eval::try_destructure_mir_constant_for_user_output;
49-
providers.valtree_to_const_val = |tcx, cv| {
50-
const_eval::valtree_to_const_value(
51-
tcx,
52-
ty::TypingEnv::fully_monomorphized(),
53-
cv.ty,
54-
cv.valtree,
55-
)
56-
};
49+
providers.valtree_to_const_val =
50+
|tcx, cv| const_eval::valtree_to_const_value(tcx, ty::TypingEnv::fully_monomorphized(), cv);
5751
providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| {
5852
util::check_validity_requirement(tcx, init_kind, param_env_and_ty)
5953
};

compiler/rustc_middle/src/mir/pretty.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rustc_middle::mir::interpret::{
1212
use rustc_middle::mir::visit::Visitor;
1313
use rustc_middle::mir::*;
1414
use tracing::trace;
15+
use ty::print::PrettyPrinter;
1516

1617
use super::graphviz::write_mir_fn_graphviz;
1718
use crate::mir::interpret::ConstAllocation;
@@ -1429,10 +1430,10 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
14291430
})
14301431
};
14311432

1432-
// FIXME: call pretty_print_const_valtree?
1433-
let fmt_valtree = |valtree: &ty::ValTree<'tcx>| match valtree {
1434-
ty::ValTree::Leaf(leaf) => format!("Leaf({leaf:?})"),
1435-
ty::ValTree::Branch(_) => "Branch(..)".to_string(),
1433+
let fmt_valtree = |cv: &ty::Value<'tcx>| {
1434+
let mut cx = FmtPrinter::new(self.tcx, Namespace::ValueNS);
1435+
cx.pretty_print_const_valtree(*cv, /*print_ty*/ true).unwrap();
1436+
cx.into_buffer()
14361437
};
14371438

14381439
let val = match const_ {
@@ -1442,7 +1443,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
14421443
format!("ty::Unevaluated({}, {:?})", self.tcx.def_path_str(uv.def), uv.args,)
14431444
}
14441445
ty::ConstKind::Value(cv) => {
1445-
format!("ty::Valtree({})", fmt_valtree(&cv.valtree))
1446+
format!("ty::Valtree({})", fmt_valtree(&cv))
14461447
}
14471448
// No `ty::` prefix since we also use this to represent errors from `mir::Unevaluated`.
14481449
ty::ConstKind::Error(_) => "Error".to_string(),

compiler/rustc_middle/src/ty/print/pretty.rs

+30-26
Original file line numberDiff line numberDiff line change
@@ -1485,7 +1485,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
14851485
},
14861486
ty::ConstKind::Param(ParamConst { name, .. }) => p!(write("{}", name)),
14871487
ty::ConstKind::Value(cv) => {
1488-
return self.pretty_print_const_valtree(cv.valtree, cv.ty, print_ty);
1488+
return self.pretty_print_const_valtree(cv, print_ty);
14891489
}
14901490

14911491
ty::ConstKind::Bound(debruijn, bound_var) => {
@@ -1785,48 +1785,49 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
17851785
Ok(())
17861786
}
17871787

1788-
// FIXME(valtrees): Accept `ty::Value` instead of `Ty` and `ty::ValTree` separately.
17891788
fn pretty_print_const_valtree(
17901789
&mut self,
1791-
valtree: ty::ValTree<'tcx>,
1792-
ty: Ty<'tcx>,
1790+
cv: ty::Value<'tcx>,
17931791
print_ty: bool,
17941792
) -> Result<(), PrintError> {
17951793
define_scoped_cx!(self);
17961794

17971795
if self.should_print_verbose() {
1798-
p!(write("ValTree({:?}: ", valtree), print(ty), ")");
1796+
p!(write("ValTree({:?}: ", cv.valtree), print(cv.ty), ")");
17991797
return Ok(());
18001798
}
18011799

18021800
let u8_type = self.tcx().types.u8;
1803-
match (valtree, ty.kind()) {
1801+
match (cv.valtree, cv.ty.kind()) {
18041802
(ty::ValTree::Branch(_), ty::Ref(_, inner_ty, _)) => match inner_ty.kind() {
18051803
ty::Slice(t) if *t == u8_type => {
1806-
let bytes = valtree.try_to_raw_bytes(self.tcx(), ty).unwrap_or_else(|| {
1807-
bug!(
1808-
"expected to convert valtree {:?} to raw bytes for type {:?}",
1809-
valtree,
1810-
t
1811-
)
1812-
});
1804+
let bytes =
1805+
cv.valtree.try_to_raw_bytes(self.tcx(), cv.ty).unwrap_or_else(|| {
1806+
bug!(
1807+
"expected to convert valtree {:?} to raw bytes for type {:?}",
1808+
cv.valtree,
1809+
t
1810+
)
1811+
});
18131812
return self.pretty_print_byte_str(bytes);
18141813
}
18151814
ty::Str => {
1816-
let bytes = valtree.try_to_raw_bytes(self.tcx(), ty).unwrap_or_else(|| {
1817-
bug!("expected to convert valtree to raw bytes for type {:?}", ty)
1818-
});
1815+
let bytes =
1816+
cv.valtree.try_to_raw_bytes(self.tcx(), cv.ty).unwrap_or_else(|| {
1817+
bug!("expected to convert valtree to raw bytes for type {:?}", cv.ty)
1818+
});
18191819
p!(write("{:?}", String::from_utf8_lossy(bytes)));
18201820
return Ok(());
18211821
}
18221822
_ => {
1823+
let cv = ty::Value { valtree: cv.valtree, ty: *inner_ty };
18231824
p!("&");
1824-
p!(pretty_print_const_valtree(valtree, *inner_ty, print_ty));
1825+
p!(pretty_print_const_valtree(cv, print_ty));
18251826
return Ok(());
18261827
}
18271828
},
18281829
(ty::ValTree::Branch(_), ty::Array(t, _)) if *t == u8_type => {
1829-
let bytes = valtree.try_to_raw_bytes(self.tcx(), ty).unwrap_or_else(|| {
1830+
let bytes = cv.valtree.try_to_raw_bytes(self.tcx(), cv.ty).unwrap_or_else(|| {
18301831
bug!("expected to convert valtree to raw bytes for type {:?}", t)
18311832
});
18321833
p!("*");
@@ -1835,10 +1836,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
18351836
}
18361837
// Aggregates, printed as array/tuple/struct/variant construction syntax.
18371838
(ty::ValTree::Branch(_), ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) => {
1838-
let contents =
1839-
self.tcx().destructure_const(ty::Const::new_value(self.tcx(), valtree, ty));
1839+
let contents = self.tcx().destructure_const(ty::Const::new_value(
1840+
self.tcx(),
1841+
cv.valtree,
1842+
cv.ty,
1843+
));
18401844
let fields = contents.fields.iter().copied();
1841-
match *ty.kind() {
1845+
match *cv.ty.kind() {
18421846
ty::Array(..) => {
18431847
p!("[", comma_sep(fields), "]");
18441848
}
@@ -1855,7 +1859,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
18551859
write!(this, "unreachable()")?;
18561860
Ok(())
18571861
},
1858-
|this| this.print_type(ty),
1862+
|this| this.print_type(cv.ty),
18591863
": ",
18601864
)?;
18611865
}
@@ -1892,21 +1896,21 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
18921896
return self.pretty_print_const_scalar_int(leaf, *inner_ty, print_ty);
18931897
}
18941898
(ty::ValTree::Leaf(leaf), _) => {
1895-
return self.pretty_print_const_scalar_int(leaf, ty, print_ty);
1899+
return self.pretty_print_const_scalar_int(leaf, cv.ty, print_ty);
18961900
}
18971901
// FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading
18981902
// their fields instead of just dumping the memory.
18991903
_ => {}
19001904
}
19011905

19021906
// fallback
1903-
if valtree == ty::ValTree::zst() {
1907+
if cv.valtree == ty::ValTree::zst() {
19041908
p!(write("<ZST>"));
19051909
} else {
1906-
p!(write("{:?}", valtree));
1910+
p!(write("{:?}", cv.valtree));
19071911
}
19081912
if print_ty {
1909-
p!(": ", print(ty));
1913+
p!(": ", print(cv.ty));
19101914
}
19111915
Ok(())
19121916
}

compiler/rustc_middle/src/ty/structural_impls.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ impl<'tcx> fmt::Debug for ty::Const<'tcx> {
170170
bug!("we checked that this is a valtree")
171171
};
172172
let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
173-
cx.pretty_print_const_valtree(cv.valtree, cv.ty, /*print_ty*/ true)?;
173+
cx.pretty_print_const_valtree(cv, /*print_ty*/ true)?;
174174
f.write_str(&cx.into_buffer())
175175
});
176176
}

0 commit comments

Comments
 (0)