Skip to content

Commit 7437136

Browse files
committed
Use CreateParameter mode for closures too.
1 parent 32af719 commit 7437136

File tree

6 files changed

+85
-67
lines changed

6 files changed

+85
-67
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+34-23
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
165165
if let Async::Yes { closure_id, .. } = asyncness {
166166
self.lower_expr_async_closure(
167167
capture_clause,
168+
e.id,
168169
closure_id,
169170
decl,
170171
body,
@@ -173,6 +174,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
173174
} else {
174175
self.lower_expr_closure(
175176
capture_clause,
177+
e.id,
176178
movability,
177179
decl,
178180
body,
@@ -604,6 +606,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
604606
// `static |_task_context| -> <ret_ty> { body }`:
605607
let generator_kind = hir::ExprKind::Closure {
606608
capture_clause,
609+
bound_generic_params: &[],
607610
fn_decl,
608611
body,
609612
fn_decl_span: self.lower_span(span),
@@ -828,6 +831,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
828831
fn lower_expr_closure(
829832
&mut self,
830833
capture_clause: CaptureBy,
834+
closure_id: NodeId,
831835
movability: Movability,
832836
decl: &FnDecl,
833837
body: &Expr,
@@ -848,16 +852,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
848852
(body_id, generator_option)
849853
});
850854

851-
// Lower outside new scope to preserve `is_in_loop_condition`.
852-
let fn_decl = self.lower_fn_decl(decl, None, FnDeclKind::Closure, None);
853-
854-
hir::ExprKind::Closure {
855-
capture_clause,
856-
fn_decl,
857-
body,
858-
fn_decl_span: self.lower_span(fn_decl_span),
859-
movability: generator_option,
860-
}
855+
self.with_lifetime_binder(closure_id, &[], |this, bound_generic_params| {
856+
// Lower outside new scope to preserve `is_in_loop_condition`.
857+
let fn_decl = this.lower_fn_decl(decl, None, FnDeclKind::Closure, None);
858+
859+
hir::ExprKind::Closure {
860+
capture_clause,
861+
bound_generic_params,
862+
fn_decl,
863+
body,
864+
fn_decl_span: this.lower_span(fn_decl_span),
865+
movability: generator_option,
866+
}
867+
})
861868
}
862869

863870
fn generator_movability_for_fn(
@@ -897,6 +904,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
897904
&mut self,
898905
capture_clause: CaptureBy,
899906
closure_id: NodeId,
907+
inner_closure_id: NodeId,
900908
decl: &FnDecl,
901909
body: &Expr,
902910
fn_decl_span: Span,
@@ -927,7 +935,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
927935
if let FnRetTy::Ty(ty) = &decl.output { Some(ty.clone()) } else { None };
928936
let async_body = this.make_async_expr(
929937
capture_clause,
930-
closure_id,
938+
inner_closure_id,
931939
async_ret_ty,
932940
body.span,
933941
hir::AsyncGeneratorKind::Closure,
@@ -938,18 +946,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
938946
body_id
939947
});
940948

941-
// We need to lower the declaration outside the new scope, because we
942-
// have to conserve the state of being inside a loop condition for the
943-
// closure argument types.
944-
let fn_decl = self.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None);
945-
946-
hir::ExprKind::Closure {
947-
capture_clause,
948-
fn_decl,
949-
body,
950-
fn_decl_span: self.lower_span(fn_decl_span),
951-
movability: None,
952-
}
949+
self.with_lifetime_binder(closure_id, &[], |this, bound_generic_params| {
950+
// We need to lower the declaration outside the new scope, because we
951+
// have to conserve the state of being inside a loop condition for the
952+
// closure argument types.
953+
let fn_decl = this.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None);
954+
955+
hir::ExprKind::Closure {
956+
capture_clause,
957+
bound_generic_params,
958+
fn_decl,
959+
body,
960+
fn_decl_span: this.lower_span(fn_decl_span),
961+
movability: None,
962+
}
963+
})
953964
}
954965

955966
/// Destructure the LHS of complex assignments.

