From df4fee9841e21ac84335d214af163a1b652ec9a2 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 11 Jul 2022 23:39:53 +0400 Subject: [PATCH] Add an indirection for closures in `hir::ExprKind` This helps bring `hir::Expr` size down, `Closure` was the biggest variant, especially after `for<>` additions. --- compiler/rustc_ast_lowering/src/expr.rs | 35 +++++++++++-------- .../rustc_borrowck/src/diagnostics/mod.rs | 6 ++-- .../src/diagnostics/region_name.rs | 12 +++---- compiler/rustc_hir/src/arena.rs | 1 + compiler/rustc_hir/src/hir.rs | 21 ++++++----- compiler/rustc_hir/src/intravisit.rs | 14 +++----- compiler/rustc_hir_pretty/src/lib.rs | 6 ++-- .../infer/error_reporting/need_type_info.rs | 4 +-- compiler/rustc_middle/src/hir/map/mod.rs | 12 ++++--- compiler/rustc_mir_build/src/build/mod.rs | 7 ++-- compiler/rustc_passes/src/loops.rs | 8 ++++- compiler/rustc_passes/src/reachable.rs | 5 ++- compiler/rustc_resolve/src/late/lifetimes.rs | 5 ++- .../rustc_save_analysis/src/dump_visitor.rs | 2 +- .../src/traits/error_reporting/mod.rs | 2 +- .../error_reporting/on_unimplemented.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 2 +- compiler/rustc_typeck/src/check/callee.rs | 10 +++--- compiler/rustc_typeck/src/check/coercion.rs | 4 +-- compiler/rustc_typeck/src/check/demand.rs | 2 +- compiler/rustc_typeck/src/check/expr.rs | 4 +-- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 2 +- compiler/rustc_typeck/src/check/region.rs | 2 +- compiler/rustc_typeck/src/check/upvar.rs | 2 +- compiler/rustc_typeck/src/check/writeback.rs | 2 +- compiler/rustc_typeck/src/collect.rs | 8 +++-- 26 files changed, 101 insertions(+), 79 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 995dc6aab55..983efa48a45 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -608,14 +608,18 @@ pub(super) fn make_async_expr( }); // `static |_task_context| -> { body }`: - let generator_kind = hir::ExprKind::Closure { - binder: &hir::ClosureBinder::Default, - capture_clause, - bound_generic_params: &[], - fn_decl, - body, - fn_decl_span: self.lower_span(span), - movability: Some(hir::Movability::Static), + let generator_kind = { + let c = self.arena.alloc(hir::Closure { + binder: hir::ClosureBinder::Default, + capture_clause, + bound_generic_params: &[], + fn_decl, + body, + fn_decl_span: self.lower_span(span), + movability: Some(hir::Movability::Static), + }); + + hir::ExprKind::Closure(c) }; let generator = hir::Expr { hir_id: self.lower_node_id(closure_node_id), @@ -864,7 +868,7 @@ fn lower_expr_closure( // Lower outside new scope to preserve `is_in_loop_condition`. let fn_decl = this.lower_fn_decl(decl, None, FnDeclKind::Closure, None); - hir::ExprKind::Closure { + let c = self.arena.alloc(hir::Closure { binder: binder_clause, capture_clause, bound_generic_params, @@ -872,7 +876,9 @@ fn lower_expr_closure( body: body_id, fn_decl_span: this.lower_span(fn_decl_span), movability: generator_option, - } + }); + + hir::ExprKind::Closure(c) }) } @@ -917,7 +923,7 @@ fn generator_movability_for_fn( fn lower_closure_binder<'c>( &mut self, binder: &'c ClosureBinder, - ) -> (&'hir hir::ClosureBinder, &'c [GenericParam]) { + ) -> (hir::ClosureBinder, &'c [GenericParam]) { let (binder, params) = match binder { ClosureBinder::NotPresent => (hir::ClosureBinder::Default, &[][..]), &ClosureBinder::For { span, ref generic_params } => { @@ -926,7 +932,7 @@ fn lower_closure_binder<'c>( } }; - (self.arena.alloc(binder), params) + (binder, params) } fn lower_expr_async_closure( @@ -991,7 +997,7 @@ fn lower_expr_async_closure( // closure argument types. let fn_decl = this.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None); - hir::ExprKind::Closure { + let c = self.arena.alloc(hir::Closure { binder: binder_clause, capture_clause, bound_generic_params, @@ -999,7 +1005,8 @@ fn lower_expr_async_closure( body, fn_decl_span: this.lower_span(fn_decl_span), movability: None, - } + }); + hir::ExprKind::Closure(c) }) } diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 6fea6941085..daf4040cc4b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -891,7 +891,7 @@ fn closure_span( let hir_id = self.infcx.tcx.hir().local_def_id_to_hir_id(local_did); let expr = &self.infcx.tcx.hir().expect_expr(hir_id).kind; debug!("closure_span: hir_id={:?} expr={:?}", hir_id, expr); - if let hir::ExprKind::Closure { body, fn_decl_span, .. } = expr { + if let hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }) = expr { for (captured_place, place) in self .infcx .tcx @@ -904,11 +904,11 @@ fn closure_span( if target_place == place.as_ref() => { debug!("closure_span: found captured local {:?}", place); - let body = self.infcx.tcx.hir().body(*body); + let body = self.infcx.tcx.hir().body(body); let generator_kind = body.generator_kind(); return Some(( - *fn_decl_span, + fn_decl_span, generator_kind, captured_place.get_capture_kind_span(self.infcx.tcx), captured_place.get_path_span(self.infcx.tcx), diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index e60e11f11df..e41af17fbf9 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -325,7 +325,7 @@ fn give_name_from_error_region(&self, fr: RegionVid) -> Option { // Can't have BrEnv in functions, constants or generators. bug!("BrEnv outside of closure."); }; - let hir::ExprKind::Closure { fn_decl_span, .. } + let hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }) = tcx.hir().expect_expr(self.mir_hir_id()).kind else { bug!("Closure is not defined by a closure expr"); @@ -701,16 +701,16 @@ fn give_name_if_anonymous_region_appears_in_output(&self, fr: RegionVid) -> Opti let (return_span, mir_description, hir_ty) = match hir.get(mir_hir_id) { hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Closure { fn_decl, body, fn_decl_span, .. }, + kind: hir::ExprKind::Closure(&hir::Closure { fn_decl, body, fn_decl_span, .. }), .. }) => { let (mut span, mut hir_ty) = match fn_decl.output { hir::FnRetTy::DefaultReturn(_) => { - (tcx.sess.source_map().end_point(*fn_decl_span), None) + (tcx.sess.source_map().end_point(fn_decl_span), None) } hir::FnRetTy::Return(hir_ty) => (fn_decl.output.span(), Some(hir_ty)), }; - let mir_description = match hir.body(*body).generator_kind { + let mir_description = match hir.body(body).generator_kind { Some(hir::GeneratorKind::Async(gen)) => match gen { hir::AsyncGeneratorKind::Block => " of async block", hir::AsyncGeneratorKind::Closure => " of async closure", @@ -841,9 +841,9 @@ fn give_name_if_anonymous_region_appears_in_yield_ty( let yield_span = match tcx.hir().get(self.mir_hir_id()) { hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Closure { fn_decl_span, .. }, + kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }), .. - }) => (tcx.sess.source_map().end_point(*fn_decl_span)), + }) => (tcx.sess.source_map().end_point(fn_decl_span)), _ => self.body.span, }; diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index a6d10f3adae..44335b7f42e 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -12,6 +12,7 @@ macro_rules! arena_types { [] asm_operand: (rustc_hir::InlineAsmOperand<'tcx>, rustc_span::Span), [] asm_template: rustc_ast::InlineAsmTemplatePiece, [] attribute: rustc_ast::Attribute, + [] closure: rustc_hir::Closure<'tcx>, [] block: rustc_hir::Block<'tcx>, [] bare_fn_ty: rustc_hir::BareFnTy<'tcx>, [] body: rustc_hir::Body<'tcx>, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 2252dfd683a..9d198fbdf74 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -922,6 +922,17 @@ pub struct Crate<'hir> { pub hir_hash: Fingerprint, } +#[derive(Debug, HashStable_Generic)] +pub struct Closure<'hir> { + pub binder: ClosureBinder, + pub capture_clause: CaptureBy, + pub bound_generic_params: &'hir [GenericParam<'hir>], + pub fn_decl: &'hir FnDecl<'hir>, + pub body: BodyId, + pub fn_decl_span: Span, + pub movability: Option, +} + /// A block of statements `{ .. }`, which may have a label (in this case the /// `targeted_by_break` field will be `true`) and may be `unsafe` by means of /// the `rules` being anything but `DefaultBlock`. @@ -1930,15 +1941,7 @@ pub enum ExprKind<'hir> { /// /// This may also be a generator literal or an `async block` as indicated by the /// `Option`. - Closure { - binder: &'hir ClosureBinder, - capture_clause: CaptureBy, - bound_generic_params: &'hir [GenericParam<'hir>], - fn_decl: &'hir FnDecl<'hir>, - body: BodyId, - fn_decl_span: Span, - movability: Option, - }, + Closure(&'hir Closure<'hir>), /// A block (e.g., `'label: { ... }`). Block(&'hir Block<'hir>, Option