Skip to content

Commit b937072

Browse files
committed
misc valtree
1 parent 4999b34 commit b937072

File tree

21 files changed

+217
-173
lines changed

21 files changed

+217
-173
lines changed

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ use rustc_hir::{self as hir};
1414
use rustc_middle::mir::BinOp;
1515
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf};
1616
use rustc_middle::ty::offload_meta::OffloadMetadata;
17-
use rustc_middle::ty::{
18-
self, GenericArgsRef, Instance, SimdAlign, Ty, TyCtxt, TypingEnv, ValTreeKindExt,
19-
};
17+
use rustc_middle::ty::{self, GenericArgsRef, Instance, SimdAlign, Ty, TyCtxt, TypingEnv};
2018
use rustc_middle::{bug, span_bug};
2119
use rustc_session::config::CrateType;
2220
use rustc_span::{Span, Symbol, sym};
@@ -353,7 +351,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
353351
_ => bug!(),
354352
};
355353
let ptr = args[0].immediate();
356-
let locality = fn_args.const_at(1).to_value().valtree.unwrap_leaf().to_i32();
354+
let locality = fn_args.const_at(1).to_leaf().to_i32();
357355
self.call_intrinsic(
358356
"llvm.prefetch",
359357
&[self.val_ty(ptr)],
@@ -1538,7 +1536,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
15381536
}
15391537