compiler/rustc_hir/src/hir.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1932,6 +1932,7 @@ pub enum ExprKind<'hir> {
19321932
/// `Option<Movability>`.
19331933
Closure {
19341934
capture_clause: CaptureBy,
1935+
bound_generic_params: &'hir [GenericParam<'hir>],
19351936
fn_decl: &'hir FnDecl<'hir>,
19361937
body: BodyId,
19371938
fn_decl_span: Span,
@@ -3480,7 +3481,7 @@ impl<'hir> Node<'hir> {
34803481
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
34813482
mod size_asserts {
34823483
rustc_data_structures::static_assert_size!(super::Block<'static>, 48);
3483-
rustc_data_structures::static_assert_size!(super::Expr<'static>, 56);
3484+
rustc_data_structures::static_assert_size!(super::Expr<'static>, 64);
34843485
rustc_data_structures::static_assert_size!(super::Pat<'static>, 88);
34853486
rustc_data_structures::static_assert_size!(super::QPath<'static>, 24);
34863487
rustc_data_structures::static_assert_size!(super::Ty<'static>, 72);

compiler/rustc_hir/src/intravisit.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1169,12 +1169,16 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
11691169
walk_list!(visitor, visit_arm, arms);
11701170
}
11711171
ExprKind::Closure {
1172+
bound_generic_params,
11721173
ref fn_decl,
11731174
body,
11741175
capture_clause: _,
11751176
fn_decl_span: _,
11761177
movability: _,
1177-
} => visitor.visit_fn(FnKind::Closure, fn_decl, body, expression.span, expression.hir_id),
1178+
} => {
1179+
walk_list!(visitor, visit_generic_param, bound_generic_params);
1180+
visitor.visit_fn(FnKind::Closure, fn_decl, body, expression.span, expression.hir_id)
1181+
}
11781182
ExprKind::Block(ref block, ref opt_label) => {
11791183
walk_list!(visitor, visit_label, opt_label);
11801184
visitor.visit_block(block);

compiler/rustc_hir_pretty/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1459,11 +1459,13 @@ impl<'a> State<'a> {
14591459
}
14601460
hir::ExprKind::Closure {
14611461
capture_clause,
1462+
bound_generic_params,
14621463
ref fn_decl,
14631464
body,
14641465
fn_decl_span: _,
14651466
movability: _,
14661467
} => {
1468+
self.print_formal_generic_params(bound_generic_params);
14671469
self.print_capture_clause(capture_clause);
14681470

14691471
self.print_closure_params(&fn_decl, body);

compiler/rustc_resolve/src/late.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -845,11 +845,13 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
845845
}
846846
}
847847
FnKind::Closure(declaration, body) => {
848-
// Do not attempt to create generic lifetime parameters.
849-
// FIXME: Revisit this decision once `for<>` bounds on closures become a
850-
// thing.
848+
// We do not have any explicit generic lifetime parameter.
849+
// FIXME(rfc3216): Change when implementing `for<>` bounds on closures.
851850
this.with_lifetime_rib(
852-
LifetimeRibKind::AnonymousPassThrough(fn_id, false),
851+
LifetimeRibKind::AnonymousCreateParameter {
852+
binder: fn_id,
853+
report_in_path: false,
854+
},
853855
// Add each argument to the rib.
854856
|this| this.resolve_params(&declaration.inputs),
855857
);
@@ -1582,7 +1584,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
15821584
}
15831585
break;
15841586
}
1585-
_ => {}
1587+
LifetimeRibKind::AnonymousCreateParameter { .. }
1588+
| LifetimeRibKind::Generics { .. }
1589+
| LifetimeRibKind::ConstGeneric
1590+
| LifetimeRibKind::AnonConst => {}
15861591
}
15871592
}
15881593
continue;

compiler/rustc_resolve/src/late/lifetimes.rs

+32-37
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ use std::cell::Cell;
2929
use std::fmt;
3030
use std::mem::take;
3131

32-
use tracing::{debug, span, Level};
33-
3432
trait RegionExt {
3533
fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (LocalDefId, Region);
3634

@@ -572,41 +570,38 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
572570
});
573571
}
574572

575-
fn visit_fn(
576-
&mut self,
577-
fk: intravisit::FnKind<'tcx>,
578-
fd: &'tcx hir::FnDecl<'tcx>,
579-
b: hir::BodyId,
580-
s: rustc_span::Span,
581-
hir_id: hir::HirId,
582-
) {
583-
let name = match fk {
584-
intravisit::FnKind::ItemFn(id, _, _) => id.name,
585-
intravisit::FnKind::Method(id, _) => id.name,
586-
intravisit::FnKind::Closure => sym::closure,
587-
};
588-
let name = name.as_str();
589-
let span = span!(Level::DEBUG, "visit_fn", name);
590-
let _enter = span.enter();
591-
match fk {
592-
// Any `Binders` are handled elsewhere
593-
intravisit::FnKind::ItemFn(..) | intravisit::FnKind::Method(..) => {
594-
intravisit::walk_fn(self, fk, fd, b, s, hir_id)
595-
}
596-
intravisit::FnKind::Closure => {
597-
self.map.late_bound_vars.insert(hir_id, vec![]);
598-
let scope = Scope::Binder {
599-
hir_id,
600-
lifetimes: FxIndexMap::default(),
601-
next_early_index: self.next_early_index(),
602-
s: self.scope,
603-
opaque_type_parent: false,
604-
scope_type: BinderScopeType::Normal,
605-
allow_late_bound: true,
606-
where_bound_origin: None,
607-
};
608-
self.with(scope, move |this| intravisit::walk_fn(this, fk, fd, b, s, hir_id));
609-
}
573+
fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
574+
if let hir::ExprKind::Closure { bound_generic_params, .. } = e.kind {
575+
let next_early_index = self.next_early_index();
576+
let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) =
577+
bound_generic_params
578+
.iter()
579+
.filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
580+
.enumerate()
581+
.map(|(late_bound_idx, param)| {
582+
let pair = Region::late(late_bound_idx as u32, self.tcx.hir(), param);
583+
let r = late_region_as_bound_region(self.tcx, &pair.1);
584+
(pair, r)
585+
})
586+
.unzip();
587+
self.map.late_bound_vars.insert(e.hir_id, binders);
588+
let scope = Scope::Binder {
589+
hir_id: e.hir_id,
590+
lifetimes,
591+
s: self.scope,
592+
next_early_index,
593+
opaque_type_parent: false,
594+
scope_type: BinderScopeType::Normal,
595+
allow_late_bound: true,
596+
where_bound_origin: None,
597+
};
598+
self.with(scope, |this| {
599+
// a closure has no bounds, so everything
600+
// contained within is scoped within its binder.
601+
intravisit::walk_expr(this, e)
602+
});
603+
} else {
604+
intravisit::walk_expr(self, e)
610605
}
611606
}
612607

0 commit comments

Comments
 (0)