Skip to content

Commit df4fee9

Browse files
committed
Add an indirection for closures in hir::ExprKind
This helps bring `hir::Expr` size down, `Closure` was the biggest variant, especially after `for<>` additions.
1 parent 3ebb852 commit df4fee9

File tree

26 files changed

+101
-79
lines changed

26 files changed

+101
-79
lines changed

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -608,14 +608,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
608608
});
609609

610610
// `static |_task_context| -> <ret_ty> { body }`:
611-
let generator_kind = hir::ExprKind::Closure {
612-
binder: &hir::ClosureBinder::Default,
613-
capture_clause,
614-
bound_generic_params: &[],
615-
fn_decl,
616-
body,
617-
fn_decl_span: self.lower_span(span),
618-
movability: Some(hir::Movability::Static),
611+
let generator_kind = {
612+
let c = self.arena.alloc(hir::Closure {
613+
binder: hir::ClosureBinder::Default,
614+
capture_clause,
615+
bound_generic_params: &[],
616+
fn_decl,
617+
body,
618+
fn_decl_span: self.lower_span(span),
619+
movability: Some(hir::Movability::Static),
620+
});
621+
622+
hir::ExprKind::Closure(c)
619623
};
620624
let generator = hir::Expr {
621625
hir_id: self.lower_node_id(closure_node_id),
@@ -864,15 +868,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
864868
// Lower outside new scope to preserve `is_in_loop_condition`.
865869
let fn_decl = this.lower_fn_decl(decl, None, FnDeclKind::Closure, None);
866870

867-
hir::ExprKind::Closure {
871+
let c = self.arena.alloc(hir::Closure {
868872
binder: binder_clause,
869873
capture_clause,
870874
bound_generic_params,
871875
fn_decl,
872876
body: body_id,
873877
fn_decl_span: this.lower_span(fn_decl_span),
874878
movability: generator_option,
875-
}
879+
});
880+
881+
hir::ExprKind::Closure(c)
876882
})
877883
}
878884

@@ -917,7 +923,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
917923
fn lower_closure_binder<'c>(
918924
&mut self,
919925
binder: &'c ClosureBinder,
920-
) -> (&'hir hir::ClosureBinder, &'c [GenericParam]) {
926+
) -> (hir::ClosureBinder, &'c [GenericParam]) {
921927
let (binder, params) = match binder {
922928
ClosureBinder::NotPresent => (hir::ClosureBinder::Default, &[][..]),
923929
&ClosureBinder::For { span, ref generic_params } => {
@@ -926,7 +932,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
926932
}
927933
};
928934

929-
(self.arena.alloc(binder), params)
935+
(binder, params)
930936
}
931937

932938
fn lower_expr_async_closure(
@@ -991,15 +997,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
991997
// closure argument types.
992998
let fn_decl = this.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None);
993999

