1
Fork 0

Add an indirection for closures in hir::ExprKind

This helps bring `hir::Expr` size down, `Closure` was the biggest
variant, especially after `for<>` additions.
This commit is contained in:
Maybe Waffle 2022-07-11 23:39:53 +04:00
parent 3ebb852956
commit df4fee9841
26 changed files with 101 additions and 79 deletions

View file

@ -608,14 +608,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
}); });
// `static |_task_context| -> <ret_ty> { body }`: // `static |_task_context| -> <ret_ty> { body }`:
let generator_kind = hir::ExprKind::Closure { let generator_kind = {
binder: &hir::ClosureBinder::Default, let c = self.arena.alloc(hir::Closure {
capture_clause, binder: hir::ClosureBinder::Default,
bound_generic_params: &[], capture_clause,
fn_decl, bound_generic_params: &[],
body, fn_decl,
fn_decl_span: self.lower_span(span), body,
movability: Some(hir::Movability::Static), fn_decl_span: self.lower_span(span),
movability: Some(hir::Movability::Static),
});
hir::ExprKind::Closure(c)
}; };
let generator = hir::Expr { let generator = hir::Expr {
hir_id: self.lower_node_id(closure_node_id), hir_id: self.lower_node_id(closure_node_id),
@ -864,7 +868,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// Lower outside new scope to preserve `is_in_loop_condition`. // Lower outside new scope to preserve `is_in_loop_condition`.
let fn_decl = this.lower_fn_decl(decl, None, FnDeclKind::Closure, None); 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, binder: binder_clause,
capture_clause, capture_clause,
bound_generic_params, bound_generic_params,
@ -872,7 +876,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
body: body_id, body: body_id,
fn_decl_span: this.lower_span(fn_decl_span), fn_decl_span: this.lower_span(fn_decl_span),
movability: generator_option, movability: generator_option,
} });
hir::ExprKind::Closure(c)
}) })
} }
@ -917,7 +923,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_closure_binder<'c>( fn lower_closure_binder<'c>(
&mut self, &mut self,
binder: &'c ClosureBinder, binder: &'c ClosureBinder,
) -> (&'hir hir::ClosureBinder, &'c [GenericParam]) { ) -> (hir::ClosureBinder, &'c [GenericParam]) {
let (binder, params) = match binder { let (binder, params) = match binder {
ClosureBinder::NotPresent => (hir::ClosureBinder::Default, &[][..]), ClosureBinder::NotPresent => (hir::ClosureBinder::Default, &[][..]),
&ClosureBinder::For { span, ref generic_params } => { &ClosureBinder::For { span, ref generic_params } => {
@ -926,7 +932,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
}; };
(self.arena.alloc(binder), params) (binder, params)
} }
fn lower_expr_async_closure( fn lower_expr_async_closure(
@ -991,7 +997,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// closure argument types. // closure argument types.
let fn_decl = this.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None); 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, binder: binder_clause,
capture_clause, capture_clause,
bound_generic_params, bound_generic_params,
@ -999,7 +1005,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
body, body,
fn_decl_span: this.lower_span(fn_decl_span), fn_decl_span: this.lower_span(fn_decl_span),
movability: None, movability: None,
} });
hir::ExprKind::Closure(c)
}) })
} }

View file

