diff options
| author | Camille GILLOT <gillot.camille@gmail.com> | 2022-05-23 15:50:02 +0200 |
|---|---|---|
| committer | Camille GILLOT <gillot.camille@gmail.com> | 2022-06-21 21:13:43 +0200 |
| commit | 7437136f0eac3f2ee58de08a784b1e9eae42b619 (patch) | |
| tree | 0924e2ca0dbce0946a33a5bf1cd887207eda16cc | |
| parent | 32af719b07217ff89e61a2031500cee138599baa (diff) | |
| download | rust-7437136f0eac3f2ee58de08a784b1e9eae42b619.tar.gz rust-7437136f0eac3f2ee58de08a784b1e9eae42b619.zip | |
Use CreateParameter mode for closures too.
| -rw-r--r-- | compiler/rustc_ast_lowering/src/expr.rs | 57 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/hir.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/intravisit.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_hir_pretty/src/lib.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 15 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/lifetimes.rs | 69 |
6 files changed, 85 insertions, 67 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 095a4b26a86..3babe73030a 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -165,6 +165,7 @@ impl<'hir> LoweringContext<'_, 'hir> { if let Async::Yes { closure_id, .. } = asyncness { self.lower_expr_async_closure( capture_clause, + e.id, closure_id, decl, body, @@ -173,6 +174,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } else { self.lower_expr_closure( capture_clause, + e.id, movability, decl, body, @@ -604,6 +606,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // `static |_task_context| -> <ret_ty> { body }`: let generator_kind = hir::ExprKind::Closure { capture_clause, + bound_generic_params: &[], fn_decl, body, fn_decl_span: self.lower_span(span), @@ -828,6 +831,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_expr_closure( &mut self, capture_clause: CaptureBy, + closure_id: NodeId, movability: Movability, decl: &FnDecl, body: &Expr, @@ -848,16 +852,19 @@ impl<'hir> LoweringContext<'_, 'hir> { (body_id, generator_option) }); - // Lower outside new scope to preserve `is_in_loop_condition`. - let fn_decl = self.lower_fn_decl(decl, None, FnDeclKind::Closure, None); - - hir::ExprKind::Closure { - capture_clause, - fn_decl, - body, - fn_decl_span: self.lower_span(fn_decl_span), - movability: generator_option, - } + self.with_lifetime_binder(closure_id, &[], |this, bound_generic_params| { + // 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 { + capture_clause, + bound_generic_params, + fn_decl, + body, + fn_decl_span: this.lower_span(fn_decl_span), + movability: generator_option, + } + }) } fn generator_movability_for_fn( @@ -897,6 +904,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, capture_clause: CaptureBy, closure_id: NodeId, + inner_closure_id: NodeId, decl: &FnDecl, body: &Expr, fn_decl_span: Span, @@ -927,7 +935,7 @@ impl<'hir> LoweringContext<'_, 'hir> { if let FnRetTy::Ty(ty) = &decl.output { Some(ty.clone()) } else { None }; let async_body = this.make_async_expr( capture_clause, - closure_id, + inner_closure_id, async_ret_ty, body.span, hir::AsyncGeneratorKind::Closure, @@ -938,18 +946,21 @@ impl<'hir> LoweringContext<'_, 'hir> { body_id }); - // We need to lower the declaration outside the new scope, because we - // have to conserve the state of being inside a loop condition for the - // closure argument types. - let fn_decl = self.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None); - - hir::ExprKind::Closure { - capture_clause, - fn_decl, - body, - fn_decl_span: self.lower_span(fn_decl_span), - movability: None, - } + self.with_lifetime_binder(closure_id, &[], |this, bound_generic_params| { + // We need to lower the declaration outside the new scope, because we + // have to conserve the state of being inside a loop condition for the + // closure argument types. + let fn_decl = this.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None); + + hir::ExprKind::Closure { + capture_clause, + bound_generic_params, + fn_decl, + body, + fn_decl_span: this.lower_span(fn_decl_span), + movability: None, + } + }) } /// Destructure the LHS of complex assignments. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 5a06f8eab7e..a7fc59255d7 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1932,6 +1932,7 @@ pub enum ExprKind<'hir> { /// `Option<Movability>`. Closure { capture_clause: CaptureBy, + bound_generic_params: &'hir [GenericParam<'hir>], fn_decl: &'hir FnDecl<'hir>, body: BodyId, fn_decl_span: Span, @@ -3480,7 +3481,7 @@ impl<'hir> Node<'hir> { #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] mod size_asserts { rustc_data_structures::static_assert_size!(super::Block<'static>, 48); - rustc_data_structures::static_assert_size!(super::Expr<'static>, 56); + rustc_data_structures::static_assert_size!(super::Expr<'static>, 64); rustc_data_structures::static_assert_size!(super::Pat<'static>, 88); rustc_data_structures::static_assert_size!(super::QPath<'static>, 24); rustc_data_structures::static_assert_size!(super::Ty<'static>, 72); diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index cce5aa9f732..e68274e2ad9 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1169,12 +1169,16 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) walk_list!(visitor, visit_arm, arms); } ExprKind::Closure { + bound_generic_params, ref fn_decl, body, capture_clause: _, fn_decl_span: _, movability: _, - } => visitor.visit_fn(FnKind::Closure, fn_decl, body, expression.span, expression.hir_id), + } => { + walk_list!(visitor, visit_generic_param, bound_generic_params); + visitor.visit_fn(FnKind::Closure, fn_decl, body, expression.span, expression.hir_id) + } ExprKind::Block(ref block, ref opt_label) => { walk_list!(visitor, visit_label, opt_label); visitor.visit_block(block); diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 7317ce7335a..7bf91df9f76 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1459,11 +1459,13 @@ impl<'a> State<'a> { } hir::ExprKind::Closure { capture_clause, + bound_generic_params, ref fn_decl, body, fn_decl_span: _, movability: _, } => { + self.print_formal_generic_params(bound_generic_params); self.print_capture_clause(capture_clause); self.print_closure_params(&fn_decl, body); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 08d6134237a..e36f55b2e02 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -845,11 +845,13 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { } } FnKind::Closure(declaration, body) => { - // Do not attempt to create generic lifetime parameters. - // FIXME: Revisit this decision once `for<>` bounds on closures become a - // thing. + // We do not have any explicit generic lifetime parameter. + // FIXME(rfc3216): Change when implementing `for<>` bounds on closures. this.with_lifetime_rib( - LifetimeRibKind::AnonymousPassThrough(fn_id, false), + LifetimeRibKind::AnonymousCreateParameter { + binder: fn_id, + report_in_path: false, + }, // Add each argument to the rib. |this| this.resolve_params(&declaration.inputs), ); @@ -1582,7 +1584,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { } break; } - _ => {} + LifetimeRibKind::AnonymousCreateParameter { .. } + | LifetimeRibKind::Generics { .. } + | LifetimeRibKind::ConstGeneric + | LifetimeRibKind::AnonConst => {} } } continue; diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 53f6870bdf5..172dc7ffe95 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -29,8 +29,6 @@ use std::cell::Cell; use std::fmt; use std::mem::take; -use tracing::{debug, span, Level}; - trait RegionExt { fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (LocalDefId, Region); @@ -572,41 +570,38 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }); } - fn visit_fn( - &mut self, - fk: intravisit::FnKind<'tcx>, - fd: &'tcx hir::FnDecl<'tcx>, - b: hir::BodyId, - s: rustc_span::Span, - hir_id: hir::HirId, - ) { - let name = match fk { - intravisit::FnKind::ItemFn(id, _, _) => id.name, - intravisit::FnKind::Method(id, _) => id.name, - intravisit::FnKind::Closure => sym::closure, - }; - let name = name.as_str(); - let span = span!(Level::DEBUG, "visit_fn", name); - let _enter = span.enter(); - match fk { - // Any `Binders` are handled elsewhere - intravisit::FnKind::ItemFn(..) | intravisit::FnKind::Method(..) => { - intravisit::walk_fn(self, fk, fd, b, s, hir_id) - } - intravisit::FnKind::Closure => { - self.map.late_bound_vars.insert(hir_id, vec![]); - let scope = Scope::Binder { - hir_id, - lifetimes: FxIndexMap::default(), - next_early_index: self.next_early_index(), - s: self.scope, - opaque_type_parent: false, - scope_type: BinderScopeType::Normal, - allow_late_bound: true, - where_bound_origin: None, - }; - self.with(scope, move |this| intravisit::walk_fn(this, fk, fd, b, s, hir_id)); - } + fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) { + if let hir::ExprKind::Closure { bound_generic_params, .. } = e.kind { + let next_early_index = self.next_early_index(); + let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) = + bound_generic_params + .iter() + .filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. })) + .enumerate() + .map(|(late_bound_idx, param)| { + let pair = Region::late(late_bound_idx as u32, self.tcx.hir(), param); + let r = late_region_as_bound_region(self.tcx, &pair.1); + (pair, r) + }) + .unzip(); + self.map.late_bound_vars.insert(e.hir_id, binders); + let scope = Scope::Binder { + hir_id: e.hir_id, + lifetimes, + s: self.scope, + next_early_index, + opaque_type_parent: false, + scope_type: BinderScopeType::Normal, + allow_late_bound: true, + where_bound_origin: None, + }; + self.with(scope, |this| { + // a closure has no bounds, so everything + // contained within is scoped within its binder. + intravisit::walk_expr(this, e) + }); + } else { + intravisit::walk_expr(self, e) } } |
