Skip to content

Commit 8a848d7

Browse files
committed
Introduce hir::ConstArgKind::Struct
1 parent 907492a commit 8a848d7

File tree

12 files changed

+150
-8
lines changed

12 files changed

+150
-8
lines changed

compiler/rustc_ast_lowering/src/index.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,13 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
281281
});
282282
}
283283

284+
fn visit_const_arg_expr_field(&mut self, field: &'hir ConstArgExprField<'hir>) {
285+
self.insert(field.span, field.hir_id, Node::ConstArgExprField(field));
286+
self.with_parent(field.hir_id, |this| {
287+
intravisit::walk_const_arg_expr_field(this, field);
288+
})
289+
}
290+
284291
fn visit_stmt(&mut self, stmt: &'hir Stmt<'hir>) {
285292
self.insert(stmt.span, stmt.hir_id, Node::Stmt(stmt));
286293

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2378,6 +2378,37 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23782378

23792379
ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Path(qpath) }
23802380
}
2381+
ExprKind::Struct(se) => {
2382+
let path = self.lower_qpath(
2383+
expr.id,
2384+
&se.qself,
2385+
&se.path,
2386+
ParamMode::Explicit,
2387+
AllowReturnTypeNotation::No,
2388+
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2389+
None,
2390+
);
2391+
2392+
let fields = self.arena.alloc_from_iter(se.fields.iter().map(|f| {
2393+
let hir_id = self.lower_node_id(f.id);
2394+
self.lower_attrs(hir_id, &f.attrs, f.span, Target::ExprField);
2395+
2396+
let expr = if let ExprKind::ConstBlock(anon_const) = &f.expr.kind {
2397+
self.lower_anon_const_to_const_arg_direct(anon_const)
2398+
} else {
2399+
self.lower_expr_to_const_arg_direct(&f.expr)
2400+
};
2401+
2402+
&*self.arena.alloc(hir::ConstArgExprField {
2403+
hir_id,
2404+
field: self.lower_ident(f.ident),
2405+
expr: self.arena.alloc(expr),
2406+
span: self.lower_span(f.span),
2407+
})
2408+
}));
2409+
2410+
ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Struct(path, fields) }
2411+
}
23812412
ExprKind::Underscore => ConstArg {
23822413
hir_id: self.lower_node_id(expr.id),
23832414
kind: hir::ConstArgKind::Infer(expr.span, ()),

compiler/rustc_hir/src/hir.rs

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

495495
pub fn span(&self) -> Span {
496496
match self.kind {
497+
ConstArgKind::Struct(path, _) => path.span(),
497498
ConstArgKind::Path(path) => path.span(),
498499
ConstArgKind::Anon(anon) => anon.span,
499500
ConstArgKind::Error(span, _) => span,
@@ -513,13 +514,23 @@ pub enum ConstArgKind<'hir, Unambig = ()> {
513514
/// However, in the future, we'll be using it for all of those.
514515
Path(QPath<'hir>),
515516
Anon(&'hir AnonConst),
517+
/// Represents construction of struct/struct variants
518+
Struct(QPath<'hir>, &'hir [&'hir ConstArgExprField<'hir>]),
516519
/// Error const
517520
Error(Span, ErrorGuaranteed),
518521
/// This variant is not always used to represent inference consts, sometimes
519522
/// [`GenericArg::Infer`] is used instead.
520523
Infer(Span, Unambig),
521524
}
522525

526+
#[derive(Clone, Copy, Debug, HashStable_Generic)]
527+
pub struct ConstArgExprField<'hir> {
528+
pub hir_id: HirId,
529+
pub span: Span,
530+
pub field: Ident,
531+
pub expr: &'hir ConstArg<'hir>,
532+
}
533+
523534
#[derive(Clone, Copy, Debug, HashStable_Generic)]
524535
pub struct InferArg {
525536
#[stable_hasher(ignore)]
@@ -4644,6 +4655,7 @@ pub enum Node<'hir> {
46444655
ConstArg(&'hir ConstArg<'hir>),
46454656
Expr(&'hir Expr<'hir>),
46464657
ExprField(&'hir ExprField<'hir>),
4658+
ConstArgExprField(&'hir ConstArgExprField<'hir>),
46474659
Stmt(&'hir Stmt<'hir>),
46484660
PathSegment(&'hir PathSegment<'hir>),
46494661
Ty(&'hir Ty<'hir>),
@@ -4703,6 +4715,7 @@ impl<'hir> Node<'hir> {
47034715
Node::AssocItemConstraint(c) => Some(c.ident),
47044716
Node::PatField(f) => Some(f.ident),
47054717
Node::ExprField(f) => Some(f.ident),
4718+
Node::ConstArgExprField(f) => Some(f.field),
47064719
Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident),
47074720
Node::Param(..)
47084721
| Node::AnonConst(..)

compiler/rustc_hir/src/intravisit.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,9 @@ pub trait Visitor<'v>: Sized {
396396
fn visit_expr_field(&mut self, field: &'v ExprField<'v>) -> Self::Result {
397397
walk_expr_field(self, field)
398398
}
399+
fn visit_const_arg_expr_field(&mut self, field: &'v ConstArgExprField<'v>) -> Self::Result {
400+
walk_const_arg_expr_field(self, field)
401+
}
399402
fn visit_pattern_type_pattern(&mut self, p: &'v TyPat<'v>) -> Self::Result {
400403
walk_ty_pat(self, p)
401404
}
@@ -955,6 +958,17 @@ pub fn walk_expr_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v ExprField
955958
try_visit!(visitor.visit_ident(*ident));
956959
visitor.visit_expr(*expr)
957960
}
961+
962+
pub fn walk_const_arg_expr_field<'v, V: Visitor<'v>>(
963+
visitor: &mut V,
964+
field: &'v ConstArgExprField<'v>,
965+
) -> V::Result {
966+
let ConstArgExprField { hir_id, field, expr, span: _ } = field;
967+
try_visit!(visitor.visit_id(*hir_id));
968+
try_visit!(visitor.visit_ident(*field));
969+
visitor.visit_const_arg_unambig(*expr)
970+
}
971+
958972
/// We track whether an infer var is from a [`Ty`], [`ConstArg`], or [`GenericArg`] so that
959973
/// HIR visitors overriding [`Visitor::visit_infer`] can determine what kind of infer is being visited
960974
pub enum InferKind<'hir> {
@@ -1069,7 +1083,17 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>(
10691083
) -> V::Result {
10701084
let ConstArg { hir_id, kind } = const_arg;
10711085
try_visit!(visitor.visit_id(*hir_id));
1086+
10721087
match kind {
1088+
ConstArgKind::Struct(qpath, field_exprs) => {
1089+
try_visit!(visitor.visit_qpath(qpath, *hir_id, qpath.span()));
1090+
1091+
for field_expr in *field_exprs {
1092+
try_visit!(visitor.visit_const_arg_expr_field(field_expr));
1093+
}
1094+
1095+
V::Result::output()
1096+
}
10731097
ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, *hir_id, qpath.span()),
10741098
ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon),
10751099
ConstArgKind::Error(_, _) => V::Result::output(), // errors and spans are not important

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2263,6 +2263,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
22632263
)
22642264
.unwrap_or_else(|guar| Const::new_error(tcx, guar))
22652265
}
2266+
hir::ConstArgKind::Struct(..) => {
2267+
span_bug!(const_arg.span(), "lowering `{:?}` is not yet implemented", const_arg)
2268+
}
22662269
hir::ConstArgKind::Anon(anon) => self.lower_anon_const(anon),
22672270
hir::ConstArgKind::Infer(span, ()) => self.ct_infer(None, span),
22682271
hir::ConstArgKind::Error(_, e) => ty::Const::new_error(tcx, e),

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ impl<'a> State<'a> {
180180
Node::ConstArg(a) => self.print_const_arg(a),
181181
Node::Expr(a) => self.print_expr(a),
182182
Node::ExprField(a) => self.print_expr_field(a),
183+
// FIXME(mgca): proper printing for struct exprs
184+
Node::ConstArgExprField(_) => self.word("/* STRUCT EXPR */"),
183185
Node::Stmt(a) => self.print_stmt(a),
184186
Node::PathSegment(a) => self.print_path_segment(a),
185187
Node::Ty(a) => self.print_type(a),
@@ -1136,6 +1138,8 @@ impl<'a> State<'a> {
11361138

11371139
fn print_const_arg(&mut self, const_arg: &hir::ConstArg<'_>) {
11381140
match &const_arg.kind {
1141+
// FIXME(mgca): proper printing for struct exprs
1142+
ConstArgKind::Struct(..) => self.word("/* STRUCT EXPR */"),
11391143
ConstArgKind::Path(qpath) => self.print_qpath(qpath, true),
11401144
ConstArgKind::Anon(anon) => self.print_anon_const(anon),
11411145
ConstArgKind::Error(_, _) => self.word("/*ERROR*/"),

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
439439
hir::Node::Block(_)
440440
| hir::Node::Arm(_)
441441
| hir::Node::ExprField(_)
442+
| hir::Node::ConstArgExprField(_)
442443
| hir::Node::AnonConst(_)
443444
| hir::Node::ConstBlock(_)
444445
| hir::Node::ConstArg(_)

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,6 +1445,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14451445
hir::Node::ConstArg(hir::ConstArg { kind, .. }) => match kind {
14461446
// Skip encoding defs for these as they should not have had a `DefId` created
14471447
hir::ConstArgKind::Error(..)
1448+
| hir::ConstArgKind::Struct(..)
14481449
| hir::ConstArgKind::Path(..)
14491450
| hir::ConstArgKind::Infer(..) => true,
14501451
hir::ConstArgKind::Anon(..) => false,

compiler/rustc_middle/src/arena.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ macro_rules! arena_types {
9292
[] name_set: rustc_data_structures::unord::UnordSet<rustc_span::Symbol>,
9393
[] autodiff_item: rustc_ast::expand::autodiff_attrs::AutoDiffItem,
9494
[] ordered_name_set: rustc_data_structures::fx::FxIndexSet<rustc_span::Symbol>,
95-
[] valtree: rustc_middle::ty::ValTreeKind<'tcx>,
95+
[] valtree: rustc_middle::ty::ValTreeKind<rustc_middle::ty::TyCtxt<'tcx>>,
9696
[] stable_order_of_exportable_impls:
9797
rustc_data_structures::fx::FxIndexMap<rustc_hir::def_id::DefId, usize>,
9898

compiler/rustc_middle/src/hir/map.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,7 @@ impl<'tcx> TyCtxt<'tcx> {
740740
Node::ConstArg(_) => node_str("const"),
741741
Node::Expr(_) => node_str("expr"),
742742
Node::ExprField(_) => node_str("expr field"),
743+
Node::ConstArgExprField(_) => node_str("const arg expr field"),
743744
Node::Stmt(_) => node_str("stmt"),
744745
Node::PathSegment(_) => node_str("path segment"),
745746
Node::Ty(_) => node_str("type"),
@@ -1008,6 +1009,7 @@ impl<'tcx> TyCtxt<'tcx> {
10081009
Node::ConstArg(const_arg) => const_arg.span(),
10091010
Node::Expr(expr) => expr.span,
10101011
Node::ExprField(field) => field.span,
1012+
Node::ConstArgExprField(field) => field.span,
10111013
Node::Stmt(stmt) => stmt.span,
10121014
Node::PathSegment(seg) => {
10131015
let ident_span = seg.ident.span;

0 commit comments

Comments
 (0)