@ -891,7 +891,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let hir_id = self.infcx.tcx.hir().local_def_id_to_hir_id(local_did); 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; let expr = &self.infcx.tcx.hir().expect_expr(hir_id).kind;
debug!("closure_span: hir_id={:?} expr={:?}", hir_id, expr); 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 for (captured_place, place) in self
.infcx .infcx
.tcx .tcx
@ -904,11 +904,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if target_place == place.as_ref() => if target_place == place.as_ref() =>
{ {
debug!("closure_span: found captured local {:?}", place); 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(); let generator_kind = body.generator_kind();
return Some(( return Some((
*fn_decl_span, fn_decl_span,
generator_kind, generator_kind,
captured_place.get_capture_kind_span(self.infcx.tcx), captured_place.get_capture_kind_span(self.infcx.tcx),
captured_place.get_path_span(self.infcx.tcx), captured_place.get_path_span(self.infcx.tcx),

View file

@ -325,7 +325,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
// Can't have BrEnv in functions, constants or generators. // Can't have BrEnv in functions, constants or generators.
bug!("BrEnv outside of closure."); 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 = tcx.hir().expect_expr(self.mir_hir_id()).kind
else { else {
bug!("Closure is not defined by a closure expr"); bug!("Closure is not defined by a closure expr");
@ -701,16 +701,16 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
let (return_span, mir_description, hir_ty) = match hir.get(mir_hir_id) { let (return_span, mir_description, hir_ty) = match hir.get(mir_hir_id) {
hir::Node::Expr(hir::Expr { 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 { let (mut span, mut hir_ty) = match fn_decl.output {
hir::FnRetTy::DefaultReturn(_) => { 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)), 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 { Some(hir::GeneratorKind::Async(gen)) => match gen {
hir::AsyncGeneratorKind::Block => " of async block", hir::AsyncGeneratorKind::Block => " of async block",
hir::AsyncGeneratorKind::Closure => " of async closure", hir::AsyncGeneratorKind::Closure => " of async closure",
@ -841,9 +841,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
let yield_span = match tcx.hir().get(self.mir_hir_id()) { let yield_span = match tcx.hir().get(self.mir_hir_id()) {
hir::Node::Expr(hir::Expr { 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, _ => self.body.span,
}; };

View file

@ -12,6 +12,7 @@ macro_rules! arena_types {
[] asm_operand: (rustc_hir::InlineAsmOperand<'tcx>, rustc_span::Span), [] asm_operand: (rustc_hir::InlineAsmOperand<'tcx>, rustc_span::Span),
[] asm_template: rustc_ast::InlineAsmTemplatePiece, [] asm_template: rustc_ast::InlineAsmTemplatePiece,
[] attribute: rustc_ast::Attribute, [] attribute: rustc_ast::Attribute,
[] closure: rustc_hir::Closure<'tcx>,
[] block: rustc_hir::Block<'tcx>, [] block: rustc_hir::Block<'tcx>,
[] bare_fn_ty: rustc_hir::BareFnTy<'tcx>, [] bare_fn_ty: rustc_hir::BareFnTy<'tcx>,
[] body: rustc_hir::Body<'tcx>, [] body: rustc_hir::Body<'tcx>,

View file

@ -922,6 +922,17 @@ pub struct Crate<'hir> {
pub hir_hash: Fingerprint, 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<Movability>,
}
/// A block of statements `{ .. }`, which may have a label (in this case the /// 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 /// `targeted_by_break` field will be `true`) and may be `unsafe` by means of
/// the `rules` being anything but `DefaultBlock`. /// 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 /// This may also be a generator literal or an `async block` as indicated by the
/// `Option<Movability>`. /// `Option<Movability>`.
Closure { Closure(&'hir Closure<'hir>),
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<Movability>,
},
/// A block (e.g., `'label: { ... }`). /// A block (e.g., `'label: { ... }`).
Block(&'hir Block<'hir>, Option<Label>), Block(&'hir Block<'hir>, Option<Label>),

View file

@ -1144,23 +1144,17 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
visitor.visit_expr(subexpression); visitor.visit_expr(subexpression);
walk_list!(visitor, visit_arm, arms); walk_list!(visitor, visit_arm, arms);
} }
ExprKind::Closure { ExprKind::Closure(&Closure {
binder: _, binder: _,
bound_generic_params, bound_generic_params,
ref fn_decl, fn_decl,
body, body,
capture_clause: _, capture_clause: _,
fn_decl_span: _, fn_decl_span: _,
movability: _, movability: _,
} => { }) => {
walk_list!(visitor, visit_generic_param, bound_generic_params); walk_list!(visitor, visit_generic_param, bound_generic_params);
visitor.visit_fn( visitor.visit_fn(FnKind::Closure, fn_decl, body, expression.span, expression.hir_id)
FnKind::Closure,
fn_decl,
body,
expression.span,
expression.hir_id,
)
} }
ExprKind::Block(ref block, ref opt_label) => { ExprKind::Block(ref block, ref opt_label) => {
walk_list!(visitor, visit_label, opt_label); walk_list!(visitor, visit_label, opt_label);

View file

@ -1441,7 +1441,7 @@ impl<'a> State<'a> {
} }
self.bclose(expr.span); self.bclose(expr.span);
} }
hir::ExprKind::Closure { hir::ExprKind::Closure(&hir::Closure {
binder, binder,
capture_clause, capture_clause,
bound_generic_params, bound_generic_params,
@ -1449,7 +1449,7 @@ impl<'a> State<'a> {
body, body,
fn_decl_span: _, fn_decl_span: _,
movability: _, movability: _,
} => { }) => {
self.print_closure_binder(binder, bound_generic_params); self.print_closure_binder(binder, bound_generic_params);
self.print_capture_clause(capture_clause); self.print_capture_clause(capture_clause);
@ -2037,7 +2037,7 @@ impl<'a> State<'a> {
pub fn print_closure_binder( pub fn print_closure_binder(
&mut self, &mut self,
binder: &hir::ClosureBinder, binder: hir::ClosureBinder,
generic_params: &[GenericParam<'_>], generic_params: &[GenericParam<'_>],
) { ) {
let generic_params = generic_params let generic_params = generic_params

View file

@ -6,7 +6,7 @@ use rustc_hir::def::Res;
use rustc_hir::def::{CtorOf, DefKind, Namespace}; use rustc_hir::def::{CtorOf, DefKind, Namespace};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{Body, Expr, ExprKind, FnRetTy, HirId, Local, LocalSource}; use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, Local, LocalSource};
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
use rustc_middle::infer::unify_key::ConstVariableOriginKind; use rustc_middle::infer::unify_key::ConstVariableOriginKind;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
@ -1051,7 +1051,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
if let Some(node_ty) = self.opt_node_type(expr.hir_id) { if let Some(node_ty) = self.opt_node_type(expr.hir_id) {
if let ( if let (
&ExprKind::Closure { fn_decl, body, fn_decl_span, .. }, &ExprKind::Closure(&Closure { fn_decl, body, fn_decl_span, .. }),
ty::Closure(_, substs), ty::Closure(_, substs),
) = (&expr.kind, node_ty.kind()) ) = (&expr.kind, node_ty.kind())
{ {

View file

@ -22,7 +22,7 @@ fn fn_decl<'hir>(node: Node<'hir>) -> Option<&'hir FnDecl<'hir>> {
Node::Item(Item { kind: ItemKind::Fn(sig, _, _), .. }) Node::Item(Item { kind: ItemKind::Fn(sig, _, _), .. })
| Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(sig, _), .. }) | Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(sig, _), .. })
| Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(sig, _), .. }) => Some(&sig.decl), | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(sig, _), .. }) => Some(&sig.decl),
Node::Expr(Expr { kind: ExprKind::Closure { fn_decl, .. }, .. }) Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl, .. }), .. })
| Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, ..), .. }) => { | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, ..), .. }) => {
Some(fn_decl) Some(fn_decl)
} }
@ -54,7 +54,7 @@ pub fn associated_body<'hir>(node: Node<'hir>) -> Option<BodyId> {
kind: ImplItemKind::Const(_, body) | ImplItemKind::Fn(_, body), kind: ImplItemKind::Const(_, body) | ImplItemKind::Fn(_, body),
.. ..
}) })
| Node::Expr(Expr { kind: ExprKind::Closure { body, .. }, .. }) => Some(*body), | Node::Expr(Expr { kind: ExprKind::Closure(Closure { body, .. }), .. }) => Some(*body),
Node::AnonConst(constant) => Some(constant.body), Node::AnonConst(constant) => Some(constant.body),
@ -279,8 +279,8 @@ impl<'hir> Map<'hir> {
} }
Node::Field(_) => DefKind::Field, Node::Field(_) => DefKind::Field,
Node::Expr(expr) => match expr.kind { Node::Expr(expr) => match expr.kind {
ExprKind::Closure { movability: None, .. } => DefKind::Closure, ExprKind::Closure(Closure { movability: None, .. }) => DefKind::Closure,
ExprKind::Closure { movability: Some(_), .. } => DefKind::Generator, ExprKind::Closure(Closure { movability: Some(_), .. }) => DefKind::Generator,
_ => bug!("def_kind: unsupported node: {}", self.node_to_string(hir_id)), _ => bug!("def_kind: unsupported node: {}", self.node_to_string(hir_id)),
}, },
Node::GenericParam(param) => match param.kind { Node::GenericParam(param) => match param.kind {
@ -1021,7 +1021,9 @@ impl<'hir> Map<'hir> {
_ => named_span(item.span, item.ident, None), _ => named_span(item.span, item.ident, None),
}, },
Node::Ctor(_) => return self.opt_span(self.get_parent_node(hir_id)), Node::Ctor(_) => return self.opt_span(self.get_parent_node(hir_id)),
Node::Expr(Expr { kind: ExprKind::Closure { fn_decl_span, .. }, .. }) => *fn_decl_span, Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl_span, .. }), .. }) => {
*fn_decl_span
}
_ => self.span_with_body(hir_id), _ => self.span_with_body(hir_id),
}; };
Some(span) Some(span)