994-
hir::ExprKind::Closure {
1000+
let c = self.arena.alloc(hir::Closure {
9951001
binder: binder_clause,
9961002
capture_clause,
9971003
bound_generic_params,
9981004
fn_decl,
9991005
body,
10001006
fn_decl_span: this.lower_span(fn_decl_span),
10011007
movability: None,
1002-
}
1008+
});
1009+
hir::ExprKind::Closure(c)
10031010
})
10041011
}
10051012

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -891,7 +891,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
891891
let hir_id = self.infcx.tcx.hir().local_def_id_to_hir_id(local_did);
892892
let expr = &self.infcx.tcx.hir().expect_expr(hir_id).kind;
893893
debug!("closure_span: hir_id={:?} expr={:?}", hir_id, expr);
894-
if let hir::ExprKind::Closure { body, fn_decl_span, .. } = expr {
894+
if let hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }) = expr {
895895
for (captured_place, place) in self
896896
.infcx
897897
.tcx
@@ -904,11 +904,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
904904
if target_place == place.as_ref() =>
905905
{
906906
debug!("closure_span: found captured local {:?}", place);
907-
let body = self.infcx.tcx.hir().body(*body);
907+
let body = self.infcx.tcx.hir().body(body);
908908
let generator_kind = body.generator_kind();
909909

910910
return Some((
911-
*fn_decl_span,
911+
fn_decl_span,
912912
generator_kind,
913913
captured_place.get_capture_kind_span(self.infcx.tcx),
914914
captured_place.get_path_span(self.infcx.tcx),

compiler/rustc_borrowck/src/diagnostics/region_name.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
325325
// Can't have BrEnv in functions, constants or generators.
326326
bug!("BrEnv outside of closure.");
327327
};
328-
let hir::ExprKind::Closure { fn_decl_span, .. }
328+
let hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. })
329329
= tcx.hir().expect_expr(self.mir_hir_id()).kind
330330
else {
331331
bug!("Closure is not defined by a closure expr");
@@ -701,16 +701,16 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
701701

702702
let (return_span, mir_description, hir_ty) = match hir.get(mir_hir_id) {
703703
hir::Node::Expr(hir::Expr {
704-
kind: hir::ExprKind::Closure { fn_decl, body, fn_decl_span, .. },
704+
kind: hir::ExprKind::Closure(&hir::Closure { fn_decl, body, fn_decl_span, .. }),
705705
..
706706
}) => {
707707
let (mut span, mut hir_ty) = match fn_decl.output {
708708
hir::FnRetTy::DefaultReturn(_) => {
709-
(tcx.sess.source_map().end_point(*fn_decl_span), None)
709+
(tcx.sess.source_map().end_point(fn_decl_span), None)
710710
}
711711
hir::FnRetTy::Return(hir_ty) => (fn_decl.output.span(), Some(hir_ty)),
712712
};
713-
let mir_description = match hir.body(*body).generator_kind {
713+
let mir_description = match hir.body(body).generator_kind {
714714
Some(hir::GeneratorKind::Async(gen)) => match gen {
715715
hir::AsyncGeneratorKind::Block => " of async block",
716716
hir::AsyncGeneratorKind::Closure => " of async closure",
@@ -841,9 +841,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
841841

842842
let yield_span = match tcx.hir().get(self.mir_hir_id()) {
843843
hir::Node::Expr(hir::Expr {
844-
kind: hir::ExprKind::Closure { fn_decl_span, .. },
844+
kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }),
845845
..
846-
}) => (tcx.sess.source_map().end_point(*fn_decl_span)),
846+
}) => (tcx.sess.source_map().end_point(fn_decl_span)),
847847
_ => self.body.span,
848848
};
849849

compiler/rustc_hir/src/arena.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ macro_rules! arena_types {
1212
[] asm_operand: (rustc_hir::InlineAsmOperand<'tcx>, rustc_span::Span),
1313
[] asm_template: rustc_ast::InlineAsmTemplatePiece,
1414
[] attribute: rustc_ast::Attribute,
15+
[] closure: rustc_hir::Closure<'tcx>,
1516
[] block: rustc_hir::Block<'tcx>,
1617
[] bare_fn_ty: rustc_hir::BareFnTy<'tcx>,
1718
[] body: rustc_hir::Body<'tcx>,

compiler/rustc_hir/src/hir.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,17 @@ pub struct Crate<'hir> {
922922
pub hir_hash: Fingerprint,
923923
}
924924

925+
#[derive(Debug, HashStable_Generic)]
926+
pub struct Closure<'hir> {
927+
pub binder: ClosureBinder,
928+
pub capture_clause: CaptureBy,
929+
pub bound_generic_params: &'hir [GenericParam<'hir>],
930+
pub fn_decl: &'hir FnDecl<'hir>,
931+
pub body: BodyId,
932+
pub fn_decl_span: Span,
933+
pub movability: Option<Movability>,
934+
}
935+
925936
/// A block of statements `{ .. }`, which may have a label (in this case the
926937
/// `targeted_by_break` field will be `true`) and may be `unsafe` by means of
927938
/// the `rules` being anything but `DefaultBlock`.
@@ -1930,15 +1941,7 @@ pub enum ExprKind<'hir> {
19301941
///
19311942
/// This may also be a generator literal or an `async block` as indicated by the
19321943
/// `Option<Movability>`.
1933-
Closure {
1934-
binder: &'hir ClosureBinder,
1935-
capture_clause: CaptureBy,
1936-
bound_generic_params: &'hir [GenericParam<'hir>],
1937-
fn_decl: &'hir FnDecl<'hir>,
1938-
body: BodyId,
1939-
fn_decl_span: Span,
1940-
movability: Option<Movability>,
1941-
},
1944+
Closure(&'hir Closure<'hir>),
19421945
/// A block (e.g., `'label: { ... }`).
19431946
Block(&'hir Block<'hir>, Option<Label>),
19441947

compiler/rustc_hir/src/intravisit.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,23 +1144,17 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
11441144
visitor.visit_expr(subexpression);
11451145
walk_list!(visitor, visit_arm, arms);
11461146
}
1147-
ExprKind::Closure {
1147+
ExprKind::Closure(&Closure {
11481148
binder: _,
11491149
bound_generic_params,
1150-
ref fn_decl,
1150+
fn_decl,
11511151
body,
11521152
capture_clause: _,
11531153
fn_decl_span: _,
11541154
movability: _,
1155-
} => {
1155+
}) => {
11561156
walk_list!(visitor, visit_generic_param, bound_generic_params);
1157-
visitor.visit_fn(
1158-
FnKind::Closure,
1159-
fn_decl,
1160-
body,
1161-
expression.span,
1162-
expression.hir_id,
1163-
)
1157+
visitor.visit_fn(FnKind::Closure, fn_decl, body, expression.span, expression.hir_id)
11641158
}
11651159
ExprKind::Block(ref block, ref opt_label) => {
11661160
walk_list!(visitor, visit_label, opt_label);

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,15 +1441,15 @@ impl<'a> State<'a> {
14411441
}
14421442
self.bclose(expr.span);
14431443
}
1444-
hir::ExprKind::Closure {
1444+
hir::ExprKind::Closure(&hir::Closure {
14451445
binder,
14461446
capture_clause,
14471447
bound_generic_params,
14481448
fn_decl,
14491449
body,
14501450
fn_decl_span: _,
14511451
movability: _,
1452-
} => {
1452+
}) => {
14531453
self.print_closure_binder(binder, bound_generic_params);
14541454
self.print_capture_clause(capture_clause);
14551455

@@ -2037,7 +2037,7 @@ impl<'a> State<'a> {
20372037

20382038
pub fn print_closure_binder(
20392039
&mut self,
2040-
binder: &hir::ClosureBinder,
2040+
binder: hir::ClosureBinder,
20412041
generic_params: &[GenericParam<'_>],
20422042
) {
20432043
let generic_params = generic_params

compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_hir::def::Res;
66
use rustc_hir::def::{CtorOf, DefKind, Namespace};
77
use rustc_hir::def_id::DefId;
88
use rustc_hir::intravisit::{self, Visitor};
9-
use rustc_hir::{Body, Expr, ExprKind, FnRetTy, HirId, Local, LocalSource};
9+
use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, Local, LocalSource};
1010
use rustc_middle::hir::nested_filter;
1111
use rustc_middle::infer::unify_key::ConstVariableOriginKind;
1212
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
@@ -1051,7 +1051,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
10511051

10521052
if let Some(node_ty) = self.opt_node_type(expr.hir_id) {
10531053
if let (
1054-
&ExprKind::Closure { fn_decl, body, fn_decl_span, .. },
1054+
&ExprKind::Closure(&Closure { fn_decl, body, fn_decl_span, .. }),
10551055
ty::Closure(_, substs),
10561056
) = (&expr.kind, node_ty.kind())
10571057
{

compiler/rustc_middle/src/hir/map/mod.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ fn fn_decl<'hir>(node: Node<'hir>) -> Option<&'hir FnDecl<'hir>> {
2222
Node::Item(Item { kind: ItemKind::Fn(sig, _, _), .. })
2323
| Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(sig, _), .. })
2424
| Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(sig, _), .. }) => Some(&sig.decl),
25-
Node::Expr(Expr { kind: ExprKind::Closure { fn_decl, .. }, .. })
25+
Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl, .. }), .. })
2626
| Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, ..), .. }) => {
2727
Some(fn_decl)
2828
}
@@ -54,7 +54,7 @@ pub fn associated_body<'hir>(node: Node<'hir>) -> Option<BodyId> {
5454
kind: ImplItemKind::Const(_, body) | ImplItemKind::Fn(_, body),
5555
..
5656
})
57-
| Node::Expr(Expr { kind: ExprKind::Closure { body, .. }, .. }) => Some(*body),
57+
| Node::Expr(Expr { kind: ExprKind::Closure(Closure { body, .. }), .. }) => Some(*body),
5858

