Skip to content

Commit 773d8b2

Browse files
committed
address review
1 parent 0a6815a commit 773d8b2

22 files changed

+116
-161
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ dependencies = [
358358
"libgit2-sys",
359359
"log",
360360
"memchr",
361+
"num_cpus",
361362
"opener",
362363
"openssl",
363364
"os_info",

compiler/rustc_middle/src/mir/interpret/queries.rs

-20
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@ impl<'tcx> TyCtxt<'tcx> {
1111
/// Evaluates a constant without providing any substitutions. This is useful to evaluate consts
1212
/// that can't take any generic arguments like statics, const items or enum discriminants. If a
1313
/// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned.
14-
///
15-
/// Note: Returns a `ConstValue`, which isn't supposed to be used in the type system. In order to
16-
/// evaluate to a type-system level constant value use `const_eval_poly_for_typeck`.
1714
#[instrument(skip(self), level = "debug")]
1815
pub fn const_eval_poly(self, def_id: DefId) -> EvalToConstValueResult<'tcx> {
1916
// In some situations def_id will have substitutions within scope, but they aren't allowed
@@ -26,23 +23,6 @@ impl<'tcx> TyCtxt<'tcx> {
2623
let param_env = self.param_env(def_id).with_reveal_all_normalized(self);
2724
self.const_eval_global_id(param_env, cid, None)
2825
}
29-
30-
/// Evaluates a constant without providing any substitutions. This is useful to evaluate consts
31-
/// that can't take any generic arguments like statics, const items or enum discriminants. If a
32-
/// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned.
33-
#[instrument(skip(self), level = "debug")]
34-
pub fn const_eval_poly_for_typeck(self, def_id: DefId) -> EvalToValTreeResult<'tcx> {
35-
// In some situations def_id will have substitutions within scope, but they aren't allowed
36-
// to be used. So we can't use `Instance::mono`, instead we feed unresolved substitutions
37-
// into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are
38-
// encountered.
39-
let substs = InternalSubsts::identity_for_item(self, def_id);
40-
let instance = ty::Instance::new(def_id, substs);
41-
let cid = GlobalId { instance, promoted: None };
42-
let param_env = self.param_env(def_id).with_reveal_all_normalized(self);
43-
self.const_eval_global_id_for_typeck(param_env, cid, None)
44-
}
45-
4626
/// Resolves and evaluates a constant.
4727
///
4828
/// The constant can be located on a trait like `<A as B>::C`, in which case the given

compiler/rustc_middle/src/mir/interpret/value.rs

+4
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ impl<'tcx> ConstValue<'tcx> {
111111
pub fn from_machine_usize(i: u64, cx: &impl HasDataLayout) -> Self {
112112
ConstValue::Scalar(Scalar::from_machine_usize(i, cx))
113113
}
114+
115+
pub fn zst() -> Self {
116+
Self::Scalar(Scalar::ZST)
117+
}
114118
}
115119

116120
/// A `Scalar` represents an immediate, primitive value existing outside of a

compiler/rustc_middle/src/mir/mod.rs

+2-11
Original file line numberDiff line numberDiff line change
@@ -2405,7 +2405,7 @@ impl<'tcx> Operand<'tcx> {
24052405
Operand::Constant(Box::new(Constant {
24062406
span,
24072407
user_ty: None,
2408-
literal: ConstantKind::Ty(ty::Const::zero_sized(tcx, ty)),
2408+
literal: ConstantKind::Val(ConstValue::zst(), ty),
24092409
}))
24102410
}
24112411

@@ -2981,16 +2981,6 @@ impl<'tcx> ConstantKind<'tcx> {
29812981
}
29822982
}
29832983