View file

@ -68,9 +68,10 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
// Figure out what primary body this item has. // Figure out what primary body this item has.
let (body_id, return_ty_span, span_with_body) = match tcx.hir().get(id) { let (body_id, return_ty_span, span_with_body) = match tcx.hir().get(id) {
Node::Expr(hir::Expr { kind: hir::ExprKind::Closure { fn_decl, body, .. }, .. }) => { Node::Expr(hir::Expr {
(*body, fn_decl.output.span(), None) kind: hir::ExprKind::Closure(hir::Closure { fn_decl, body, .. }),
} ..
}) => (*body, fn_decl.output.span(), None),
Node::Item(hir::Item { Node::Item(hir::Item {
kind: hir::ItemKind::Fn(hir::FnSig { decl, .. }, _, body_id), kind: hir::ItemKind::Fn(hir::FnSig { decl, .. }, _, body_id),
span, span,

View file

@ -57,7 +57,13 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
hir::ExprKind::Loop(ref b, _, source, _) => { hir::ExprKind::Loop(ref b, _, source, _) => {
self.with_context(Loop(source), |v| v.visit_block(&b)); self.with_context(Loop(source), |v| v.visit_block(&b));
} }
hir::ExprKind::Closure { ref fn_decl, body, fn_decl_span, movability, .. } => { hir::ExprKind::Closure(&hir::Closure {
ref fn_decl,
body,
fn_decl_span,
movability,
..
}) => {
let cx = if let Some(Movability::Static) = movability { let cx = if let Some(Movability::Static) = movability {
AsyncClosure(fn_decl_span) AsyncClosure(fn_decl_span)
} else { } else {

View file

@ -273,7 +273,10 @@ impl<'tcx> ReachableContext<'tcx> {
} }
hir::ImplItemKind::TyAlias(_) => {} hir::ImplItemKind::TyAlias(_) => {}
}, },
Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { body, .. }, .. }) => { Node::Expr(&hir::Expr {
kind: hir::ExprKind::Closure(&hir::Closure { body, .. }),
..
}) => {
self.visit_nested_body(body); self.visit_nested_body(body);
} }
// Nothing to recurse on for these // Nothing to recurse on for these

View file

@ -571,7 +571,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
} }
fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) { fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
if let hir::ExprKind::Closure { binder, bound_generic_params, fn_decl, .. } = e.kind { if let hir::ExprKind::Closure(hir::Closure {
binder, bound_generic_params, fn_decl, ..
}) = e.kind
{
if let &hir::ClosureBinder::For { span: for_sp, .. } = binder { if let &hir::ClosureBinder::For { span: for_sp, .. } = binder {
fn span_of_infer(ty: &hir::Ty<'_>) -> Option<Span> { fn span_of_infer(ty: &hir::Ty<'_>) -> Option<Span> {
struct V(Option<Span>); struct V(Option<Span>);

View file

@ -1360,7 +1360,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
} }
} }
} }
hir::ExprKind::Closure { ref fn_decl, body, .. } => { hir::ExprKind::Closure(&hir::Closure { ref fn_decl, body, .. }) => {
let id = format!("${}", ex.hir_id); let id = format!("${}", ex.hir_id);
// walk arg and return types // walk arg and return types

View file

@ -1084,7 +1084,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let hir = self.tcx.hir(); let hir = self.tcx.hir();
Some(match node { Some(match node {
Node::Expr(&hir::Expr { Node::Expr(&hir::Expr {
kind: hir::ExprKind::Closure { body, fn_decl_span, .. }, kind: hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }),
.. ..
}) => ( }) => (
sm.guess_head_span(fn_decl_span), sm.guess_head_span(fn_decl_span),

View file

@ -103,7 +103,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
}) })
}), }),
hir::Node::Expr(hir::Expr { hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Closure { body, movability, .. }, kind: hir::ExprKind::Closure(hir::Closure { body, movability, .. }),
.. ..
}) => self.describe_generator(*body).or_else(|| { }) => self.describe_generator(*body).or_else(|| {
Some(if movability.is_some() { "an async closure" } else { "a closure" }) Some(if movability.is_some() { "an async closure" } else { "a closure" })

View file

@ -785,7 +785,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// Get the name of the callable and the arguments to be used in the suggestion. // Get the name of the callable and the arguments to be used in the suggestion.
let (snippet, sugg) = match hir.get_if_local(def_id) { let (snippet, sugg) = match hir.get_if_local(def_id) {
Some(hir::Node::Expr(hir::Expr { Some(hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Closure { fn_decl, fn_decl_span, .. }, kind: hir::ExprKind::Closure(hir::Closure { fn_decl, fn_decl_span, .. }),
.. ..
})) => { })) => {
err.span_label(*fn_decl_span, "consider calling this closure"); err.span_label(*fn_decl_span, "consider calling this closure");

View file

@ -285,29 +285,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let parent_node = hir.get(parent_hir_id); let parent_node = hir.get(parent_hir_id);
if let ( if let (
hir::Node::Expr(hir::Expr { hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Closure { fn_decl_span, body, .. }, kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, body, .. }),
.. ..
}), }),
hir::ExprKind::Block(..), hir::ExprKind::Block(..),
) = (parent_node, callee_node) ) = (parent_node, callee_node)
{ {
let fn_decl_span = if hir.body(*body).generator_kind let fn_decl_span = if hir.body(body).generator_kind
== Some(hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure)) == Some(hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure))
{ {
// Actually need to unwrap a few more layers of HIR to get to // Actually need to unwrap a few more layers of HIR to get to
// the _real_ closure... // the _real_ closure...
let async_closure = hir.get_parent_node(hir.get_parent_node(parent_hir_id)); let async_closure = hir.get_parent_node(hir.get_parent_node(parent_hir_id));
if let hir::Node::Expr(hir::Expr { if let hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Closure { fn_decl_span, .. }, kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }),
.. ..
}) = hir.get(async_closure) }) = hir.get(async_closure)
{ {
*fn_decl_span fn_decl_span
} else { } else {
return; return;
} }
} else { } else {
*fn_decl_span fn_decl_span
}; };
let start = fn_decl_span.shrink_to_lo(); let start = fn_decl_span.shrink_to_lo();