5959
Node::AnonConst(constant) => Some(constant.body),
6060

@@ -279,8 +279,8 @@ impl<'hir> Map<'hir> {
279279
}
280280
Node::Field(_) => DefKind::Field,
281281
Node::Expr(expr) => match expr.kind {
282-
ExprKind::Closure { movability: None, .. } => DefKind::Closure,
283-
ExprKind::Closure { movability: Some(_), .. } => DefKind::Generator,
282+
ExprKind::Closure(Closure { movability: None, .. }) => DefKind::Closure,
283+
ExprKind::Closure(Closure { movability: Some(_), .. }) => DefKind::Generator,
284284
_ => bug!("def_kind: unsupported node: {}", self.node_to_string(hir_id)),
285285
},
286286
Node::GenericParam(param) => match param.kind {
@@ -1021,7 +1021,9 @@ impl<'hir> Map<'hir> {
10211021
_ => named_span(item.span, item.ident, None),
10221022
},
10231023
Node::Ctor(_) => return self.opt_span(self.get_parent_node(hir_id)),
1024-
Node::Expr(Expr { kind: ExprKind::Closure { fn_decl_span, .. }, .. }) => *fn_decl_span,
1024+
Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl_span, .. }), .. }) => {
1025+
*fn_decl_span
1026+
}
10251027
_ => self.span_with_body(hir_id),
10261028
};
10271029
Some(span)

