Skip to content

Commit 562c507

Browse files
committed
Make ValTree recurse through ty::Const
1 parent d5ae178 commit 562c507

File tree

28 files changed

+218
-100
lines changed

28 files changed

+218
-100
lines changed

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ use rustc_hir::def_id::LOCAL_CRATE;
1313
use rustc_hir::{self as hir};
1414
use rustc_middle::mir::BinOp;
1515
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf};
16-
use rustc_middle::ty::{self, GenericArgsRef, Instance, SimdAlign, Ty, TyCtxt, TypingEnv};
16+
use rustc_middle::ty::{
17+
self, GenericArgsRef, Instance, SimdAlign, Ty, TyCtxt, TypingEnv, ValTreeKindExt,
18+
};
1719
use rustc_middle::{bug, span_bug};
1820
use rustc_span::{Span, Symbol, sym};
1921
use rustc_symbol_mangling::{mangle_internal_symbol, symbol_name_for_instance_in_crate};
@@ -1459,7 +1461,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
14591461
.iter()
14601462
.enumerate()
14611463
.map(|(arg_idx, val)| {
1462-
let idx = val.unwrap_leaf().to_i32();
1464+
let idx = val.to_value().valtree.unwrap_leaf().to_i32();
14631465
if idx >= i32::try_from(total_len).unwrap() {
14641466
bx.sess().dcx().emit_err(InvalidMonomorphization::SimdIndexOutOfBounds {
14651467
span,
@@ -1857,6 +1859,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
18571859
// The memory addresses corresponding to the “off” lanes are not accessed.
18581860

18591861
let alignment = fn_args[3].expect_const().to_value().valtree.unwrap_branch()[0]
1862+
.to_value()
1863+
.valtree
18601864
.unwrap_leaf()
18611865
.to_simd_alignment();
18621866

@@ -1952,6 +1956,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
19521956
// The memory addresses corresponding to the “off” lanes are not accessed.
19531957

19541958
let alignment = fn_args[3].expect_const().to_value().valtree.unwrap_branch()[0]
1959+
.to_value()
1960+
.valtree
19551961
.unwrap_leaf()
19561962
.to_simd_alignment();
19571963

compiler/rustc_codegen_ssa/src/mir/constant.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use rustc_abi::BackendRepr;
22
use rustc_middle::mir::interpret::ErrorHandled;
33
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv};
4-
use rustc_middle::ty::{self, Ty};
4+
use rustc_middle::ty::{self, Ty, ValTreeKindExt};
55
use rustc_middle::{bug, mir, span_bug};
66

77
use super::FunctionCx;
@@ -79,12 +79,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
7979
// A SIMD type has a single field, which is an array.
8080
let fields = val.unwrap_branch();
8181
assert_eq!(fields.len(), 1);
82-
let array = fields[0].unwrap_branch();
82+
let array = fields[0].to_value().valtree.unwrap_branch();
8383
// Iterate over the array elements to obtain the values in the vector.
8484
let values: Vec<_> = array
8585
.iter()
8686
.map(|field| {
87-
if let Some(prim) = field.try_to_scalar() {
87+
if let Some(prim) = field.to_value().valtree.try_to_scalar() {
8888
let layout = bx.layout_of(field_ty);
8989
let BackendRepr::Scalar(scalar) = layout.backend_repr else {
9090
bug!("from_const: invalid ByVal layout: {:#?}", layout);

compiler/rustc_codegen_ssa/src/mir/intrinsic.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_abi::WrappingRange;
22
use rustc_middle::mir::SourceInfo;
3-
use rustc_middle::ty::{self, Ty, TyCtxt};
3+
use rustc_middle::ty::{self, Ty, TyCtxt, ValTreeKindExt};
44
use rustc_middle::{bug, span_bug};
55
use rustc_session::config::OptLevel;
66
use rustc_span::sym;
@@ -102,7 +102,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
102102
};
103103

104104
let parse_atomic_ordering = |ord: ty::Value<'tcx>| {
105-
let discr = ord.valtree.unwrap_branch()[0].unwrap_leaf();
105+
let discr = ord.valtree.unwrap_branch()[0].to_value().valtree.unwrap_leaf();
106106
discr.to_atomic_ordering()
107107
};
108108

compiler/rustc_const_eval/src/const_eval/valtrees.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
33
use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId, ValTreeCreationError};
44
use rustc_middle::traits::ObligationCause;
55
use rustc_middle::ty::layout::{LayoutCx, TyAndLayout};
6-
use rustc_middle::ty::{self, Ty, TyCtxt};
6+
use rustc_middle::ty::{self, Ty, TyCtxt, ValTreeKindExt};
77
use rustc_middle::{bug, mir};
88
use rustc_span::DUMMY_SP;
99
use tracing::{debug, instrument, trace};
@@ -36,13 +36,17 @@ fn branches<'tcx>(
3636
// For enums, we prepend their variant index before the variant's fields so we can figure out
3737
// the variant again when just seeing a valtree.
3838
if let Some(variant) = variant {
39-
branches.push(ty::ValTree::from_scalar_int(*ecx.tcx, variant.as_u32().into()));
39+
branches.push(ty::Const::new_value(
40+
*ecx.tcx,
41+
ty::ValTree::from_scalar_int(*ecx.tcx, variant.as_u32().into()),
42+
ecx.tcx.types.u32,
43+
));
4044
}
4145

4246
for i in 0..field_count {
4347
let field = ecx.project_field(&place, FieldIdx::from_usize(i)).unwrap();
4448
let valtree = const_to_valtree_inner(ecx, &field, num_nodes)?;
45-
branches.push(valtree);
49+
branches.push(ty::Const::new_value(*ecx.tcx, valtree, field.layout.ty));
4650
}
4751

4852
// Have to account for ZSTs here
@@ -65,7 +69,7 @@ fn slice_branches<'tcx>(
6569
for i in 0..n {
6670
let place_elem = ecx.project_index(place, i).unwrap();
6771
let valtree = const_to_valtree_inner(ecx, &place_elem, num_nodes)?;
68-
elems.push(valtree);
72+
elems.push(ty::Const::new_value(*ecx.tcx, valtree, place_elem.layout.ty));
6973
}
7074

7175
Ok(ty::ValTree::from_branches(*ecx.tcx, elems))
@@ -201,7 +205,7 @@ fn reconstruct_place_meta<'tcx>(
201205
|ty| ty,
202206
|| {
203207
let branches = last_valtree.unwrap_branch();
204-
last_valtree = *branches.last().unwrap();
208+
last_valtree = branches.last().unwrap().to_value().valtree;
205209
debug!(?branches, ?last_valtree);
206210
},
207211
);
@@ -306,7 +310,8 @@ pub fn valtree_to_const_value<'tcx>(
306310
for (i, &inner_valtree) in branches.iter().enumerate() {
307311
let field = layout.field(&LayoutCx::new(tcx, typing_env), i);
308312
if !field.is_zst() {
309-
let cv = ty::Value { valtree: inner_valtree, ty: field.ty };
313+
let cv =
314+
ty::Value { valtree: inner_valtree.to_value().valtree, ty: field.ty };
310315
return valtree_to_const_value(tcx, typing_env, cv);
311316
}
312317
}
@@ -397,7 +402,7 @@ fn valtree_into_mplace<'tcx>(
397402
let (place_adjusted, branches, variant_idx) = match ty.kind() {
398403
ty::Adt(def, _) if def.is_enum() => {
399404
// First element of valtree corresponds to variant
400-
let scalar_int = branches[0].unwrap_leaf();
405+
let scalar_int = branches[0].to_value().valtree.unwrap_leaf();
401406
let variant_idx = VariantIdx::from_u32(scalar_int.to_u32());
402407
let variant = def.variant(variant_idx);
403408
debug!(?variant);
@@ -425,7 +430,7 @@ fn valtree_into_mplace<'tcx>(
425430
};
426431

427432
debug!(?place_inner);
428-
valtree_into_mplace(ecx, &place_inner, *inner_valtree);
433+
valtree_into_mplace(ecx, &place_inner, inner_valtree.to_value().valtree);
429434
dump_place(ecx, &place_inner);
430435
}
431436

compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc_abi::{BackendRepr, Endian};
33
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
44
use rustc_apfloat::{Float, Round};
55
use rustc_middle::mir::interpret::{InterpErrorKind, Pointer, UndefinedBehaviorInfo};
6-
use rustc_middle::ty::{FloatTy, ScalarInt, SimdAlign};
6+
use rustc_middle::ty::{FloatTy, ScalarInt, SimdAlign, ValTreeKindExt};
77
use rustc_middle::{bug, err_ub_format, mir, span_bug, throw_unsup_format, ty};
88
use rustc_span::{Symbol, sym};
99
use tracing::trace;
@@ -552,8 +552,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
552552
assert_eq!(u64::try_from(index_len).unwrap(), dest_len);
553553

554554
for i in 0..dest_len {
555-
let src_index: u64 =
556-
index[usize::try_from(i).unwrap()].unwrap_leaf().to_u32().into();
555+
let src_index: u64 = index[usize::try_from(i).unwrap()]
556+
.to_value()
557+
.valtree
558+
.unwrap_leaf()
559+
.to_u32()
560+
.into();
557561
let dest = self.project_index(&dest, i)?;
558562

559563
let val = if src_index < left_len {
@@ -658,6 +662,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
658662
ptr,
659663
dest_layout,
660664
generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0]
665+
.to_value()
666+
.valtree
661667
.unwrap_leaf()
662668
.to_simd_alignment(),
663669
)?;
@@ -690,6 +696,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
690696
ptr,
691697
args[2].layout,
692698
generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0]
699+
.to_value()
700+
.valtree
693701
.unwrap_leaf()
694702
.to_simd_alignment(),
695703
)?;

compiler/rustc_middle/src/mir/consts.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use super::interpret::ReportedErrorInfo;
1212
use crate::mir::interpret::{AllocId, AllocRange, ErrorHandled, GlobalAlloc, Scalar, alloc_range};
1313
use crate::mir::{Promoted, pretty_print_const_value};
1414
use crate::ty::print::{pretty_print_const, with_no_trimmed_paths};
15-
use crate::ty::{self, ConstKind, GenericArgsRef, ScalarInt, Ty, TyCtxt};
15+
use crate::ty::{self, ConstKind, GenericArgsRef, ScalarInt, Ty, TyCtxt, ValTreeKindExt};
1616

1717
///////////////////////////////////////////////////////////////////////////
1818
/// Evaluated Constants

compiler/rustc_middle/src/thir.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use crate::ty::adjustment::PointerCoercion;
3333
use crate::ty::layout::IntegerExt;
3434
use crate::ty::{
3535
self, AdtDef, CanonicalUserType, CanonicalUserTypeAnnotation, FnSig, GenericArgsRef, Ty,
36-
TyCtxt, UpvarArgs,
36+
TyCtxt, UpvarArgs, ValTreeKindExt,
3737
};
3838

3939
pub mod visit;

compiler/rustc_middle/src/ty/consts/valtree.rs

Lines changed: 37 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,74 +3,45 @@ use std::ops::Deref;
33

44
use rustc_data_structures::intern::Interned;
55
use rustc_hir::def::Namespace;
6-
use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
6+
use rustc_macros::{
7+
HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, extension,
8+
};
79

810
use super::ScalarInt;
911
use crate::mir::interpret::{ErrorHandled, Scalar};
1012
use crate::ty::print::{FmtPrinter, PrettyPrinter};
1113
use crate::ty::{self, Ty, TyCtxt};
1214

13-
/// This datastructure is used to represent the value of constants used in the type system.
14-
///
15-
/// We explicitly choose a different datastructure from the way values are processed within
16-
/// CTFE, as in the type system equal values (according to their `PartialEq`) must also have
17-
/// equal representation (`==` on the rustc data structure, e.g. `ValTree`) and vice versa.
18-
/// Since CTFE uses `AllocId` to represent pointers, it often happens that two different
19-
/// `AllocId`s point to equal values. So we may end up with different representations for
20-
/// two constants whose value is `&42`. Furthermore any kind of struct that has padding will
21-
/// have arbitrary values within that padding, even if the values of the struct are the same.
22-
///
23-
/// `ValTree` does not have this problem with representation, as it only contains integers or
24-
/// lists of (nested) `ValTree`.
25-
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
26-
#[derive(HashStable, TyEncodable, TyDecodable)]
27-
pub enum ValTreeKind<'tcx> {
28-
/// integers, `bool`, `char` are represented as scalars.
29-
/// See the `ScalarInt` documentation for how `ScalarInt` guarantees that equal values
30-
/// of these types have the same representation.
31-
Leaf(ScalarInt),
32-
33-
//SliceOrStr(ValSlice<'tcx>),
34-
// don't use SliceOrStr for now
35-
/// The fields of any kind of aggregate. Structs, tuples and arrays are represented by
36-
/// listing their fields' values in order.
37-
///
38-
/// Enums are represented by storing their variant index as a u32 field, followed by all
39-
/// the fields of the variant.
40-
///
41-
/// ZST types are represented as an empty slice.
42-
Branch(Box<[ValTree<'tcx>]>),
43-
}
44-
45-
impl<'tcx> ValTreeKind<'tcx> {
15+
#[extension(pub trait ValTreeKindExt<'tcx>)]
16+
impl<'tcx> ty::ValTreeKind<TyCtxt<'tcx>> {
4617
#[inline]
47-
pub fn unwrap_leaf(&self) -> ScalarInt {
18+
fn unwrap_leaf(&self) -> ScalarInt {
4819
match self {
4920
Self::Leaf(s) => *s,
5021
_ => bug!("expected leaf, got {:?}", self),
5122
}
5223
}
5324

5425
#[inline]
55-
pub fn unwrap_branch(&self) -> &[ValTree<'tcx>] {
26+
fn unwrap_branch(&self) -> &[ty::Const<'tcx>] {
5627
match self {
5728
Self::Branch(branch) => &**branch,
5829
_ => bug!("expected branch, got {:?}", self),
5930
}
6031
}
6132

62-
pub fn try_to_scalar(&self) -> Option<Scalar> {
33+
fn try_to_scalar(&self) -> Option<Scalar> {
6334
self.try_to_scalar_int().map(Scalar::Int)
6435
}
6536

66-
pub fn try_to_scalar_int(&self) -> Option<ScalarInt> {
37+
fn try_to_scalar_int(&self) -> Option<ScalarInt> {
6738
match self {
6839
Self::Leaf(s) => Some(*s),
6940
Self::Branch(_) => None,
7041
}
7142
}
7243

73-
pub fn try_to_branch(&self) -> Option<&[ValTree<'tcx>]> {
44+
fn try_to_branch(&self) -> Option<&[ty::Const<'tcx>]> {
7445
match self {
7546
Self::Branch(branch) => Some(&**branch),
7647
Self::Leaf(_) => None,
@@ -85,7 +56,13 @@ impl<'tcx> ValTreeKind<'tcx> {
8556
/// [dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html#valtrees
8657
#[derive(Copy, Clone, Hash, Eq, PartialEq)]
8758
#[derive(HashStable)]
88-
pub struct ValTree<'tcx>(pub(crate) Interned<'tcx, ValTreeKind<'tcx>>);
59+
pub struct ValTree<'tcx>(pub(crate) Interned<'tcx, ty::ValTreeKind<TyCtxt<'tcx>>>);
60+
61+
impl<'tcx> rustc_type_ir::inherent::ValTree<TyCtxt<'tcx>> for ValTree<'tcx> {
62+
fn kind(&self) -> &ty::ValTreeKind<TyCtxt<'tcx>> {
63+
&self
64+
}
65+
}
8966

9067
impl<'tcx> ValTree<'tcx> {
9168
/// Returns the zero-sized valtree: `Branch([])`.
@@ -94,28 +71,33 @@ impl<'tcx> ValTree<'tcx> {
9471
}
9572

9673
pub fn is_zst(self) -> bool {
97-
matches!(*self, ValTreeKind::Branch(box []))
74+
matches!(*self, ty::ValTreeKind::Branch(box []))
9875
}
9976

10077
pub fn from_raw_bytes(tcx: TyCtxt<'tcx>, bytes: &[u8]) -> Self {
101-
let branches = bytes.iter().map(|&b| Self::from_scalar_int(tcx, b.into()));
78+
let branches = bytes.iter().map(|&b| {
79+
ty::Const::new_value(tcx, Self::from_scalar_int(tcx, b.into()), tcx.types.u8)
80+
});
10281
Self::from_branches(tcx, branches)
10382
}
10483

105-
pub fn from_branches(tcx: TyCtxt<'tcx>, branches: impl IntoIterator<Item = Self>) -> Self {
106-
tcx.intern_valtree(ValTreeKind::Branch(branches.into_iter().collect()))
84+
pub fn from_branches(
85+
tcx: TyCtxt<'tcx>,
86+
branches: impl IntoIterator<Item = ty::Const<'tcx>>,
87+
) -> Self {
88+
tcx.intern_valtree(ty::ValTreeKind::Branch(branches.into_iter().collect()))
10789
}
10890

10991
pub fn from_scalar_int(tcx: TyCtxt<'tcx>, i: ScalarInt) -> Self {
110-
tcx.intern_valtree(ValTreeKind::Leaf(i))
92+
tcx.intern_valtree(ty::ValTreeKind::Leaf(i))
11193
}
11294
}
11395

11496
impl<'tcx> Deref for ValTree<'tcx> {
115-
type Target = &'tcx ValTreeKind<'tcx>;
97+
type Target = &'tcx ty::ValTreeKind<TyCtxt<'tcx>>;
11698

11799
#[inline]
118-
fn deref(&self) -> &&'tcx ValTreeKind<'tcx> {
100+
fn deref(&self) -> &&'tcx ty::ValTreeKind<TyCtxt<'tcx>> {
119101
&self.0.0
120102
}
121103
}
@@ -192,9 +174,14 @@ impl<'tcx> Value<'tcx> {
192174
_ => return None,
193175
}
194176

195-
Some(tcx.arena.alloc_from_iter(
196-
self.valtree.unwrap_branch().into_iter().map(|v| v.unwrap_leaf().to_u8()),
197-
))
177+
Some(
178+
tcx.arena.alloc_from_iter(
179+
self.valtree
180+
.unwrap_branch()
181+
.into_iter()
182+
.map(|ct| ct.to_value().valtree.unwrap_leaf().to_u8()),
183+
),
184+
)
198185
}
199186
}
200187

compiler/rustc_middle/src/ty/context.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
165165
type ValueConst = ty::Value<'tcx>;
166166
type ExprConst = ty::Expr<'tcx>;
167167
type ValTree = ty::ValTree<'tcx>;
168+
type ScalarInt = ty::ScalarInt;
168169

169170
type Region = Region<'tcx>;
170171
type EarlyParamRegion = ty::EarlyParamRegion;
@@ -954,7 +955,7 @@ pub struct CtxtInterners<'tcx> {
954955
fields: InternedSet<'tcx, List<FieldIdx>>,
955956
local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
956957
captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
957-
valtree: InternedSet<'tcx, ty::ValTreeKind<'tcx>>,
958+
valtree: InternedSet<'tcx, ty::ValTreeKind<TyCtxt<'tcx>>>,
958959
patterns: InternedSet<'tcx, List<ty::Pattern<'tcx>>>,
959960
outlives: InternedSet<'tcx, List<ty::ArgOutlivesPredicate<'tcx>>>,
960961
}
@@ -2789,7 +2790,7 @@ macro_rules! direct_interners {
27892790
// crate only, and have a corresponding `mk_` function.
27902791
direct_interners! {
27912792
region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
2792-
valtree: pub(crate) intern_valtree(ValTreeKind<'tcx>): ValTree -> ValTree<'tcx>,
2793+
valtree: pub(crate) intern_valtree(ValTreeKind<TyCtxt<'tcx>>): ValTree -> ValTree<'tcx>,
27932794
pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>,
27942795
const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
27952796
layout: pub mk_layout(LayoutData<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,

0 commit comments

Comments
 (0)