View file

@ -1577,8 +1577,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
let parent_id = fcx.tcx.hir().get_parent_node(id); let parent_id = fcx.tcx.hir().get_parent_node(id);
let parent = fcx.tcx.hir().get(parent_id); let parent = fcx.tcx.hir().get(parent_id);
if let Some(expr) = expression if let Some(expr) = expression
&& let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure { body, .. }, .. }) = parent && let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { body, .. }), .. }) = parent
&& !matches!(fcx.tcx.hir().body(*body).value.kind, hir::ExprKind::Block(..)) && !matches!(fcx.tcx.hir().body(body).value.kind, hir::ExprKind::Block(..))
{ {
fcx.suggest_missing_semicolon(&mut err, expr, expected, true); fcx.suggest_missing_semicolon(&mut err, expr, expected, true);
} }

View file

@ -483,7 +483,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let param_parent = self.tcx.hir().get_parent_node(*param_hir_id); let param_parent = self.tcx.hir().get_parent_node(*param_hir_id);
let Some(Node::Expr(hir::Expr { let Some(Node::Expr(hir::Expr {
hir_id: expr_hir_id, hir_id: expr_hir_id,
kind: hir::ExprKind::Closure { fn_decl: closure_fn_decl, .. }, kind: hir::ExprKind::Closure(hir::Closure { fn_decl: closure_fn_decl, .. }),
.. ..
})) = self.tcx.hir().find(param_parent) else { })) = self.tcx.hir().find(param_parent) else {
return None; return None;

View file

@ -35,7 +35,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_hir::{ExprKind, HirId, QPath}; use rustc_hir::{Closure, ExprKind, HirId, QPath};
use rustc_infer::infer; use rustc_infer::infer;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::InferOk; use rustc_infer::infer::InferOk;
@ -319,7 +319,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ExprKind::Match(discrim, arms, match_src) => { ExprKind::Match(discrim, arms, match_src) => {
self.check_match(expr, &discrim, arms, expected, match_src) self.check_match(expr, &discrim, arms, expected, match_src)
} }
ExprKind::Closure { capture_clause, fn_decl, body, movability, .. } => { ExprKind::Closure(&Closure { capture_clause, fn_decl, body, movability, .. }) => {
self.check_expr_closure(expr, capture_clause, &fn_decl, body, movability, expected) self.check_expr_closure(expr, capture_clause, &fn_decl, body, movability, expected)
} }
ExprKind::Block(body, _) => self.check_block_with_expected(&body, expected), ExprKind::Block(body, _) => self.check_block_with_expected(&body, expected),

View file

@ -1821,7 +1821,7 @@ fn label_fn_like<'tcx>(
} else { } else {
match tcx.hir().get_if_local(def_id) { match tcx.hir().get_if_local(def_id) {
Some(hir::Node::Expr(hir::Expr { Some(hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Closure { fn_decl_span, .. }, kind: hir::ExprKind::Closure(hir::Closure { fn_decl_span, .. }),
.. ..
})) => { })) => {
let spans: MultiSpan = (*fn_decl_span).into(); let spans: MultiSpan = (*fn_decl_span).into();

View file

@ -335,7 +335,7 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
match expr.kind { match expr.kind {
// Manually recurse over closures and inline consts, because they are the only // Manually recurse over closures and inline consts, because they are the only
// case of nested bodies that share the parent environment. // case of nested bodies that share the parent environment.
hir::ExprKind::Closure { body, .. } hir::ExprKind::Closure(&hir::Closure { body, .. })
| hir::ExprKind::ConstBlock(hir::AnonConst { body, .. }) => { | hir::ExprKind::ConstBlock(hir::AnonConst { body, .. }) => {
let body = visitor.tcx.hir().body(body); let body = visitor.tcx.hir().body(body);
visitor.visit_body(body); visitor.visit_body(body);

View file

@ -142,7 +142,7 @@ struct InferBorrowKindVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for InferBorrowKindVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for InferBorrowKindVisitor<'a, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) { fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
match expr.kind { match expr.kind {
hir::ExprKind::Closure { capture_clause, body: body_id, .. } => { hir::ExprKind::Closure(&hir::Closure { capture_clause, body: body_id, .. }) => {
let body = self.fcx.tcx.hir().body(body_id); let body = self.fcx.tcx.hir().body(body_id);
self.visit_body(body); self.visit_body(body);
self.fcx.analyze_closure(expr.hir_id, expr.span, body_id, body, capture_clause); self.fcx.analyze_closure(expr.hir_id, expr.span, body_id, body, capture_clause);

View file

@ -263,7 +263,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
self.fix_index_builtin_expr(e); self.fix_index_builtin_expr(e);
match e.kind { match e.kind {
hir::ExprKind::Closure { body, .. } => { hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
let body = self.fcx.tcx.hir().body(body); let body = self.fcx.tcx.hir().body(body);
for param in body.params { for param in body.params {
self.visit_node_id(e.span, param.hir_id); self.visit_node_id(e.span, param.hir_id);

View file

@ -1717,8 +1717,10 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
// provide junk type parameter defs - the only place that // provide junk type parameter defs - the only place that
// cares about anything but the length is instantiation, // cares about anything but the length is instantiation,
// and we don't do that for closures. // and we don't do that for closures.
if let Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { movability: gen, .. }, .. }) = if let Node::Expr(&hir::Expr {
node kind: hir::ExprKind::Closure(hir::Closure { movability: gen, .. }),
..
}) = node
{ {
let dummy_args = if gen.is_some() { let dummy_args = if gen.is_some() {
&["<resume_ty>", "<yield_ty>", "<return_ty>", "<witness>", "<upvars>"][..] &["<resume_ty>", "<yield_ty>", "<return_ty>", "<witness>", "<upvars>"][..]
@ -2564,7 +2566,7 @@ fn is_foreign_item(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
fn generator_kind(tcx: TyCtxt<'_>, def_id: DefId) -> Option<hir::GeneratorKind> { fn generator_kind(tcx: TyCtxt<'_>, def_id: DefId) -> Option<hir::GeneratorKind> {
match tcx.hir().get_if_local(def_id) { match tcx.hir().get_if_local(def_id) {
Some(Node::Expr(&rustc_hir::Expr { Some(Node::Expr(&rustc_hir::Expr {
kind: rustc_hir::ExprKind::Closure { body, .. }, kind: rustc_hir::ExprKind::Closure(&rustc_hir::Closure { body, .. }),
.. ..
})) => tcx.hir().body(body).generator_kind(), })) => tcx.hir().body(body).generator_kind(),
Some(_) => None, Some(_) => None,