compiler/rustc_mir_build/src/build/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,10 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
6868

6969
// Figure out what primary body this item has.
7070
let (body_id, return_ty_span, span_with_body) = match tcx.hir().get(id) {
71-
Node::Expr(hir::Expr { kind: hir::ExprKind::Closure { fn_decl, body, .. }, .. }) => {
72-
(*body, fn_decl.output.span(), None)
73-
}
71+
Node::Expr(hir::Expr {
72+
kind: hir::ExprKind::Closure(hir::Closure { fn_decl, body, .. }),
73+
..
74+
}) => (*body, fn_decl.output.span(), None),
7475
Node::Item(hir::Item {
7576
kind: hir::ItemKind::Fn(hir::FnSig { decl, .. }, _, body_id),
7677
span,

compiler/rustc_passes/src/loops.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,13 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
5757
hir::ExprKind::Loop(ref b, _, source, _) => {
5858
self.with_context(Loop(source), |v| v.visit_block(&b));
5959
}
60-
hir::ExprKind::Closure { ref fn_decl, body, fn_decl_span, movability, .. } => {
60+
hir::ExprKind::Closure(&hir::Closure {
61+
ref fn_decl,
62+
body,
63+
fn_decl_span,
64+
movability,
65+
..
66+
}) => {
6167
let cx = if let Some(Movability::Static) = movability {
6268
AsyncClosure(fn_decl_span)
6369
} else {

compiler/rustc_passes/src/reachable.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,10 @@ impl<'tcx> ReachableContext<'tcx> {
273273
}
274274
hir::ImplItemKind::TyAlias(_) => {}
275275
},
276-
Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { body, .. }, .. }) => {
276+
Node::Expr(&hir::Expr {
277+
kind: hir::ExprKind::Closure(&hir::Closure { body, .. }),
278+
..
279+
}) => {
277280
self.visit_nested_body(body);
278281
}
279282
// Nothing to recurse on for these

compiler/rustc_resolve/src/late/lifetimes.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
571571
}
572572

573573
fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
574-
if let hir::ExprKind::Closure { binder, bound_generic_params, fn_decl, .. } = e.kind {
574+
if let hir::ExprKind::Closure(hir::Closure {
575+
binder, bound_generic_params, fn_decl, ..
576+
}) = e.kind
577+
{
575578
if let &hir::ClosureBinder::For { span: for_sp, .. } = binder {
576579
fn span_of_infer(ty: &hir::Ty<'_>) -> Option<Span> {
577580
struct V(Option<Span>);

compiler/rustc_save_analysis/src/dump_visitor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1360,7 +1360,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
13601360
}
13611361
}
13621362
}
1363-
hir::ExprKind::Closure { ref fn_decl, body, .. } => {
1363+
hir::ExprKind::Closure(&hir::Closure { ref fn_decl, body, .. }) => {
13641364
let id = format!("${}", ex.hir_id);
13651365

13661366
// walk arg and return types

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1084,7 +1084,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
10841084
let hir = self.tcx.hir();
10851085
Some(match node {
10861086
Node::Expr(&hir::Expr {
1087-
kind: hir::ExprKind::Closure { body, fn_decl_span, .. },
1087+
kind: hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }),
10881088
..
10891089
}) => (
10901090
sm.guess_head_span(fn_decl_span),

compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
103103
})
104104
}),
105105
hir::Node::Expr(hir::Expr {
106-
kind: hir::ExprKind::Closure { body, movability, .. },
106+
kind: hir::ExprKind::Closure(hir::Closure { body, movability, .. }),
107107
..
108108
}) => self.describe_generator(*body).or_else(|| {
109109
Some(if movability.is_some() { "an async closure" } else { "a closure" })

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
785785
// Get the name of the callable and the arguments to be used in the suggestion.
786786
let (snippet, sugg) = match hir.get_if_local(def_id) {
787787
Some(hir::Node::Expr(hir::Expr {
788-
kind: hir::ExprKind::Closure { fn_decl, fn_decl_span, .. },
788+
kind: hir::ExprKind::Closure(hir::Closure { fn_decl, fn_decl_span, .. }),
789789
..
790790
})) => {
791791
err.span_label(*fn_decl_span, "consider calling this closure");

0 commit comments

Comments
 (0)