Skip to content

Commit 45c921e

Browse files
authored
Rollup merge of rust-lang#150786 - mgca-array, r=BoxyUwU
mGCA: Support array expression as direct const arguments tracking issue: rust-lang#132980 resolve: rust-lang#150612 Support array expression as direct const arguments (e. g. [1, 2, N]) in min_generic_const_args. todo: * [x] Rebase another mGCA PR * [x] Add more test case * [x] Modify clippy code
2 parents cafda8d + 49b8c2b commit 45c921e

20 files changed

Lines changed: 243 additions & 5 deletions

File tree

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2517,6 +2517,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
25172517
span,
25182518
}
25192519
}
2520+
ExprKind::Array(elements) => {
2521+
let lowered_elems = self.arena.alloc_from_iter(elements.iter().map(|element| {
2522+
let const_arg = if let ExprKind::ConstBlock(anon_const) = &element.kind {
2523+
let def_id = self.local_def_id(anon_const.id);
2524+
assert_eq!(DefKind::AnonConst, self.tcx.def_kind(def_id));
2525+
self.lower_anon_const_to_const_arg(anon_const)
2526+
} else {
2527+
self.lower_expr_to_const_arg_direct(element)
2528+
};
2529+
&*self.arena.alloc(const_arg)
2530+
}));
2531+
let array_expr = self.arena.alloc(hir::ConstArgArrayExpr {
2532+
span: self.lower_span(expr.span),
2533+
elems: lowered_elems,
2534+
});
2535+
2536+
ConstArg {
2537+
hir_id: self.next_id(),
2538+
kind: hir::ConstArgKind::Array(array_expr),
2539+
span,
2540+
}
2541+
}
25202542
ExprKind::Underscore => ConstArg {
25212543
hir_id: self.lower_node_id(expr.id),
25222544
kind: hir::ConstArgKind::Infer(()),
@@ -2532,6 +2554,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
25322554
| ExprKind::Struct(..)
25332555
| ExprKind::Call(..)
25342556
| ExprKind::Tup(..)
2557+
| ExprKind::Array(..)
25352558
)
25362559
{
25372560
return self.lower_expr_to_const_arg_direct(expr);

compiler/rustc_hir/src/hir.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,8 @@ pub enum ConstArgKind<'hir, Unambig = ()> {
513513
Struct(QPath<'hir>, &'hir [&'hir ConstArgExprField<'hir>]),
514514
/// Tuple constructor variant
515515
TupleCall(QPath<'hir>, &'hir [&'hir ConstArg<'hir>]),
516+
/// Array literal argument
517+
Array(&'hir ConstArgArrayExpr<'hir>),
516518
/// Error const
517519
Error(ErrorGuaranteed),
518520
/// This variant is not always used to represent inference consts, sometimes
@@ -529,6 +531,12 @@ pub struct ConstArgExprField<'hir> {
529531
pub expr: &'hir ConstArg<'hir>,
530532
}
531533

534+
#[derive(Clone, Copy, Debug, HashStable_Generic)]
535+
pub struct ConstArgArrayExpr<'hir> {
536+
pub span: Span,
537+
pub elems: &'hir [&'hir ConstArg<'hir>],
538+
}
539+
532540
#[derive(Clone, Copy, Debug, HashStable_Generic)]
533541
pub struct InferArg {
534542
#[stable_hasher(ignore)]

compiler/rustc_hir/src/intravisit.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,12 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>(
11011101
}
11021102
V::Result::output()
11031103
}
1104+
ConstArgKind::Array(array_expr) => {
1105+
for arg in array_expr.elems {
1106+
try_visit!(visitor.visit_const_arg_unambig(*arg));
1107+
}
1108+
V::Result::output()
1109+
}
11041110
ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, *hir_id, qpath.span()),
11051111
ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon),
11061112
ConstArgKind::Error(_) => V::Result::output(), // errors and spans are not important

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2389,6 +2389,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23892389
hir::ConstArgKind::TupleCall(qpath, args) => {
23902390
self.lower_const_arg_tuple_call(hir_id, qpath, args, const_arg.span)
23912391
}
2392+
hir::ConstArgKind::Array(array_expr) => self.lower_const_arg_array(array_expr, feed),
23922393
hir::ConstArgKind::Anon(anon) => self.lower_const_arg_anon(anon),
23932394
hir::ConstArgKind::Infer(()) => self.ct_infer(None, const_arg.span),
23942395
hir::ConstArgKind::Error(e) => ty::Const::new_error(tcx, e),
@@ -2402,6 +2403,36 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
24022403
}
24032404
}
24042405

