Skip to content

Commit 9783e80

Browse files
Move try_to_bits from Const to Valtree
Signed-off-by: FedericoBruzzone <[email protected]>
1 parent 5545959 commit 9783e80

File tree

6 files changed

+45
-37
lines changed

6 files changed

+45
-37
lines changed

compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -676,17 +676,15 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
676676
ty::ConstKind::Value(ty, valtree) => {
677677
match ty.kind() {
678678
ty::Int(ity) => {
679-
// FIXME: directly extract the bits from a valtree instead of evaluating an
680-
// already evaluated `Const` in order to get the bits.
681-
let bits = ct
682-
.try_to_bits(tcx, ty::TypingEnv::fully_monomorphized())
679+
let bits = valtree
680+
.try_to_bits(tcx, ty, ty::TypingEnv::fully_monomorphized())
683681
.expect("expected monomorphic const in codegen");
684682
let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
685683
write!(output, "{val}")
686684
}
687685
ty::Uint(_) => {
688-
let val = ct
689-
.try_to_bits(tcx, ty::TypingEnv::fully_monomorphized())
686+
let val = valtree
687+
.try_to_bits(tcx, ty, ty::TypingEnv::fully_monomorphized())
690688
.expect("expected monomorphic const in codegen");
691689
write!(output, "{val}")
692690
}

compiler/rustc_middle/src/ty/consts.rs

-12
Original file line numberDiff line numberDiff line change
@@ -245,18 +245,6 @@ impl<'tcx> Const<'tcx> {
245245
self.try_to_valtree()?.0.try_to_target_usize(tcx)
246246
}
247247

248-
/// Attempts to evaluate the given constant to bits. Can fail to evaluate in the presence of
249-
/// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it
250-
/// contains const generic parameters or pointers).
251-
#[inline]
252-
pub fn try_to_bits(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Option<u128> {
253-
let (scalar, ty) = self.try_to_scalar()?;
254-
let scalar = scalar.try_to_scalar_int().ok()?;
255-
let input = typing_env.with_post_analysis_normalized(tcx).as_query_input(ty);
256-
let size = tcx.layout_of(input).ok()?.size;
257-
Some(scalar.to_bits(size))
258-
}
259-
260248
pub fn is_ct_infer(self) -> bool {
261249
matches!(self.kind(), ty::ConstKind::Infer(_))
262250
}

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

+15
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,21 @@ impl<'tcx> ValTree<'tcx> {
8383
self.try_to_scalar_int().map(|s| s.to_target_usize(tcx))
8484
}
8585

86+
/// Attempts to extract the raw bits of the valtree.
87+
///
88+
/// Can fail if the value can't be represented as bits (e.g. because it is an aggregate).
89+
pub fn try_to_bits(
90+
self,
91+
tcx: TyCtxt<'tcx>,
92+
ty: Ty<'tcx>,
93+
typing_env: ty::TypingEnv<'tcx>,
94+
) -> Option<u128> {
95+
let input = typing_env.with_post_analysis_normalized(tcx).as_query_input(ty);
96+
let size = tcx.layout_of(input).ok()?.size;
97+
let scalar = self.try_to_scalar_int()?;
98+
Some(scalar.to_bits(size))
99+
}
100+
86101
/// Get the values inside the ValTree as a slice of bytes. This only works for
87102
/// constants with types &str, &[u8], or [u8; _].
88103
pub fn try_to_raw_bytes(self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx [u8]> {

compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ fn encode_const<'tcx>(
121121
}
122122

123123
// Literal arguments
124-
ty::ConstKind::Value(ct_ty, ..) => {
124+
ty::ConstKind::Value(ct_ty, valtree) => {
125125
// L<element-type>[n]<element-value>E as literal argument
126126

127127
// Element type
@@ -132,8 +132,8 @@ fn encode_const<'tcx>(
132132
// bool value false is encoded as 0 and true as 1.
133133
match ct_ty.kind() {
134134
ty::Int(ity) => {
135-
let bits = c
136-
.try_to_bits(tcx, ty::TypingEnv::fully_monomorphized())
135+
let bits = valtree
136+
.try_to_bits(tcx, ct_ty, ty::TypingEnv::fully_monomorphized())
137137
.expect("expected monomorphic const in cfi");
138138
let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
139139
if val < 0 {
@@ -142,8 +142,8 @@ fn encode_const<'tcx>(
142142
let _ = write!(s, "{val}");
143143
}
144144
ty::Uint(_) => {
145-
let val = c
146-
.try_to_bits(tcx, ty::TypingEnv::fully_monomorphized())
145+
let val = valtree
146+
.try_to_bits(tcx, ct_ty, ty::TypingEnv::fully_monomorphized())
147147
.expect("expected monomorphic const in cfi");
148148
let _ = write!(s, "{val}");
149149
}

compiler/rustc_symbol_mangling/src/v0.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -625,8 +625,8 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
625625
ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Char => {
626626
ct_ty.print(self)?;
627627

628-
let mut bits = ct
629-
.try_to_bits(self.tcx, ty::TypingEnv::fully_monomorphized())
628+
let mut bits = valtree
629+
.try_to_bits(self.tcx, ct_ty, ty::TypingEnv::fully_monomorphized())
630630
.expect("expected const to be monomorphic");
631631

632632
// Negative integer values are mangled using `n` as a "sign prefix".

compiler/rustc_ty_utils/src/layout.rs

+19-12
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ use crate::errors::{
3333

3434
mod invariant;
3535

36+
/// The `ValTree` alongside its type.
37+
struct ValTreeAndTy<'tcx> {
38+
valtree: ty::ValTree<'tcx>,
39+
ty: Ty<'tcx>,
40+
}
41+
3642
pub(crate) fn provide(providers: &mut Providers) {
3743
*providers = Providers { layout_of, ..*providers };
3844
}
@@ -144,13 +150,13 @@ fn univariant_uninterned<'tcx>(
144150
cx.calc.univariant(fields, repr, kind).map_err(|err| map_error(cx, ty, err))
145151
}
146152

147-
fn validate_const_with_value<'tcx>(
153+
fn extract_valtree_and_ty<'tcx>(
148154
const_: ty::Const<'tcx>,
149155
ty: Ty<'tcx>,
150156
cx: &LayoutCx<'tcx>,
151-
) -> Result<ty::Const<'tcx>, &'tcx LayoutError<'tcx>> {
157+
) -> Result<ValTreeAndTy<'tcx>, &'tcx LayoutError<'tcx>> {
152158
match const_.kind() {
153-
ty::ConstKind::Value(..) => Ok(const_),
159+
ty::ConstKind::Value(ty, valtree) => Ok(ValTreeAndTy { valtree, ty }),
154160
ty::ConstKind::Error(guar) => {
155161
return Err(error(cx, LayoutError::ReferencesError(guar)));
156162
}
@@ -209,14 +215,16 @@ fn layout_of_uncached<'tcx>(
209215
&mut layout.backend_repr
210216
{
211217
if let Some(start) = start {
212-
scalar.valid_range_mut().start =
213-
validate_const_with_value(start, ty, cx)?
214-
.try_to_bits(tcx, cx.typing_env)
215-
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
218+
let ValTreeAndTy { valtree, ty } =
219+
extract_valtree_and_ty(start, ty, cx)?;
220+
scalar.valid_range_mut().start = valtree
221+
.try_to_bits(tcx, ty, cx.typing_env)
222+
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
216223
}
217224
if let Some(end) = end {
218-
let mut end = validate_const_with_value(end, ty, cx)?
219-
.try_to_bits(tcx, cx.typing_env)
225+
let ValTreeAndTy { valtree, ty } = extract_valtree_and_ty(end, ty, cx)?;
226+
let mut end = valtree
227+
.try_to_bits(tcx, ty, cx.typing_env)
220228
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
221229
if !include_end {
222230
end = end.wrapping_sub(1);
@@ -348,9 +356,8 @@ fn layout_of_uncached<'tcx>(
348356

349357
// Arrays and slices.
350358
ty::Array(element, count) => {
351-
let count = validate_const_with_value(count, ty, cx)?
352-
.to_valtree()
353-
.0
359+
let count = extract_valtree_and_ty(count, ty, cx)?
360+
.valtree
354361
.try_to_target_usize(tcx)
355362
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
356363

0 commit comments

Comments
 (0)