Introduce hir::ConstArgKind::Array

This commit is contained in:
reddevilmidzy 2026-01-07 19:47:02 +09:00
parent 1191620b8c
commit fc06a57a78
8 changed files with 42 additions and 1 deletions

View file

@ -2517,6 +2517,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
span,
}
}
ExprKind::Array(elements) => {
let lowered_elems = self.arena.alloc_from_iter(elements.iter().map(|element| {
let const_arg = if let ExprKind::ConstBlock(anon_const) = &element.kind {
let def_id = self.local_def_id(anon_const.id);
assert_eq!(DefKind::AnonConst, self.tcx.def_kind(def_id));
self.lower_anon_const_to_const_arg(anon_const)
} else {
self.lower_expr_to_const_arg_direct(element)
};
&*self.arena.alloc(const_arg)
}));
let array_expr = self.arena.alloc(hir::ConstArgArrayExpr {
span: self.lower_span(expr.span),
elems: lowered_elems,
});
ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Array(array_expr) }
}
ExprKind::Underscore => ConstArg {
hir_id: self.lower_node_id(expr.id),
kind: hir::ConstArgKind::Infer(()),
@ -2532,6 +2550,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
| ExprKind::Struct(..)
| ExprKind::Call(..)
| ExprKind::Tup(..)
| ExprKind::Array(..)
)
{
return self.lower_expr_to_const_arg_direct(expr);

View file

@ -513,6 +513,8 @@ pub enum ConstArgKind<'hir, Unambig = ()> {
Struct(QPath<'hir>, &'hir [&'hir ConstArgExprField<'hir>]),
/// Tuple constructor variant
TupleCall(QPath<'hir>, &'hir [&'hir ConstArg<'hir>]),
/// Array literal argument
Array(&'hir ConstArgArrayExpr<'hir>),
/// Error const
Error(ErrorGuaranteed),
/// This variant is not always used to represent inference consts, sometimes
@ -529,6 +531,12 @@ pub struct ConstArgExprField<'hir> {
pub expr: &'hir ConstArg<'hir>,
}
#[derive(Clone, Copy, Debug, HashStable_Generic)]
pub struct ConstArgArrayExpr<'hir> {
pub span: Span,
pub elems: &'hir [&'hir ConstArg<'hir>],
}
#[derive(Clone, Copy, Debug, HashStable_Generic)]
pub struct InferArg {
#[stable_hasher(ignore)]

View file

@ -1101,6 +1101,12 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>(
}
V::Result::output()
}
ConstArgKind::Array(array_expr) => {
for arg in array_expr.elems {
try_visit!(visitor.visit_const_arg_unambig(*arg));
}
V::Result::output()
}
ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, *hir_id, qpath.span()),
ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon),
ConstArgKind::Error(_) => V::Result::output(), // errors and spans are not important

View file

@ -2389,6 +2389,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
hir::ConstArgKind::TupleCall(qpath, args) => {
self.lower_const_arg_tuple_call(hir_id, qpath, args, const_arg.span)
}
hir::ConstArgKind::Array(_array_expr) => {
span_bug!(const_arg.span(), "lowering `{:?}` is not yet implemented", const_arg)
}
hir::ConstArgKind::Anon(anon) => self.lower_const_arg_anon(anon),
hir::ConstArgKind::Infer(()) => self.ct_infer(None, const_arg.span),
hir::ConstArgKind::Error(e) => ty::Const::new_error(tcx, e),

View file

@ -1153,6 +1153,7 @@ impl<'a> State<'a> {
}
ConstArgKind::Struct(qpath, fields) => self.print_const_struct(qpath, fields),
ConstArgKind::TupleCall(qpath, args) => self.print_const_ctor(qpath, args),
ConstArgKind::Array(..) => self.word("/* ARRAY EXPR */"),
ConstArgKind::Path(qpath) => self.print_qpath(qpath, true),
ConstArgKind::Anon(anon) => self.print_anon_const(anon),
ConstArgKind::Error(_) => self.word("/*ERROR*/"),

View file

@ -1441,6 +1441,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// Skip encoding defs for these as they should not have had a `DefId` created
hir::ConstArgKind::Error(..)
| hir::ConstArgKind::Struct(..)
| hir::ConstArgKind::Array(..)
| hir::ConstArgKind::TupleCall(..)
| hir::ConstArgKind::Tup(..)
| hir::ConstArgKind::Path(..)

View file

@ -419,7 +419,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
// Avoid overwriting `const_arg_context` as we may want to treat const blocks
// as being anon consts if we are inside a const argument.
ExprKind::Struct(_) | ExprKind::Call(..) | ExprKind::Tup(..) => {
ExprKind::Struct(_) | ExprKind::Call(..) | ExprKind::Tup(..) | ExprKind::Array(..) => {
return visit::walk_expr(self, expr);
}
// FIXME(mgca): we may want to handle block labels in some manner

View file

@ -329,6 +329,8 @@ pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg<'tcx>) -> ConstantKind
hir::ConstArgKind::Tup(..) => {
// FIXME(mgca): proper printing :3
ConstantKind::Path { path: "/* TUPLE EXPR */".to_string().into() }
hir::ConstArgKind::Array(..) => {
ConstantKind::Path { path: "/* ARRAY EXPR */".to_string().into() }
}
hir::ConstArgKind::Anon(anon) => ConstantKind::Anonymous { body: anon.body },
hir::ConstArgKind::Infer(..) | hir::ConstArgKind::Error(..) => ConstantKind::Infer,
@ -1818,6 +1820,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
| hir::ConstArgKind::Path(..)
| hir::ConstArgKind::TupleCall(..)
| hir::ConstArgKind::Tup(..)
| hir::ConstArgKind::Array(..)
| hir::ConstArgKind::Literal(..) => {
let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, FeedConstTy::No);
print_const(cx, ct)