2406+
fn lower_const_arg_array(
2407+
&self,
2408+
array_expr: &'tcx hir::ConstArgArrayExpr<'tcx>,
2409+
feed: FeedConstTy<'tcx>,
2410+
) -> Const<'tcx> {
2411+
let tcx = self.tcx();
2412+
2413+
let FeedConstTy::WithTy(ty) = feed else {
2414+
return Const::new_error_with_message(tcx, array_expr.span, "unsupported const array");
2415+
};
2416+
2417+
let ty::Array(elem_ty, _) = ty.kind() else {
2418+
return Const::new_error_with_message(
2419+
tcx,
2420+
array_expr.span,
2421+
"const array must have an array type",
2422+
);
2423+
};
2424+
2425+
let elems = array_expr
2426+
.elems
2427+
.iter()
2428+
.map(|elem| self.lower_const_arg(elem, FeedConstTy::WithTy(*elem_ty)))
2429+
.collect::<Vec<_>>();
2430+
2431+
let valtree = ty::ValTree::from_branches(tcx, elems);
2432+
2433+
ty::Const::new_value(tcx, valtree, ty)
2434+
}
2435+
24052436
fn lower_const_arg_tuple_call(
24062437
&self,
24072438
hir_id: HirId,

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,7 @@ impl<'a> State<'a> {
11531153
}
11541154
ConstArgKind::Struct(qpath, fields) => self.print_const_struct(qpath, fields),
11551155
ConstArgKind::TupleCall(qpath, args) => self.print_const_ctor(qpath, args),
1156+
ConstArgKind::Array(..) => self.word("/* ARRAY EXPR */"),
11561157
ConstArgKind::Path(qpath) => self.print_qpath(qpath, true),
11571158
ConstArgKind::Anon(anon) => self.print_anon_const(anon),
11581159
ConstArgKind::Error(_) => self.word("/*ERROR*/"),

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,6 +1441,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14411441
// Skip encoding defs for these as they should not have had a `DefId` created
14421442
hir::ConstArgKind::Error(..)
14431443
| hir::ConstArgKind::Struct(..)
1444+
| hir::ConstArgKind::Array(..)
14441445
| hir::ConstArgKind::TupleCall(..)
14451446
| hir::ConstArgKind::Tup(..)
14461447
| hir::ConstArgKind::Path(..)

compiler/rustc_resolve/src/def_collector.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
419419

420420
// Avoid overwriting `const_arg_context` as we may want to treat const blocks
421421
// as being anon consts if we are inside a const argument.
422-
ExprKind::Struct(_) | ExprKind::Call(..) | ExprKind::Tup(..) => {
422+
ExprKind::Struct(_) | ExprKind::Call(..) | ExprKind::Tup(..) | ExprKind::Array(..) => {
423423
return visit::walk_expr(self, expr);
424424
}
425425
// FIXME(mgca): we may want to handle block labels in some manner

src/librustdoc/clean/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,9 @@ pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg<'tcx>) -> ConstantKind
330330
// FIXME(mgca): proper printing :3
331331
ConstantKind::Path { path: "/* TUPLE EXPR */".to_string().into() }
332332
}
333+
hir::ConstArgKind::Array(..) => {
334+
ConstantKind::Path { path: "/* ARRAY EXPR */".to_string().into() }
335+
}
333336
hir::ConstArgKind::Anon(anon) => ConstantKind::Anonymous { body: anon.body },
334337
hir::ConstArgKind::Infer(..) | hir::ConstArgKind::Error(..) => ConstantKind::Infer,
335338
hir::ConstArgKind::Literal(..) => {
@@ -1818,6 +1821,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
18181821
| hir::ConstArgKind::Path(..)
18191822
| hir::ConstArgKind::TupleCall(..)
18201823
| hir::ConstArgKind::Tup(..)
1824+
| hir::ConstArgKind::Array(..)
18211825
| hir::ConstArgKind::Literal(..) => {
18221826
let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, FeedConstTy::No);
18231827
print_const(cx, ct)

src/tools/clippy/clippy_lints/src/utils/author.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
322322
ConstArgKind::Struct(..) => chain!(self, "let ConstArgKind::Struct(..) = {const_arg}.kind"),
323323
ConstArgKind::TupleCall(..) => chain!(self, "let ConstArgKind::TupleCall(..) = {const_arg}.kind"),
324324
ConstArgKind::Tup(..) => chain!(self, "let ConstArgKind::Tup(..) = {const_arg}.kind"),
325+
ConstArgKind::Array(..) => chain!(self, "let ConstArgKind::Array(..) = {const_arg}.kind"),
325326
ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"),
326327
ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"),
327328
ConstArgKind::Literal(..) => chain!(self, "let ConstArgKind::Literal(..) = {const_arg}.kind")

src/tools/clippy/clippy_utils/src/consts.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,9 +1140,14 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx
11401140
ConstItemRhs::Body(body_id) => Some(tcx.hir_body(body_id).value),
11411141
ConstItemRhs::TypeConst(const_arg) => match const_arg.kind {
11421142
ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value),
1143-
ConstArgKind::Struct(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Tup(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) | ConstArgKind::Literal(..) => {
1144-
None
1145-
},
1143+
ConstArgKind::Struct(..)
1144+
| ConstArgKind::TupleCall(..)
1145+
| ConstArgKind::Tup(..)
1146+
| ConstArgKind::Path(_)
1147+
| ConstArgKind::Error(..)
1148+
| ConstArgKind::Infer(..)
1149+
| ConstArgKind::Literal(..)
1150+
| ConstArgKind::Array(..) => None,
11461151
},
11471152
}
11481153
}

0 commit comments

Comments
 (0)