Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 6f46db0

Browse files
authoredJun 4, 2024
Unrolled build for #125968
Rollup merge of #125968 - BoxyUwU:shrink_ty_expr, r=oli-obk Store the types of `ty::Expr` arguments in the `ty::Expr` Part of #125958 In attempting to remove the `ty` field on `Const` it will become necessary to store the `Ty<'tcx>` inside of `Expr<'tcx>`. In order to do this without blowing up the size of `ConstKind`, we start storing the type/const args as `GenericArgs` r? `@oli-obk`
2 parents bc33782 + 67a73f2 commit 6f46db0

File tree

13 files changed

+259
-165
lines changed

13 files changed

+259
-165
lines changed
 

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub type ConstKind<'tcx> = ir::ConstKind<TyCtxt<'tcx>>;
2424
pub type UnevaluatedConst<'tcx> = ir::UnevaluatedConst<TyCtxt<'tcx>>;
2525

2626
#[cfg(target_pointer_width = "64")]
27-
rustc_data_structures::static_assert_size!(ConstKind<'_>, 32);
27+
rustc_data_structures::static_assert_size!(ConstKind<'_>, 24);
2828

2929
/// Use this rather than `ConstData`, whenever possible.
3030
#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)]
@@ -58,7 +58,7 @@ pub struct ConstData<'tcx> {
5858
}
5959

6060
#[cfg(target_pointer_width = "64")]
61-
rustc_data_structures::static_assert_size!(ConstData<'_>, 40);
61+
rustc_data_structures::static_assert_size!(ConstData<'_>, 32);
6262

6363
impl<'tcx> Const<'tcx> {
6464
#[inline]

‎compiler/rustc_middle/src/ty/consts/kind.rs

Lines changed: 118 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::Const;
22
use crate::mir;
33
use crate::ty::abstract_const::CastKind;
4-
use crate::ty::{self, visit::TypeVisitableExt as _, List, Ty, TyCtxt};
4+
use crate::ty::{self, visit::TypeVisitableExt as _, Ty, TyCtxt};
55
use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
66

77
#[extension(pub(crate) trait UnevaluatedConstEvalExt<'tcx>)]
@@ -40,14 +40,125 @@ impl<'tcx> ty::UnevaluatedConst<'tcx> {
4040
}
4141
}
4242

43+
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
44+
#[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)]
45+
pub enum ExprKind {
46+
Binop(mir::BinOp),
47+
UnOp(mir::UnOp),
48+
FunctionCall,
49+
Cast(CastKind),
50+
}
4351
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
4452
#[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)]
45-
pub enum Expr<'tcx> {
46-
Binop(mir::BinOp, Const<'tcx>, Const<'tcx>),
47-
UnOp(mir::UnOp, Const<'tcx>),
48-
FunctionCall(Const<'tcx>, &'tcx List<Const<'tcx>>),
49-
Cast(CastKind, Const<'tcx>, Ty<'tcx>),
53+
pub struct Expr<'tcx> {
54+
pub kind: ExprKind,
55+
args: ty::GenericArgsRef<'tcx>,
56+
}
57+
impl<'tcx> Expr<'tcx> {
58+
pub fn new_binop(
59+
tcx: TyCtxt<'tcx>,
60+
binop: mir::BinOp,
61+
lhs_ty: Ty<'tcx>,
62+
rhs_ty: Ty<'tcx>,
63+
lhs_ct: Const<'tcx>,
64+
rhs_ct: Const<'tcx>,
65+
) -> Self {
66+
let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>(
67+
[lhs_ty.into(), rhs_ty.into(), lhs_ct.into(), rhs_ct.into()].into_iter(),
68+
);
69+
70+
Self { kind: ExprKind::Binop(binop), args }
71+
}
72+
73+
pub fn binop_args(self) -> (Ty<'tcx>, Ty<'tcx>, Const<'tcx>, Const<'tcx>) {
74+
assert!(matches!(self.kind, ExprKind::Binop(_)));
75+
76+
match self.args().as_slice() {
77+
[lhs_ty, rhs_ty, lhs_ct, rhs_ct] => (
78+
lhs_ty.expect_ty(),
79+
rhs_ty.expect_ty(),
80+
lhs_ct.expect_const(),
81+
rhs_ct.expect_const(),
82+
),
83+
_ => bug!("Invalid args for `Binop` expr {self:?}"),
84+
}
85+
}
86+
87+
pub fn new_unop(tcx: TyCtxt<'tcx>, unop: mir::UnOp, ty: Ty<'tcx>, ct: Const<'tcx>) -> Self {
88+
let args =
89+
tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>([ty.into(), ct.into()].into_iter());
90+
91+
Self { kind: ExprKind::UnOp(unop), args }
92+
}
93+
94+
pub fn unop_args(self) -> (Ty<'tcx>, Const<'tcx>) {
95+
assert!(matches!(self.kind, ExprKind::UnOp(_)));
96+
97+
match self.args().as_slice() {
98+
[ty, ct] => (ty.expect_ty(), ct.expect_const()),
99+
_ => bug!("Invalid args for `UnOp` expr {self:?}"),
100+
}
101+
}
102+
103+
pub fn new_call(
104+
tcx: TyCtxt<'tcx>,
105+
func_ty: Ty<'tcx>,
106+
func_expr: Const<'tcx>,
107+
arguments: impl Iterator<Item = Const<'tcx>>,
108+
) -> Self {
109+
let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>(
110+
[func_ty.into(), func_expr.into()].into_iter().chain(arguments.map(|ct| ct.into())),
111+
);
112+
113+
Self { kind: ExprKind::FunctionCall, args }
114+
}
115+
116+
pub fn call_args(self) -> (Ty<'tcx>, Const<'tcx>, impl Iterator<Item = Const<'tcx>>) {
117+
assert!(matches!(self.kind, ExprKind::FunctionCall));
118+
119+
match self.args().as_slice() {
120+
[func_ty, func, rest @ ..] => (
121+
func_ty.expect_ty(),
122+
func.expect_const(),
123+
rest.iter().map(|arg| arg.expect_const()),
124+
),
125+
_ => bug!("Invalid args for `Call` expr {self:?}"),
126+
}
127+
}
128+
129+
pub fn new_cast(
130+
tcx: TyCtxt<'tcx>,
131+
cast: CastKind,
132+
value_ty: Ty<'tcx>,
133+
value: Const<'tcx>,
134+
to_ty: Ty<'tcx>,
135+
) -> Self {
136+
let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>(
137+
[value_ty.into(), value.into(), to_ty.into()].into_iter(),
138+
);
139+
140+
Self { kind: ExprKind::Cast(cast), args }
141+
}
142+
143+
pub fn cast_args(self) -> (Ty<'tcx>, Const<'tcx>, Ty<'tcx>) {
144+
assert!(matches!(self.kind, ExprKind::Cast(_)));
145+
146+
match self.args().as_slice() {
147+
[value_ty, value, to_ty] => {
148+
(value_ty.expect_ty(), value.expect_const(), to_ty.expect_ty())
149+
}
150+
_ => bug!("Invalid args for `Cast` expr {self:?}"),
151+
}
152+
}
153+
154+
pub fn new(kind: ExprKind, args: ty::GenericArgsRef<'tcx>) -> Self {
155+
Self { kind, args }
156+
}
157+
158+
pub fn args(&self) -> ty::GenericArgsRef<'tcx> {
159+
self.args
160+
}
50161
}
51162

52163
#[cfg(target_pointer_width = "64")]
53-
rustc_data_structures::static_assert_size!(Expr<'_>, 24);
164+
rustc_data_structures::static_assert_size!(Expr<'_>, 16);

‎compiler/rustc_middle/src/ty/flags.rs

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -374,26 +374,7 @@ impl FlagComputation {
374374
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
375375
}
376376
ty::ConstKind::Value(_) => {}
377-
ty::ConstKind::Expr(e) => {
378-
use ty::Expr;
379-
match e {
380-
Expr::Binop(_, l, r) => {
381-
self.add_const(l);
382-
self.add_const(r);
383-
}
384-
Expr::UnOp(_, v) => self.add_const(v),
385-
Expr::FunctionCall(f, args) => {
386-
self.add_const(f);
387-
for arg in args {
388-
self.add_const(arg);
389-
}
390-
}
391-
Expr::Cast(_, c, t) => {
392-
self.add_ty(t);
393-
self.add_const(c);
394-
}
395-
}
396-
}
377+
ty::ConstKind::Expr(e) => self.add_args(e.args()),
397378
ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_ERROR),
398379
}
399380
}

‎compiler/rustc_middle/src/ty/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ pub use self::closure::{
8787
CAPTURE_STRUCT_LOCAL,
8888
};
8989
pub use self::consts::{
90-
Const, ConstData, ConstInt, ConstKind, Expr, ScalarInt, UnevaluatedConst, ValTree,
90+
Const, ConstData, ConstInt, ConstKind, Expr, ExprKind, ScalarInt, UnevaluatedConst, ValTree,
9191
};
9292
pub use self::context::{
9393
tls, CtxtInterners, CurrentGcx, DeducedParamAttrs, Feed, FreeRegionInfo, GlobalCtxt, Lift,

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

Lines changed: 44 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,8 +1533,10 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
15331533
print_ty: bool,
15341534
) -> Result<(), PrintError> {
15351535
define_scoped_cx!(self);
1536-
match expr {
1537-
Expr::Binop(op, c1, c2) => {
1536+
match expr.kind {
1537+
ty::ExprKind::Binop(op) => {
1538+
let (_, _, c1, c2) = expr.binop_args();
1539+
15381540
let precedence = |binop: rustc_middle::mir::BinOp| {
15391541
use rustc_ast::util::parser::AssocOp;
15401542
AssocOp::from_ast_binop(binop.to_hir_binop().into()).precedence()
@@ -1543,22 +1545,26 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
15431545
let formatted_op = op.to_hir_binop().as_str();
15441546
let (lhs_parenthesized, rhs_parenthesized) = match (c1.kind(), c2.kind()) {
15451547
(
1546-
ty::ConstKind::Expr(Expr::Binop(lhs_op, _, _)),
1547-
ty::ConstKind::Expr(Expr::Binop(rhs_op, _, _)),
1548+
ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(lhs_op), .. }),
1549+
ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(rhs_op), .. }),
15481550
) => (precedence(lhs_op) < op_precedence, precedence(rhs_op) < op_precedence),
1549-
(ty::ConstKind::Expr(Expr::Binop(lhs_op, ..)), ty::ConstKind::Expr(_)) => {
1550-
(precedence(lhs_op) < op_precedence, true)
1551-
}
1552-
(ty::ConstKind::Expr(_), ty::ConstKind::Expr(Expr::Binop(rhs_op, ..))) => {
1553-
(true, precedence(rhs_op) < op_precedence)
1554-
}
1551+
(
1552+
ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(lhs_op), .. }),
1553+
ty::ConstKind::Expr(_),
1554+
) => (precedence(lhs_op) < op_precedence, true),
1555+
(
1556+
ty::ConstKind::Expr(_),
1557+
ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(rhs_op), .. }),
1558+
) => (true, precedence(rhs_op) < op_precedence),
15551559
(ty::ConstKind::Expr(_), ty::ConstKind::Expr(_)) => (true, true),
1556-
(ty::ConstKind::Expr(Expr::Binop(lhs_op, ..)), _) => {
1557-
(precedence(lhs_op) < op_precedence, false)
1558-
}
1559-
(_, ty::ConstKind::Expr(Expr::Binop(rhs_op, ..))) => {
1560-
(false, precedence(rhs_op) < op_precedence)
1561-
}
1560+
(
1561+
ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(lhs_op), .. }),
1562+
_,
1563+
) => (precedence(lhs_op) < op_precedence, false),
1564+
(
1565+
_,
1566+
ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(rhs_op), .. }),
1567+
) => (false, precedence(rhs_op) < op_precedence),
15621568
(ty::ConstKind::Expr(_), _) => (true, false),
15631569
(_, ty::ConstKind::Expr(_)) => (false, true),
15641570
_ => (false, false),
@@ -1574,7 +1580,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
15741580
rhs_parenthesized,
15751581
)?;
15761582
}
1577-
Expr::UnOp(op, ct) => {
1583+
ty::ExprKind::UnOp(op) => {
1584+
let (_, ct) = expr.unop_args();
1585+
15781586
use rustc_middle::mir::UnOp;
15791587
let formatted_op = match op {
15801588
UnOp::Not => "!",
@@ -1583,7 +1591,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
15831591
};
15841592
let parenthesized = match ct.kind() {
15851593
_ if op == UnOp::PtrMetadata => true,
1586-
ty::ConstKind::Expr(Expr::UnOp(c_op, ..)) => c_op != op,
1594+
ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::UnOp(c_op), .. }) => {
1595+
c_op != op
1596+
}
15871597
ty::ConstKind::Expr(_) => true,
15881598
_ => false,
15891599
};
@@ -1593,61 +1603,37 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
15931603
parenthesized,
15941604
)?
15951605
}
1596-
Expr::FunctionCall(fn_def, fn_args) => {
1597-
use ty::TyKind;
1598-
match fn_def.ty().kind() {
1599-
TyKind::FnDef(def_id, gen_args) => {
1600-
p!(print_value_path(*def_id, gen_args), "(");
1601-
if print_ty {
1602-
let tcx = self.tcx();
1603-
let sig = tcx.fn_sig(def_id).instantiate(tcx, gen_args).skip_binder();
1604-
1605-
let mut args_with_ty = fn_args.iter().map(|ct| (ct, ct.ty()));
1606-
let output_ty = sig.output();
1607-
1608-
if let Some((ct, ty)) = args_with_ty.next() {
1609-
self.typed_value(
1610-
|this| this.pretty_print_const(ct, print_ty),
1611-
|this| this.pretty_print_type(ty),
1612-
": ",
1613-
)?;
1614-
for (ct, ty) in args_with_ty {
1615-
p!(", ");
1616-
self.typed_value(
1617-
|this| this.pretty_print_const(ct, print_ty),
1618-
|this| this.pretty_print_type(ty),
1619-
": ",
1620-
)?;
1621-
}
1622-
}
1623-
p!(write(") -> {output_ty}"));
1624-
} else {
1625-
p!(comma_sep(fn_args.iter()), ")");
1626-
}
1627-
}
1628-
_ => bug!("unexpected type of fn def"),
1629-
}
1606+
ty::ExprKind::FunctionCall => {
1607+
let (_, fn_def, fn_args) = expr.call_args();
1608+
1609+
write!(self, "(")?;
1610+
self.pretty_print_const(fn_def, print_ty)?;
1611+
p!(")(", comma_sep(fn_args), ")");
16301612
}
1631-
Expr::Cast(kind, ct, ty) => {
1613+
ty::ExprKind::Cast(kind) => {
1614+
let (_, value, to_ty) = expr.cast_args();
1615+
16321616
use ty::abstract_const::CastKind;
16331617
if kind == CastKind::As || (kind == CastKind::Use && self.should_print_verbose()) {
1634-
let parenthesized = match ct.kind() {
1635-
ty::ConstKind::Expr(Expr::Cast(_, _, _)) => false,
1618+
let parenthesized = match value.kind() {
1619+
ty::ConstKind::Expr(ty::Expr {
1620+
kind: ty::ExprKind::Cast { .. }, ..
1621+
}) => false,
16361622
ty::ConstKind::Expr(_) => true,
16371623
_ => false,
16381624
};
16391625
self.maybe_parenthesized(
16401626
|this| {
16411627
this.typed_value(
1642-
|this| this.pretty_print_const(ct, print_ty),
1643-
|this| this.pretty_print_type(ty),
1628+
|this| this.pretty_print_const(value, print_ty),
1629+
|this| this.pretty_print_type(to_ty),
16441630
" as ",
16451631
)
16461632
},
16471633
parenthesized,
16481634
)?;
16491635
} else {
1650-
self.pretty_print_const(ct, print_ty)?
1636+
self.pretty_print_const(value, print_ty)?
16511637
}
16521638
}
16531639
}

‎compiler/rustc_middle/src/ty/relate.rs

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
77
use crate::ty::error::{ExpectedFound, TypeError};
88
use crate::ty::{
9-
self, ExistentialPredicate, ExistentialPredicateStableCmpExt as _, Expr, GenericArg,
10-
GenericArgKind, GenericArgsRef, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable,
9+
self, ExistentialPredicate, ExistentialPredicateStableCmpExt as _, GenericArg, GenericArgKind,
10+
GenericArgsRef, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable,
1111
};
1212
use rustc_hir as hir;
1313
use rustc_hir::def_id::DefId;
@@ -665,46 +665,18 @@ pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>(
665665
a.ty(),
666666
));
667667
}
668-
// Before calling relate on exprs, it is necessary to ensure that the nested consts
669-
// have identical types.
670668
(ty::ConstKind::Expr(ae), ty::ConstKind::Expr(be)) => {
671-
let r = relation;
672-
673-
// FIXME(generic_const_exprs): is it possible to relate two consts which are not identical
674-
// exprs? Should we care about that?
675-
// FIXME(generic_const_exprs): relating the `ty()`s is a little weird since it is supposed to
676-
// ICE If they mismatch. Unfortunately `ConstKind::Expr` is a little special and can be thought
677-
// of as being generic over the argument types, however this is implicit so these types don't get
678-
// related when we relate the args of the item this const arg is for.
679-
let expr = match (ae, be) {
680-
(Expr::Binop(a_op, al, ar), Expr::Binop(b_op, bl, br)) if a_op == b_op => {
681-
r.relate(al.ty(), bl.ty())?;
682-
r.relate(ar.ty(), br.ty())?;
683-
Expr::Binop(a_op, r.consts(al, bl)?, r.consts(ar, br)?)
684-
}
685-
(Expr::UnOp(a_op, av), Expr::UnOp(b_op, bv)) if a_op == b_op => {
686-
r.relate(av.ty(), bv.ty())?;
687-
Expr::UnOp(a_op, r.consts(av, bv)?)
688-
}
689-
(Expr::Cast(ak, av, at), Expr::Cast(bk, bv, bt)) if ak == bk => {
690-
r.relate(av.ty(), bv.ty())?;
691-
Expr::Cast(ak, r.consts(av, bv)?, r.tys(at, bt)?)
692-
}
693-
(Expr::FunctionCall(af, aa), Expr::FunctionCall(bf, ba))
694-
if aa.len() == ba.len() =>
695-
{
696-
r.relate(af.ty(), bf.ty())?;
697-
let func = r.consts(af, bf)?;
698-
let mut related_args = Vec::with_capacity(aa.len());
699-
for (a_arg, b_arg) in aa.iter().zip(ba.iter()) {
700-
related_args.push(r.consts(a_arg, b_arg)?);
701-
}
702-
let related_args = tcx.mk_const_list(&related_args);
703-
Expr::FunctionCall(func, related_args)
704-
}
669+
match (ae.kind, be.kind) {
670+
(ty::ExprKind::Binop(a_binop), ty::ExprKind::Binop(b_binop))
671+
if a_binop == b_binop => {}
672+
(ty::ExprKind::UnOp(a_unop), ty::ExprKind::UnOp(b_unop)) if a_unop == b_unop => {}
673+
(ty::ExprKind::FunctionCall, ty::ExprKind::FunctionCall) => {}
674+
(ty::ExprKind::Cast(a_kind), ty::ExprKind::Cast(b_kind)) if a_kind == b_kind => {}
705675
_ => return Err(TypeError::ConstMismatch(expected_found(a, b))),
706-
};
707-
return Ok(ty::Const::new_expr(tcx, expr, a.ty()));
676+
}
677+
678+
let args = relation.relate(ae.args(), be.args())?;
679+
return Ok(ty::Const::new_expr(tcx, ty::Expr::new(ae.kind, args), a.ty()));
708680
}
709681
_ => false,
710682
};