15401538
if name == sym::simd_shuffle_const_generic {
1541-
let idx = fn_args[2].expect_const().to_value().valtree.unwrap_branch();
1539+
let idx = fn_args[2].expect_const().to_branch();
15421540
let n = idx.len() as u64;
15431541

15441542
let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn);
@@ -1557,7 +1555,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
15571555
.iter()
15581556
.enumerate()
15591557
.map(|(arg_idx, val)| {
1560-
let idx = val.to_value().valtree.unwrap_leaf().to_i32();
1558+
let idx = val.to_leaf().to_i32();
15611559
if idx >= i32::try_from(total_len).unwrap() {
15621560
bx.sess().dcx().emit_err(InvalidMonomorphization::SimdIndexOutOfBounds {
15631561
span,
@@ -1969,11 +1967,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
19691967
// those lanes whose `mask` bit is enabled.
19701968
// The memory addresses corresponding to the “off” lanes are not accessed.
19711969

1972-
let alignment = fn_args[3].expect_const().to_value().valtree.unwrap_branch()[0]
1973-
.to_value()
1974-
.valtree
1975-
.unwrap_leaf()
1976-
.to_simd_alignment();
1970+
let alignment = fn_args[3].expect_const().to_branch()[0].to_leaf().to_simd_alignment();
19771971

19781972
// The element type of the "mask" argument must be a signed integer type of any width
19791973
let mask_ty = in_ty;
@@ -2066,11 +2060,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
20662060
// those lanes whose `mask` bit is enabled.
20672061
// The memory addresses corresponding to the “off” lanes are not accessed.
20682062

2069-
let alignment = fn_args[3].expect_const().to_value().valtree.unwrap_branch()[0]
2070-
.to_value()
2071-
.valtree
2072-
.unwrap_leaf()
2073-
.to_simd_alignment();
2063+
let alignment = fn_args[3].expect_const().to_branch()[0].to_leaf().to_simd_alignment();
20742064

20752065
// The element type of the "mask" argument must be a signed integer type of any width
20762066
let mask_ty = in_ty;

compiler/rustc_codegen_ssa/src/mir/constant.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
7777
.flatten()
7878
.map(|val| {
7979
// A SIMD type has a single field, which is an array.
80-
let fields = val.unwrap_branch();
80+
let fields = val.to_branch();
8181
assert_eq!(fields.len(), 1);
82-
let array = fields[0].to_value().valtree.unwrap_branch();
82+
let array = fields[0].to_branch();
8383
// Iterate over the array elements to obtain the values in the vector.
8484
let values: Vec<_> = array
8585
.iter()

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, ValTreeKindExt};
3+
use rustc_middle::ty::{self, Ty, TyCtxt};
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].to_value().valtree.unwrap_leaf();
105+
let discr = ord.to_branch()[0].to_leaf();
106106
discr.to_atomic_ordering()
107107
};
108108

compiler/rustc_const_eval/src/const_eval/valtrees.rs

Lines changed: 8 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, ValTreeKindExt};
6+
use rustc_middle::ty::{self, Ty, TyCtxt};
77
use rustc_middle::{bug, mir};
88
use rustc_span::DUMMY_SP;
99
use tracing::{debug, instrument, trace};
@@ -204,7 +204,7 @@ fn reconstruct_place_meta<'tcx>(
204204
&ObligationCause::dummy(),
205205
|ty| ty,
206206
|| {
207-
let branches = last_valtree.unwrap_branch();
207+
let branches = last_valtree.to_branch();
208208
last_valtree = branches.last().unwrap().to_value().valtree;
209209
debug!(?branches, ?last_valtree);
210210
},
@@ -216,7 +216,7 @@ fn reconstruct_place_meta<'tcx>(
216216
};
217217

218218
// Get the number of elements in the unsized field.
219-
let num_elems = last_valtree.unwrap_branch().len();
219+
let num_elems = last_valtree.to_branch().len();
220220
MemPlaceMeta::Meta(Scalar::from_target_usize(num_elems as u64, &tcx))
221221
}
222222

@@ -278,7 +278,7 @@ pub fn valtree_to_const_value<'tcx>(
278278
mir::ConstValue::ZeroSized
279279
}
280280
ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char | ty::RawPtr(_, _) => {
281-
mir::ConstValue::Scalar(Scalar::Int(cv.valtree.unwrap_leaf()))
281+
mir::ConstValue::Scalar(Scalar::Int(cv.to_leaf()))
282282
}
283283
ty::Pat(ty, _) => {
284284
let cv = ty::Value { valtree: cv.valtree, ty };
@@ -305,7 +305,7 @@ pub fn valtree_to_const_value<'tcx>(
305305
|| matches!(cv.ty.kind(), ty::Adt(def, _) if def.is_struct()))
306306
{
307307
// A Scalar tuple/struct; we can avoid creating an allocation.
308-
let branches = cv.valtree.unwrap_branch();
308+
let branches = cv.to_branch();
309309
// Find the non-ZST field. (There can be aligned ZST!)
310310
for (i, &inner_valtree) in branches.iter().enumerate() {
311311
let field = layout.field(&LayoutCx::new(tcx, typing_env), i);
@@ -386,7 +386,7 @@ fn valtree_into_mplace<'tcx>(
386386
// Zero-sized type, nothing to do.
387387
}
388388
ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char | ty::RawPtr(..) => {
389-
let scalar_int = valtree.unwrap_leaf();
389+
let scalar_int = valtree.to_leaf();
390390
debug!("writing trivial valtree {:?} to place {:?}", scalar_int, place);
391391
ecx.write_immediate(Immediate::Scalar(scalar_int.into()), place).unwrap();
392392
}
@@ -396,13 +396,13 @@ fn valtree_into_mplace<'tcx>(
396396
ecx.write_immediate(imm, place).unwrap();
397397
}
398398
ty::Adt(_, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Str | ty::Slice(_) => {
399-
let branches = valtree.unwrap_branch();
399+
let branches = valtree.to_branch();
400400

401401
// Need to downcast place for enums
402402
let (place_adjusted, branches, variant_idx) = match ty.kind() {
403403
ty::Adt(def, _) if def.is_enum() => {
404404
// First element of valtree corresponds to variant
405-
let scalar_int = branches[0].to_value().valtree.unwrap_leaf();
405+
let scalar_int = branches[0].to_leaf();
406406
let variant_idx = VariantIdx::from_u32(scalar_int.to_u32());
407407
let variant = def.variant(variant_idx);
408408
debug!(?variant);

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

Lines changed: 6 additions & 18 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, ValTreeKindExt};
6+
use rustc_middle::ty::{FloatTy, ScalarInt, SimdAlign};
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;
@@ -545,19 +545,15 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
545545
let (right, right_len) = self.project_to_simd(&args[1])?;
546546
let (dest, dest_len) = self.project_to_simd(&dest)?;
547547

548-
let index = generic_args[2].expect_const().to_value().valtree.unwrap_branch();
548+
let index = generic_args[2].expect_const().to_branch();
549549
let index_len = index.len();
550550

551551
assert_eq!(left_len, right_len);
552552
assert_eq!(u64::try_from(index_len).unwrap(), dest_len);
553553

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

563559
let val = if src_index < left_len {
@@ -661,11 +657,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
661657
self.check_simd_ptr_alignment(
662658
ptr,
663659
dest_layout,
664-
generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0]
665-
.to_value()
666-
.valtree
667-
.unwrap_leaf()
668-
.to_simd_alignment(),
660+
generic_args[3].expect_const().to_branch()[0].to_leaf().to_simd_alignment(),
669661
)?;
670662

671663
for i in 0..dest_len {
@@ -695,11 +687,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
695687
self.check_simd_ptr_alignment(
696688
ptr,
697689
args[2].layout,
698-
generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0]
699-
.to_value()
700-
.valtree
701-
.unwrap_leaf()
702-
.to_simd_alignment(),
690+
generic_args[3].expect_const().to_branch()[0].to_leaf().to_simd_alignment(),
703691
)?;
704692

705693
for i in 0..vals_len {

compiler/rustc_middle/src/mir/consts.rs

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use super::interpret::ReportedErrorInfo;
1010
use crate::mir::interpret::{AllocId, AllocRange, ErrorHandled, GlobalAlloc, Scalar, alloc_range};
1111
use crate::mir::{Promoted, pretty_print_const_value};
1212
use crate::ty::print::{pretty_print_const, with_no_trimmed_paths};
13-
use crate::ty::{self, ConstKind, GenericArgsRef, ScalarInt, Ty, TyCtxt, ValTreeKindExt};
13+
use crate::ty::{self, ConstKind, GenericArgsRef, ScalarInt, Ty, TyCtxt};
1414

1515
///////////////////////////////////////////////////////////////////////////
1616
/// Evaluated Constants
@@ -302,15 +302,7 @@ impl<'tcx> Const<'tcx> {
302302
#[inline]
303303
pub fn try_to_scalar(self) -> Option<Scalar> {
304304
match self {
305-
Const::Ty(_, c) => match c.kind() {
306-
ty::ConstKind::Value(cv) if cv.ty.is_primitive() => {
307-
// A valtree of a type where leaves directly represent the scalar const value.
308-
// Just checking whether it is a leaf is insufficient as e.g. references are leafs
309-
// but the leaf value is the value they point to, not the reference itself!
310-
Some(cv.valtree.unwrap_leaf().into())
311-
}
312-
_ => None,
313-
},
305+
Const::Ty(_, c) => c.try_to_scalar(),
314306
Const::Val(val, _) => val.try_to_scalar(),
315307
Const::Unevaluated(..) => None,
316308
}
@@ -321,10 +313,7 @@ impl<'tcx> Const<'tcx> {
321313
// This is equivalent to `self.try_to_scalar()?.try_to_int().ok()`, but measurably faster.
322314
match self {
323315
Const::Val(ConstValue::Scalar(Scalar::Int(x)), _) => Some(x),
324-
Const::Ty(_, c) => match c.kind() {
325-
ty::ConstKind::Value(cv) if cv.ty.is_primitive() => Some(cv.valtree.unwrap_leaf()),
326-
_ => None,
327-
},
316+
Const::Ty(_, c) => c.try_to_leaf(),
328317
_ => None,
329318
}
330319
}
@@ -377,14 +366,10 @@ impl<'tcx> Const<'tcx> {
377366
tcx: TyCtxt<'tcx>,
378367
typing_env: ty::TypingEnv<'tcx>,
379368
) -> Option<Scalar> {
380-
if let Const::Ty(_, c) = self
381-
&& let ty::ConstKind::Value(cv) = c.kind()
382-
&& cv.ty.is_primitive()
383-
{
384-
// Avoid the `valtree_to_const_val` query. Can only be done on primitive types that
385-
// are valtree leaves, and *not* on references. (References should return the
386-
// pointer here, which valtrees don't represent.)
387-
Some(cv.valtree.unwrap_leaf().into())
369+
if let Const::Ty(_, c) = self {
370+
// We don't evaluate anything for type system constants as normalizing
371+
// the MIR will handle this for us
372+
c.try_to_scalar()
388373
} else {
389374
self.eval(tcx, typing_env, DUMMY_SP).ok()?.try_to_scalar()
390375
}

compiler/rustc_middle/src/thir.rs

Lines changed: 5 additions & 5 deletions
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, ValTreeKindExt,
36+
TyCtxt, UpvarArgs,
3737
};
3838

3939
pub mod visit;
@@ -922,7 +922,7 @@ impl<'tcx> PatRange<'tcx> {
922922
let lo_is_min = match self.lo {
923923
PatRangeBoundary::NegInfinity => true,
924924
PatRangeBoundary::Finite(value) => {
925-
let lo = value.try_to_scalar_int().unwrap().to_bits(size) ^ bias;
925+
let lo = value.to_leaf().to_bits(size) ^ bias;
926926
lo <= min
927927
}
928928
PatRangeBoundary::PosInfinity => false,
@@ -931,7 +931,7 @@ impl<'tcx> PatRange<'tcx> {
931931
let hi_is_max = match self.hi {
932932
PatRangeBoundary::NegInfinity => false,
933933
PatRangeBoundary::Finite(value) => {
934-
let hi = value.try_to_scalar_int().unwrap().to_bits(size) ^ bias;
934+
let hi = value.to_leaf().to_bits(size) ^ bias;
935935
hi > max || hi == max && self.end == RangeEnd::Included
936936
}
937937
PatRangeBoundary::PosInfinity => true,
@@ -1023,7 +1023,7 @@ impl<'tcx> PatRangeBoundary<'tcx> {
10231023
}
10241024
pub fn to_bits(self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> u128 {
10251025
match self {
1026-
Self::Finite(value) => value.try_to_scalar_int().unwrap().to_bits_unchecked(),
1026+
Self::Finite(value) => value.to_leaf().to_bits_unchecked(),
10271027
Self::NegInfinity => {
10281028
// Unwrap is ok because the type is known to be numeric.
10291029
ty.numeric_min_and_max_as_bits(tcx).unwrap().0
@@ -1051,7 +1051,7 @@ impl<'tcx> PatRangeBoundary<'tcx> {
10511051
// many ranges such as '\u{037A}'..='\u{037F}', and chars can be compared
10521052
// in this way.
10531053
(Finite(a), Finite(b)) if matches!(ty.kind(), ty::Int(_) | ty::Uint(_) | ty::Char) => {
1054-
if let (Some(a), Some(b)) = (a.try_to_scalar_int(), b.try_to_scalar_int()) {
1054+
if let (Some(a), Some(b)) = (a.try_to_leaf(), b.try_to_leaf()) {
10551055
let sz = ty.primitive_size(tcx);
10561056
let cmp = match ty.kind() {
10571057
ty::Uint(_) | ty::Char => a.to_uint(sz).cmp(&b.to_uint(sz)),

compiler/rustc_middle/src/ty/consts.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable};
66
use rustc_type_ir::walk::TypeWalker;
77
use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo};
88

9+
use crate::mir::interpret::Scalar;
910
use crate::ty::{self, Ty, TyCtxt};
1011

1112
mod int;
@@ -260,14 +261,53 @@ impl<'tcx> Const<'tcx> {
260261

261262
/// Attempts to convert to a value.
262263
///
263-
/// Note that this does not evaluate the constant.
264+
/// Note that this does not normalize the constant.
264265
pub fn try_to_value(self) -> Option<ty::Value<'tcx>> {
265266
match self.kind() {
266267
ty::ConstKind::Value(cv) => Some(cv),
267268
_ => None,
268269
}
269270
}
270271

272+
/// Converts to a `ValTreeKind::Leaf` value, panicing
273+
/// if this constant is some other kind.
274+
///
275+
/// Note that this does not normalize the constant.
276+
#[inline]
277+
pub fn to_leaf(self) -> ScalarInt {
278+
self.to_value().to_leaf()
279+
}
280+
281+
/// Converts to a `ValTreeKind::Branch` value, panicing
282+
/// if this constant is some other kind.
283+
///
284+
/// Note that this does not normalize the constant.
285+
#[inline]
286+
pub fn to_branch(self) -> &'tcx [ty::Const<'tcx>] {
287+
self.to_value().to_branch()
288+
}
289+
290+
/// Attempts to convert to a `ValTreeKind::Leaf` value.
291+
///
292+
/// Note that this does not normalize the constant.
293+
pub fn try_to_leaf(self) -> Option<ScalarInt> {
294+
self.try_to_value()?.try_to_leaf()
295+
}
296+
297+
/// Attempts to convert to a `ValTreeKind::Leaf` value.
298+
///
299+
/// Note that this does not normalize the constant.
300+
pub fn try_to_scalar(self) -> Option<Scalar> {
301+
self.try_to_leaf().map(Scalar::Int)
302+
}
303+
304+
/// Attempts to convert to a `ValTreeKind::Branch` value.
305+
///
306+
/// Note that this does not normalize the constant.
307+
pub fn try_to_branch(self) -> Option<&'tcx [ty::Const<'tcx>]> {
308+
self.try_to_value()?.try_to_branch()
309+
}
310+
271311
/// Convenience method to extract the value of a usize constant,
272312
/// useful to get the length of an array type.
273313
///

0 commit comments

Comments
 (0)