2984-
pub fn try_val(&self, tcx: TyCtxt<'tcx>) -> Option<ConstValue<'tcx>> {
2985-
match self {
2986-
ConstantKind::Ty(c) => match c.kind() {
2987-
ty::ConstKind::Value(v) => Some(tcx.valtree_to_const_val((c.ty(), v))),
2988-
_ => None,
2989-
},
2990-
ConstantKind::Val(v, _) => Some(*v),
2991-
}
2992-
}
2993-
29942984
#[inline]
29952985
pub fn try_to_value(self, tcx: TyCtxt<'tcx>) -> Option<interpret::ConstValue<'tcx>> {
29962986
match self {
@@ -3548,6 +3538,7 @@ fn comma_sep<'tcx>(fmt: &mut Formatter<'_>, elems: Vec<ConstantKind<'tcx>>) -> f
35483538
Ok(())
35493539
}
35503540

3541+
// FIXME: Move that into `mir/pretty.rs`.
35513542
fn pretty_print_const_value<'tcx>(
35523543
ct: ConstValue<'tcx>,
35533544
ty: Ty<'tcx>,

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -1530,7 +1530,9 @@ pub trait PrettyPrinter<'tcx>:
15301530
}
15311531

15321532
// fallback
1533-
if valtree != ty::ValTree::zst() {
1533+
if valtree == ty::ValTree::zst() {
1534+
p!(write("<ZST>"));
1535+
} else {
15341536
p!(write("{:?}", valtree));
15351537
}
15361538
if print_ty {

compiler/rustc_mir_build/src/build/mod.rs

+58-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ use crate::build;
22
pub(crate) use crate::build::expr::as_constant::lit_to_mir_constant;
33
use crate::build::expr::as_place::PlaceBuilder;
44
use crate::build::scope::DropKind;
5-
use crate::thir::constant::parse_float_into_scalar;
65
use crate::thir::pattern::pat_from_hir;
76
use rustc_data_structures::fx::FxHashMap;
7+
use rustc_apfloat::ieee::{Double, Single};
88
use rustc_errors::ErrorGuaranteed;
99
use rustc_hir as hir;
1010
use rustc_hir::def_id::{DefId, LocalDefId};
@@ -15,6 +15,7 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
1515
use rustc_middle::hir::place::PlaceBase as HirPlaceBase;
1616
use rustc_middle::middle::region;
1717
use rustc_middle::mir::interpret::ConstValue;
18+
use rustc_middle::mir::interpret::Scalar;
1819
use rustc_middle::mir::*;
1920
use rustc_middle::thir::{BindingMode, Expr, ExprId, LintLevel, LocalVarId, PatKind, Thir};
2021
use rustc_middle::ty::subst::Subst;
@@ -1093,6 +1094,62 @@ fn parse_float_into_constval<'tcx>(
10931094
parse_float_into_scalar(num, float_ty, neg).map(ConstValue::Scalar)
10941095
}
10951096

1097+
pub(crate) fn parse_float_into_scalar(
1098+
num: Symbol,
1099+
float_ty: ty::FloatTy,
1100+
neg: bool,
1101+
) -> Option<Scalar> {
1102+
let num = num.as_str();
1103+
match float_ty {
1104+
ty::FloatTy::F32 => {
1105+
let Ok(rust_f) = num.parse::<f32>() else { return None };
1106+
let mut f = num.parse::<Single>().unwrap_or_else(|e| {
1107+
panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
1108+
});
1109+
1110+
assert!(
1111+
u128::from(rust_f.to_bits()) == f.to_bits(),
1112+
"apfloat::ieee::Single gave different result for `{}`: \
1113+
{}({:#x}) vs Rust's {}({:#x})",
1114+
rust_f,
1115+
f,
1116+
f.to_bits(),
1117+
Single::from_bits(rust_f.to_bits().into()),
1118+
rust_f.to_bits()
1119+
);
1120+
1121+
if neg {
1122+
f = -f;
1123+
}
1124+
1125+
Some(Scalar::from_f32(f))
1126+
}
1127+
ty::FloatTy::F64 => {
1128+
let Ok(rust_f) = num.parse::<f64>() else { return None };
1129+
let mut f = num.parse::<Double>().unwrap_or_else(|e| {
1130+
panic!("apfloat::ieee::Double failed to parse `{}`: {:?}", num, e)
1131+
});
1132+
1133+
assert!(
1134+
u128::from(rust_f.to_bits()) == f.to_bits(),
1135+
"apfloat::ieee::Double gave different result for `{}`: \
1136+
{}({:#x}) vs Rust's {}({:#x})",
1137+
rust_f,
1138+
f,
1139+
f.to_bits(),
1140+
Double::from_bits(rust_f.to_bits().into()),
1141+
rust_f.to_bits()
1142+
);
1143+
1144+
if neg {
1145+
f = -f;
1146+
}
1147+
1148+
Some(Scalar::from_f64(f))
1149+
}
1150+
}
1151+
}
1152+
10961153
///////////////////////////////////////////////////////////////////////////
10971154
// Builder methods are broken up into modules, depending on what kind
10981155
// of thing is being lowered. Note that they use the `unpack` macro
+1-71
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
use rustc_apfloat::ieee::{Double, Single};
2-
use rustc_apfloat::Float;
31
use rustc_ast as ast;
4-
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput, Scalar};
2+
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
53
use rustc_middle::ty::{self, ParamEnv, ScalarInt, TyCtxt};
6-
use rustc_span::symbol::Symbol;
74

85
pub(crate) fn lit_to_const<'tcx>(
96
tcx: TyCtxt<'tcx>,
@@ -45,9 +42,6 @@ pub(crate) fn lit_to_const<'tcx>(
4542
trunc(if neg { (*n as i128).overflowing_neg().0 as u128 } else { *n })?;
4643
ty::ValTree::from_scalar_int(scalar_int)
4744
}
48-
(ast::LitKind::Float(n, _), ty::Float(fty)) => {
49-
parse_float_into_valtree(*n, *fty, neg).ok_or(LitToConstError::Reported)?
50-
}
5145
(ast::LitKind::Bool(b), ty::Bool) => ty::ValTree::from_scalar_int((*b).into()),
5246
(ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()),
5347
(ast::LitKind::Err(_), _) => return Err(LitToConstError::Reported),
@@ -56,67 +50,3 @@ pub(crate) fn lit_to_const<'tcx>(
5650

5751
Ok(ty::Const::from_value(tcx, valtree, ty))
5852
}
59-
60-
pub(crate) fn parse_float_into_scalar(
61-
num: Symbol,
62-
float_ty: ty::FloatTy,
63-
neg: bool,
64-
) -> Option<Scalar> {
65-
let num = num.as_str();
66-
match float_ty {
67-
ty::FloatTy::F32 => {
68-
let Ok(rust_f) = num.parse::<f32>() else { return None };
69-
let mut f = num.parse::<Single>().unwrap_or_else(|e| {
70-
panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
71-
});
72-
73-
assert!(
74-
u128::from(rust_f.to_bits()) == f.to_bits(),
75-
"apfloat::ieee::Single gave different result for `{}`: \
76-
{}({:#x}) vs Rust's {}({:#x})",
77-
rust_f,
78-
f,
79-
f.to_bits(),
80-
Single::from_bits(rust_f.to_bits().into()),
81-
rust_f.to_bits()
82-
);
83-
84-
if neg {
85-
f = -f;
86-
}
87-
88-
Some(Scalar::from_f32(f))
89-
}
90-
ty::FloatTy::F64 => {
91-
let Ok(rust_f) = num.parse::<f64>() else { return None };
92-
let mut f = num.parse::<Double>().unwrap_or_else(|e| {
93-
panic!("apfloat::ieee::Double failed to parse `{}`: {:?}", num, e)
94-
});
95-
96-
assert!(
97-
u128::from(rust_f.to_bits()) == f.to_bits(),
98-
"apfloat::ieee::Double gave different result for `{}`: \
99-
{}({:#x}) vs Rust's {}({:#x})",
100-
rust_f,
101-
f,
102-
f.to_bits(),
103-
Double::from_bits(rust_f.to_bits().into()),
104-
rust_f.to_bits()
105-
);
106-
107-
if neg {
108-
f = -f;
109-
}
110-
111-
Some(Scalar::from_f64(f))
112-
}
113-
}
114-
}
115-
116-
fn parse_float_into_valtree<'tcx>(
117-
num: Symbol,
118-
float_ty: ty::FloatTy,
119-
neg: bool,
120-
) -> Option<ty::ValTree<'tcx>> {
121-
parse_float_into_scalar(num, float_ty, neg).map(|s| ty::ValTree::Leaf(s.try_to_int().unwrap()))
122-
}

compiler/rustc_symbol_mangling/src/v0.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -626,9 +626,8 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
626626
let _ = write!(self.out, "{:x}_", bits);
627627
}
628628

629-
// HACK(eddyb) because `ty::Const` only supports sized values (for now),
630-
// we can't use dereference the const + supporting `str`, we have to specially
631-
// handle `&str` and include both `&` ("R") and `str` ("e") prefixes.
629+
// FIXME(valtrees): Remove the special case for `str`
630+
// here and fully support unsized constants.
632631
ty::Ref(_, inner_ty, mutbl) => {
633632
self.push(match mutbl {
634633
hir::Mutability::Not => "R",

src/librustdoc/clean/utils.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ use rustc_data_structures::thin_vec::ThinVec;
1515
use rustc_hir as hir;
1616
use rustc_hir::def::{DefKind, Res};
1717
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
18+
use rustc_middle::mir;
19+
use rustc_middle::mir::interpret::ConstValue;
1820
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
1921
use rustc_middle::ty::{self, DefIdTree, TyCtxt};
2022
use rustc_span::symbol::{kw, sym, Symbol};
@@ -263,13 +265,13 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
263265
}
264266

265267
pub(crate) fn print_evaluated_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option<String> {
266-
tcx.const_eval_poly_for_typeck(def_id).ok().and_then(|val| {
268+
tcx.const_eval_poly(def_id).ok().and_then(|val| {
267269
let ty = tcx.type_of(def_id);
268270
match (val, ty.kind()) {
269271
(_, &ty::Ref(..)) => None,
270-
(Some(ty::ValTree::Branch(_)), &ty::Adt(_, _)) => None,
271-
(Some(ty::ValTree::Leaf(_)), _) => {
272-
let const_ = ty::Const::from_value(tcx, val.unwrap(), ty);
272+
(ConstValue::Scalar(_), &ty::Adt(_, _)) => None,
273+
(ConstValue::Scalar(_), _) => {
274+
let const_ = mir::ConstantKind::from_value(val, ty);
273275
Some(print_const_with_custom_print_scalar(tcx, const_))
274276
}
275277
_ => None,
@@ -303,19 +305,18 @@ fn format_integer_with_underscore_sep(num: &str) -> String {
303305
.collect()
304306
}
305307

306-
fn print_const_with_custom_print_scalar(tcx: TyCtxt<'_>, ct: ty::Const<'_>) -> String {
308+
fn print_const_with_custom_print_scalar(tcx: TyCtxt<'_>, ct: mir::ConstantKind<'_>) -> String {
307309
// Use a slightly different format for integer types which always shows the actual value.
308310
// For all other types, fallback to the original `pretty_print_const`.
309-
match (ct.kind(), ct.ty().kind()) {
310-
(ty::ConstKind::Value(ty::ValTree::Leaf(int)), ty::Uint(ui)) => {
311+
match (ct, ct.ty().kind()) {
312+
(mir::ConstantKind::Val(ConstValue::Scalar(int), _), ty::Uint(ui)) => {
311313
format!("{}{}", format_integer_with_underscore_sep(&int.to_string()), ui.name_str())
312314
}
313-
(ty::ConstKind::Value(ty::ValTree::Leaf(int)), ty::Int(i)) => {
315+
(mir::ConstantKind::Val(ConstValue::Scalar(int), _), ty::Int(i)) => {
314316
let ty = tcx.lift(ct.ty()).unwrap();
315317
let size = tcx.layout_of(ty::ParamEnv::empty().and(ty)).unwrap().size;
316318
let data = int.assert_bits(size);
317319
let sign_extended_data = size.sign_extend(data) as i128;
318-
319320
format!(
320321
"{}{}",
321322
format_integer_with_underscore_sep(&sign_extended_data.to_string()),

src/test/mir-opt/box_expr.main.ElaborateDrops.before.mir

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ fn main() -> () {
1919
StorageLive(_1); // scope 0 at $DIR/box_expr.rs:7:9: 7:10
2020
_2 = SizeOf(S); // scope 2 at $DIR/box_expr.rs:7:13: 7:25
2121
_3 = AlignOf(S); // scope 2 at $DIR/box_expr.rs:7:13: 7:25
22-
_4 = : unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}(move _2, move _3) -> bb1; // scope 2 at $DIR/box_expr.rs:7:13: 7:25
22+
_4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 2 at $DIR/box_expr.rs:7:13: 7:25
2323
// mir::Constant
2424
// + span: $DIR/box_expr.rs:7:13: 7:25
25-
// + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(ValTree::Branch(..)) }
25+
// + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(Scalar(<ZST>)) }
2626
}
2727

2828
bb1: {

src/test/mir-opt/const_prop/boxes.main.ConstProp.diff

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@
2222
StorageLive(_3); // scope 0 at $DIR/boxes.rs:12:14: 12:22
2323
- _4 = SizeOf(i32); // scope 2 at $DIR/boxes.rs:12:14: 12:22
2424
- _5 = AlignOf(i32); // scope 2 at $DIR/boxes.rs:12:14: 12:22
25-
- _6 = : unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}(move _4, move _5) -> bb1; // scope 2 at $DIR/boxes.rs:12:14: 12:22
25+
- _6 = alloc::alloc::exchange_malloc(move _4, move _5) -> bb1; // scope 2 at $DIR/boxes.rs:12:14: 12:22
2626
+ _4 = const 4_usize; // scope 2 at $DIR/boxes.rs:12:14: 12:22
2727
+ _5 = const 4_usize; // scope 2 at $DIR/boxes.rs:12:14: 12:22
28-
+ _6 = : unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}(const 4_usize, const 4_usize) -> bb1; // scope 2 at $DIR/boxes.rs:12:14: 12:22
28+
+ _6 = alloc::alloc::exchange_malloc(const 4_usize, const 4_usize) -> bb1; // scope 2 at $DIR/boxes.rs:12:14: 12:22
2929
// mir::Constant
3030
// + span: $DIR/boxes.rs:12:14: 12:22
31-
// + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(ValTree::Branch(..)) }
31+
// + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(Scalar(<ZST>)) }
3232
}
3333

3434
bb1: {

src/test/mir-opt/derefer_inline_test.main.Derefer.diff

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
StorageLive(_1); // scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12
1717
_2 = SizeOf(std::boxed::Box<u32>); // scope 1 at $DIR/derefer_inline_test.rs:10:5: 10:12
1818
_3 = AlignOf(std::boxed::Box<u32>); // scope 1 at $DIR/derefer_inline_test.rs:10:5: 10:12
19-
_4 = : unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}(move _2, move _3) -> bb1; // scope 1 at $DIR/derefer_inline_test.rs:10:5: 10:12
19+
_4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 1 at $DIR/derefer_inline_test.rs:10:5: 10:12
2020
// mir::Constant
2121
// + span: $DIR/derefer_inline_test.rs:10:5: 10:12
22-
// + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(ValTree::Branch(..)) }
22+
// + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(Scalar(<ZST>)) }
2323
}
2424

2525
bb1: {
@@ -56,10 +56,10 @@
5656
}
5757

5858
bb7 (cleanup): {
59-
_6 = : unsafe fn(Unique::<Box<u32>>, std::alloc::Global) {alloc::alloc::box_free::<Box<u32>, std::alloc::Global>}(move (_5.0: std::ptr::Unique<std::boxed::Box<u32>>), move (_5.1: std::alloc::Global)) -> bb6; // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12
59+
_6 = alloc::alloc::box_free::<Box<u32>, std::alloc::Global>(move (_5.0: std::ptr::Unique<std::boxed::Box<u32>>), move (_5.1: std::alloc::Global)) -> bb6; // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12
6060
// mir::Constant
6161
// + span: $DIR/derefer_inline_test.rs:10:11: 10:12
62-
// + literal: Const { ty: unsafe fn(Unique<Box<u32>>, std::alloc::Global) {alloc::alloc::box_free::<Box<u32>, std::alloc::Global>}, val: Value(ValTree::Branch(..)) }
62+
// + literal: Const { ty: unsafe fn(Unique<Box<u32>>, std::alloc::Global) {alloc::alloc::box_free::<Box<u32>, std::alloc::Global>}, val: Value(Scalar(<ZST>)) }
6363
}
6464

6565
bb8 (cleanup): {

0 commit comments

Comments
 (0)