‎compiler/rustc_middle/src/ty/structural_impls.rs

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -147,14 +147,27 @@ impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::consts::Expr<'tcx> {
147147
this: WithInfcx<'_, Infcx, &Self>,
148148
f: &mut core::fmt::Formatter<'_>,
149149
) -> core::fmt::Result {
150-
match this.data {
151-
ty::Expr::Binop(op, lhs, rhs) => {
152-
write!(f, "({op:?}: {:?}, {:?})", &this.wrap(lhs), &this.wrap(rhs))
150+
match this.data.kind {
151+
ty::ExprKind::Binop(op) => {
152+
let (lhs_ty, rhs_ty, lhs, rhs) = this.data.binop_args();
153+
write!(
154+
f,
155+
"({op:?}: ({:?}: {:?}), ({:?}: {:?}))",
156+
&this.wrap(lhs),
157+
&this.wrap(lhs_ty),
158+
&this.wrap(rhs),
159+
&this.wrap(rhs_ty),
160+
)
153161
}
154-
ty::Expr::UnOp(op, rhs) => write!(f, "({op:?}: {:?})", &this.wrap(rhs)),
155-
ty::Expr::FunctionCall(func, args) => {
156-
write!(f, "{:?}(", &this.wrap(func))?;
157-
for arg in args.as_slice().iter().rev().skip(1).rev() {
162+
ty::ExprKind::UnOp(op) => {
163+
let (rhs_ty, rhs) = this.data.unop_args();
164+
write!(f, "({op:?}: ({:?}: {:?}))", &this.wrap(rhs), &this.wrap(rhs_ty))
165+
}
166+
ty::ExprKind::FunctionCall => {
167+
let (func_ty, func, args) = this.data.call_args();
168+
let args = args.collect::<Vec<_>>();
169+
write!(f, "({:?}: {:?})(", &this.wrap(func), &this.wrap(func_ty))?;
170+
for arg in args.iter().rev().skip(1).rev() {
158171
write!(f, "{:?}, ", &this.wrap(arg))?;
159172
}
160173
if let Some(arg) = args.last() {
@@ -163,8 +176,15 @@ impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::consts::Expr<'tcx> {
163176

164177
write!(f, ")")
165178
}
166-
ty::Expr::Cast(cast_kind, lhs, rhs) => {
167-
write!(f, "({cast_kind:?}: {:?}, {:?})", &this.wrap(lhs), &this.wrap(rhs))
179+
ty::ExprKind::Cast(kind) => {
180+
let (value_ty, value, to_ty) = this.data.cast_args();
181+
write!(
182+
f,
183+
"({kind:?}: ({:?}: {:?}), {:?})",
184+
&this.wrap(value),
185+
&this.wrap(value_ty),
186+
&this.wrap(to_ty)
187+
)
168188
}
169189
}
170190
}

‎compiler/rustc_middle/src/ty/walk.rs

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -222,24 +222,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
222222
| ty::ConstKind::Value(_)
223223
| ty::ConstKind::Error(_) => {}
224224

225-
ty::ConstKind::Expr(expr) => match expr {
226-
ty::Expr::UnOp(_, v) => push_inner(stack, v.into()),
227-
ty::Expr::Binop(_, l, r) => {
228-
push_inner(stack, r.into());
229-
push_inner(stack, l.into())
230-
}
231-
ty::Expr::FunctionCall(func, args) => {
232-
for a in args.iter().rev() {
233-
push_inner(stack, a.into());
234-
}
235-
push_inner(stack, func.into());
236-
}
237-
ty::Expr::Cast(_, c, t) => {
238-
push_inner(stack, t.into());
239-
push_inner(stack, c.into());
240-
}
241-
},
242-
225+
ty::ConstKind::Expr(expr) => stack.extend(expr.args().iter().rev()),
243226
ty::ConstKind::Unevaluated(ct) => {
244227
stack.extend(ct.args.iter().rev());
245228
}

‎compiler/rustc_ty_utils/src/consts.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -148,17 +148,24 @@ fn recurse_build<'tcx>(
148148
for &id in args.iter() {
149149
new_args.push(recurse_build(tcx, body, id, root_span)?);
150150
}
151-
let new_args = tcx.mk_const_list(&new_args);
152-
ty::Const::new_expr(tcx, Expr::FunctionCall(fun, new_args), node.ty)
151+
ty::Const::new_expr(
152+
tcx,
153+
Expr::new_call(tcx, fun.ty(), fun, new_args.into_iter()),
154+
node.ty,
155+
)
153156
}
154157
&ExprKind::Binary { op, lhs, rhs } if check_binop(op) => {
155158
let lhs = recurse_build(tcx, body, lhs, root_span)?;
156159
let rhs = recurse_build(tcx, body, rhs, root_span)?;
157-
ty::Const::new_expr(tcx, Expr::Binop(op, lhs, rhs), node.ty)
160+
ty::Const::new_expr(
161+
tcx,
162+
Expr::new_binop(tcx, op, lhs.ty(), rhs.ty(), lhs, rhs),
163+
node.ty,
164+
)
158165
}
159166
&ExprKind::Unary { op, arg } if check_unop(op) => {
160167
let arg = recurse_build(tcx, body, arg, root_span)?;
161-
ty::Const::new_expr(tcx, Expr::UnOp(op, arg), node.ty)
168+
ty::Const::new_expr(tcx, Expr::new_unop(tcx, op, arg.ty(), arg), node.ty)
162169
}
163170
// This is necessary so that the following compiles:
164171
//
@@ -178,12 +185,22 @@ fn recurse_build<'tcx>(
178185
// "coercion cast" i.e. using a coercion or is a no-op.
179186
// This is important so that `N as usize as usize` doesn't unify with `N as usize`. (untested)
180187
&ExprKind::Use { source } => {
181-
let arg = recurse_build(tcx, body, source, root_span)?;
182-
ty::Const::new_expr(tcx, Expr::Cast(CastKind::Use, arg, node.ty), node.ty)
188+
let value_ty = body.exprs[source].ty;
189+
let value = recurse_build(tcx, body, source, root_span)?;
190+
ty::Const::new_expr(
191+
tcx,
192+
Expr::new_cast(tcx, CastKind::Use, value_ty, value, node.ty),
193+
node.ty,
194+
)
183195
}
184196
&ExprKind::Cast { source } => {
185-
let arg = recurse_build(tcx, body, source, root_span)?;
186-
ty::Const::new_expr(tcx, Expr::Cast(CastKind::As, arg, node.ty), node.ty)
197+
let value_ty = body.exprs[source].ty;
198+
let value = recurse_build(tcx, body, source, root_span)?;
199+
ty::Const::new_expr(
200+
tcx,
201+
Expr::new_cast(tcx, CastKind::As, value_ty, value, node.ty),
202+
node.ty,
203+
)
187204
}
188205
ExprKind::Borrow { arg, .. } => {
189206
let arg_node = &body.exprs[*arg];

‎tests/ui/const-generics/generic_const_exprs/eval-privacy.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ where
1515
{
1616
type AssocTy = Const<{ my_const_fn(U) }>;
1717
//~^ ERROR private type
18+
//~| ERROR private type
1819
fn assoc_fn() -> Self::AssocTy {
1920
Const
2021
}

‎tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ LL | type AssocTy = Const<{ my_const_fn(U) }>;
77
LL | const fn my_const_fn(val: u8) -> u8 {
88
| ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
99

10-
error: aborting due to 1 previous error
10+
error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
11+
--> $DIR/eval-privacy.rs:16:5
12+
|
13+
LL | type AssocTy = Const<{ my_const_fn(U) }>;
14+
| ^^^^^^^^^^^^ can't leak private type
15+
...
16+
LL | const fn my_const_fn(val: u8) -> u8 {
17+
| ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
18+
|
19+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
20+
21+
error: aborting due to 2 previous errors
1122

1223
For more information about this error, try `rustc --explain E0446`.

‎tests/ui/privacy/where-priv-type.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ where
7474
{
7575
type AssocTy = Const<{ my_const_fn(U) }>;
7676
//~^ ERROR private type
77+
//~| ERROR private type
7778
fn assoc_fn() -> Self::AssocTy {
7879
Const
7980
}

‎tests/ui/privacy/where-priv-type.stderr

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,17 @@ LL | type AssocTy = Const<{ my_const_fn(U) }>;
7777
LL | const fn my_const_fn(val: u8) -> u8 {
7878
| ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
7979

80-
error: aborting due to 1 previous error; 5 warnings emitted
80+
error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
81+
--> $DIR/where-priv-type.rs:75:5
82+
|
83+
LL | type AssocTy = Const<{ my_const_fn(U) }>;
84+
| ^^^^^^^^^^^^ can't leak private type
85+
...
86+
LL | const fn my_const_fn(val: u8) -> u8 {
87+
| ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
88+
|
89+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
90+
91+
error: aborting due to 2 previous errors; 5 warnings emitted
8192

8293
For more information about this error, try `rustc --explain E0446`.

0 commit comments

Comments
 (0)
Please sign in to comment.