Skip to content

Commit af76a24

Browse files
committed
MGCA: Support tuple expressions as direct const arguments
1 parent 0aced20 commit af76a24

18 files changed

Lines changed: 177 additions & 53 deletions

File tree

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2427,6 +2427,23 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
24272427
kind: hir::ConstArgKind::TupleCall(qpath, lowered_args),
24282428
}
24292429
}
2430+
ExprKind::Tup(exprs) => {
2431+
let exprs = self.arena.alloc_from_iter(exprs.iter().map(|expr| {
2432+
let expr = if let ExprKind::ConstBlock(anon_const) = &expr.kind {
2433+
let def_id = self.local_def_id(anon_const.id);
2434+
let def_kind = self.tcx.def_kind(def_id);
2435+
assert_eq!(DefKind::AnonConst, def_kind);
2436+
2437+
self.lower_anon_const_to_const_arg(anon_const)
2438+
} else {
2439+
self.lower_expr_to_const_arg_direct(&expr)
2440+
};
2441+
2442+
&*self.arena.alloc(expr)
2443+
}));
2444+
2445+
ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Tup(expr.span, exprs) }
2446+
}
24302447
ExprKind::Path(qself, path) => {
24312448
let qpath = self.lower_qpath(
24322449
expr.id,
@@ -2495,6 +2512,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
24952512
| ExprKind::Path(..)
24962513
| ExprKind::Struct(..)
24972514
| ExprKind::Call(..)
2515+
| ExprKind::Tup(..)
24982516
)
24992517
{
25002518
return self.lower_expr_to_const_arg_direct(expr);

compiler/rustc_hir/src/hir.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,7 @@ impl<'hir, Unambig> ConstArg<'hir, Unambig> {
497497

498498
pub fn span(&self) -> Span {
499499
match self.kind {
500+
ConstArgKind::Tup(span, ..) => span,
500501
ConstArgKind::Struct(path, _) => path.span(),
501502
ConstArgKind::Path(path) => path.span(),
502503
ConstArgKind::TupleCall(path, _) => path.span(),
@@ -511,6 +512,7 @@ impl<'hir, Unambig> ConstArg<'hir, Unambig> {
511512
#[derive(Clone, Copy, Debug, HashStable_Generic)]
512513
#[repr(u8, C)]
513514
pub enum ConstArgKind<'hir, Unambig = ()> {
515+
Tup(Span, &'hir [&'hir ConstArg<'hir, Unambig>]),
514516
/// **Note:** Currently this is only used for bare const params
515517
/// (`N` where `fn foo<const N: usize>(...)`),
516518
/// not paths to any const (`N` where `const N: usize = ...`).

compiler/rustc_hir/src/intravisit.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,6 +1081,10 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>(
10811081
let ConstArg { hir_id, kind } = const_arg;
10821082
try_visit!(visitor.visit_id(*hir_id));
10831083
match kind {
1084+
ConstArgKind::Tup(_, exprs) => {
1085+
walk_list!(visitor, visit_const_arg, *exprs);
1086+
V::Result::output()
1087+
}
10841088
ConstArgKind::Struct(qpath, field_exprs) => {
10851089
try_visit!(visitor.visit_qpath(qpath, *hir_id, qpath.span()));
10861090

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,9 +1493,10 @@ fn const_param_default<'tcx>(
14931493
};
14941494
let icx = ItemCtxt::new(tcx, def_id);
14951495
let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
1496-
let ct = icx
1497-
.lowerer()
1498-
.lower_const_arg(default_ct, FeedConstTy::Param(def_id.to_def_id(), identity_args));
1496+
let ct = icx.lowerer().lower_const_arg(
1497+
default_ct,
1498+
FeedConstTy::with_type_of(tcx, def_id.to_def_id(), identity_args),
1499+
);
14991500
ty::EarlyBinder::bind(ct)
15001501
}
15011502

@@ -1553,7 +1554,7 @@ fn const_of_item<'tcx>(
15531554
let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
15541555
let ct = icx
15551556
.lowerer()
1556-
.lower_const_arg(ct_arg, FeedConstTy::Param(def_id.to_def_id(), identity_args));
1557+
.lower_const_arg(ct_arg, FeedConstTy::with_type_of(tcx, def_id.to_def_id(), identity_args));
15571558
if let Err(e) = icx.check_tainted_by_errors()
15581559
&& !ct.references_error()
15591560
{

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -259,17 +259,26 @@ impl AssocItemQSelf {
259259
/// Use this enum with `<dyn HirTyLowerer>::lower_const_arg` to instruct it with the
260260
/// desired behavior.
261261
#[derive(Debug, Clone, Copy)]
262-
pub enum FeedConstTy<'a, 'tcx> {
263-
/// Feed the type.
264-
///
262+
pub enum FeedConstTy<'tcx> {
263+
/// Feed the type to the (anno) const arg.
264+
WithTy(Ty<'tcx>),
265+
/// Don't feed the type.
266+
No,
267+
}
268+
269+
impl<'tcx> FeedConstTy<'tcx> {
265270
/// The `DefId` belongs to the const param that we are supplying
266271
/// this (anon) const arg to.
267272
///
268273
/// The list of generic args is used to instantiate the parameters
269274
/// used by the type of the const param specified by `DefId`.
270-
Param(DefId, &'a [ty::GenericArg<'tcx>]),
271-
/// Don't feed the type.
272-
No,
275+
pub fn with_type_of(
276+
tcx: TyCtxt<'tcx>,
277+
def_id: DefId,
278+
generic_args: &[ty::GenericArg<'tcx>],
279+
) -> Self {
280+
Self::WithTy(tcx.type_of(def_id).instantiate(tcx, generic_args))
281+
}
273282
}
274283

275284
#[derive(Debug, Clone, Copy)]
@@ -723,7 +732,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
723732
// Ambig portions of `ConstArg` are handled in the match arm below
724733
.lower_const_arg(
725734
ct.as_unambig_ct(),
726-
FeedConstTy::Param(param.def_id, preceding_args),
735+
FeedConstTy::with_type_of(tcx, param.def_id, preceding_args),
727736
)
728737
.into(),
729738
(&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
@@ -2303,15 +2312,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23032312
pub fn lower_const_arg(
23042313
&self,
23052314
const_arg: &hir::ConstArg<'tcx>,
2306-
feed: FeedConstTy<'_, 'tcx>,
2315+
feed: FeedConstTy<'tcx>,
23072316
) -> Const<'tcx> {
23082317
let tcx = self.tcx();
23092318

2310-
if let FeedConstTy::Param(param_def_id, args) = feed
2319+
if let FeedConstTy::WithTy(anon_const_type) = feed
23112320
&& let hir::ConstArgKind::Anon(anon) = &const_arg.kind
23122321
{
2313-
let anon_const_type = tcx.type_of(param_def_id).instantiate(tcx, args);
2314-
23152322
// FIXME(generic_const_parameter_types): Ideally we remove these errors below when
23162323
// we have the ability to intermix typeck of anon const const args with the parent
23172324
// bodies typeck.
@@ -2352,14 +2359,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23522359
return ty::Const::new_error(tcx, e);
23532360
}
23542361

2355-
tcx.feed_anon_const_type(
2356-
anon.def_id,
2357-
ty::EarlyBinder::bind(tcx.type_of(param_def_id).instantiate(tcx, args)),
2358-
);
2362+
tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(anon_const_type));
23592363
}
23602364

23612365
let hir_id = const_arg.hir_id;
23622366
match const_arg.kind {
2367+
hir::ConstArgKind::Tup(span, exprs) => self.lower_const_arg_tup(exprs, feed, span),
23632368
hir::ConstArgKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
23642369
debug!(?maybe_qself, ?path);
23652370
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
@@ -2464,7 +2469,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
24642469
.iter()
24652470
.zip(args)
24662471
.map(|(field_def, arg)| {
2467-
self.lower_const_arg(arg, FeedConstTy::Param(field_def.did, adt_args))
2472+
self.lower_const_arg(arg, FeedConstTy::with_type_of(tcx, field_def.did, adt_args))
24682473
})
24692474
.collect::<Vec<_>>();
24702475

@@ -2480,6 +2485,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
24802485
ty::Const::new_value(tcx, valtree, adt_ty)
24812486
}
24822487

2488+
fn lower_const_arg_tup(
2489+
&self,
2490+
exprs: &'tcx [&'tcx hir::ConstArg<'tcx>],
2491+
feed: FeedConstTy<'tcx>,
2492+
span: Span,
2493+
) -> Const<'tcx> {
2494+
let tcx = self.tcx();
2495+
2496+
let FeedConstTy::WithTy(ty) = feed else {
2497+
return Const::new_error_with_message(tcx, span, "unsupported const tuple");
2498+
};
2499+
2500+
let ty::Tuple(tys) = ty.kind() else {
2501+
return Const::new_error_with_message(tcx, span, "const tuple must have a tuple type");
2502+
};
2503+
2504+
let exprs = exprs
2505+
.iter()
2506+
.zip(tys.iter())
2507+
.map(|(expr, ty)| self.lower_const_arg(expr, FeedConstTy::WithTy(ty)))
2508+
.collect::<Vec<_>>();
2509+
2510+
let valtree = ty::ValTree::from_branches(tcx, exprs);
2511+
ty::Const::new_value(tcx, valtree, ty)
2512+
}
2513+
24832514
fn lower_const_arg_struct(
24842515
&self,
24852516
hir_id: HirId,
@@ -2558,7 +2589,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
25582589
return ty::Const::new_error(tcx, e);
25592590
}
25602591

2561-
self.lower_const_arg(expr.expr, FeedConstTy::Param(field_def.did, adt_args))
2592+
self.lower_const_arg(
2593+
expr.expr,
2594+
FeedConstTy::with_type_of(tcx, field_def.did, adt_args),
2595+
)
25622596
}
25632597
None => {
25642598
let e = tcx.dcx().span_err(

compiler/rustc_hir_analysis/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
301301
pub fn lower_const_arg_for_rustdoc<'tcx>(
302302
tcx: TyCtxt<'tcx>,
303303
hir_ct: &hir::ConstArg<'tcx>,
304-
feed: FeedConstTy<'_, 'tcx>,
304+
feed: FeedConstTy<'tcx>,
305305
) -> Const<'tcx> {
306306
let env_def_id = tcx.hir_get_parent_item(hir_ct.hir_id);
307307
collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, feed)

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,6 +1141,16 @@ impl<'a> State<'a> {
11411141

11421142
fn print_const_arg(&mut self, const_arg: &hir::ConstArg<'_>) {
11431143
match &const_arg.kind {
1144+
ConstArgKind::Tup(_, exprs) => {
1145+
self.popen();
1146+
self.commasep_cmnt(
1147+
Inconsistent,
1148+
exprs,
1149+
|s, arg| s.print_const_arg(arg),
1150+
|arg| arg.span(),
1151+
);
1152+
self.pclose();
1153+
}
11441154
ConstArgKind::Struct(qpath, fields) => self.print_const_struct(qpath, fields),
11451155
ConstArgKind::TupleCall(qpath, args) => self.print_const_ctor(qpath, args),
11461156
ConstArgKind::Path(qpath) => self.print_qpath(qpath, true),

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
525525
pub(crate) fn lower_const_arg(
526526
&self,
527527
const_arg: &'tcx hir::ConstArg<'tcx>,
528-
feed: FeedConstTy<'_, 'tcx>,
528+
feed: FeedConstTy<'tcx>,
529529
) -> ty::Const<'tcx> {
530530
let ct = self.lowerer().lower_const_arg(const_arg, feed);
531531
self.register_wf_obligation(
@@ -1228,7 +1228,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12281228
// Ambiguous parts of `ConstArg` are handled in the match arms below
12291229
.lower_const_arg(
12301230
ct.as_unambig_ct(),
1231-
FeedConstTy::Param(param.def_id, preceding_args),
1231+
FeedConstTy::with_type_of(self.fcx.tcx, param.def_id, preceding_args),
12321232
)
12331233
.into(),
12341234
(&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {

compiler/rustc_hir_typeck/src/method/confirm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
447447
// We handle the ambig portions of `ConstArg` in the match arms below
448448
.lower_const_arg(
449449
ct.as_unambig_ct(),
450-
FeedConstTy::Param(param.def_id, preceding_args),
450+
FeedConstTy::with_type_of(self.cfcx.tcx, param.def_id, preceding_args),
451451
)
452452
.into(),
453453
(GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,6 +1442,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14421442
hir::ConstArgKind::Error(..)
14431443
| hir::ConstArgKind::Struct(..)
14441444
| hir::ConstArgKind::TupleCall(..)
1445+
| hir::ConstArgKind::Tup(..)
14451446
| hir::ConstArgKind::Path(..)
14461447
| hir::ConstArgKind::Infer(..) => true,
14471448
hir::ConstArgKind::Anon(..) => false,

0 commit comments

Comments
 (0)