diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 77babeb5d39d1..89655eafea92d 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -847,21 +847,22 @@ impl<'hir> LoweringContext<'_, 'hir> { (body_id, generator_option) }); - let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params); - // Lower outside new scope to preserve `is_in_loop_condition`. - let fn_decl = self.lower_fn_decl(decl, None, FnDeclKind::Closure, None); - - let c = self.arena.alloc(hir::Closure { - binder: binder_clause, - capture_clause, - bound_generic_params, - fn_decl, - body: body_id, - fn_decl_span: self.lower_span(fn_decl_span), - movability: generator_option, - }); + self.lower_lifetime_binder(closure_id, generic_params, |lctx, bound_generic_params| { + // Lower outside new scope to preserve `is_in_loop_condition`. + let fn_decl = lctx.lower_fn_decl(decl, None, FnDeclKind::Closure, None); + + let c = lctx.arena.alloc(hir::Closure { + binder: binder_clause, + capture_clause, + bound_generic_params, + fn_decl, + body: body_id, + fn_decl_span: lctx.lower_span(fn_decl_span), + movability: generator_option, + }); - hir::ExprKind::Closure(c) + hir::ExprKind::Closure(c) + }) } fn generator_movability_for_fn( @@ -948,23 +949,23 @@ impl<'hir> LoweringContext<'_, 'hir> { body_id }); - let bound_generic_params = self.lower_lifetime_binder(closure_id, 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 = self.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None); - - let c = self.arena.alloc(hir::Closure { - binder: binder_clause, - capture_clause, - bound_generic_params, - fn_decl, - body, - fn_decl_span: self.lower_span(fn_decl_span), - movability: None, - }); - hir::ExprKind::Closure(c) + self.lower_lifetime_binder(closure_id, generic_params, |lctx, 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 = lctx.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None); + + let c = lctx.arena.alloc(hir::Closure { + binder: binder_clause, + capture_clause, + bound_generic_params, + fn_decl, + body, + fn_decl_span: lctx.lower_span(fn_decl_span), + movability: None, + }); + hir::ExprKind::Closure(c) + }) } /// Destructure the LHS of complex assignments. diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 3a94c7a91b23f..b8becd9b149c6 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -808,23 +808,31 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// name resolver owing to lifetime elision; this also populates the resolver's node-id->def-id /// map, so that later calls to `opt_node_id_to_def_id` that refer to these extra lifetime /// parameters will be successful. - #[instrument(level = "debug", skip(self))] + #[instrument(level = "debug", skip(self, in_binder))] #[inline] - fn lower_lifetime_binder( + fn lower_lifetime_binder( &mut self, binder: NodeId, generic_params: &[GenericParam], - ) -> &'hir [hir::GenericParam<'hir>] { - let mut generic_params: Vec<_> = self.lower_generic_params_mut(generic_params).collect(); + in_binder: impl FnOnce(&mut Self, &'hir [hir::GenericParam<'hir>]) -> R, + ) -> R { let extra_lifetimes = self.resolver.take_extra_lifetime_params(binder); debug!(?extra_lifetimes); - generic_params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| { - self.lifetime_res_to_generic_param(ident, node_id, res) - })); + let extra_lifetimes: Vec<_> = extra_lifetimes + .into_iter() + .filter_map(|(ident, node_id, res)| { + self.lifetime_res_to_generic_param(ident, node_id, res) + }) + .collect(); + + let generic_params: Vec<_> = self + .lower_generic_params_mut(generic_params) + .chain(extra_lifetimes.into_iter()) + .collect(); let generic_params = self.arena.alloc_from_iter(generic_params); debug!(?generic_params); - generic_params + in_binder(self, generic_params) } fn with_dyn_type_scope(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T { @@ -1233,14 +1241,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::TyKind::Rptr(lifetime, self.lower_mt(mt, itctx)) } TyKind::BareFn(ref f) => { - let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params); - hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy { - generic_params, - unsafety: self.lower_unsafety(f.unsafety), - abi: self.lower_extern(f.ext), - decl: self.lower_fn_decl(&f.decl, None, FnDeclKind::Pointer, None), - param_names: self.lower_fn_params_to_names(&f.decl), - })) + self.lower_lifetime_binder(t.id, &f.generic_params, |lctx, generic_params| { + hir::TyKind::BareFn(lctx.arena.alloc(hir::BareFnTy { + generic_params, + unsafety: lctx.lower_unsafety(f.unsafety), + abi: lctx.lower_extern(f.ext), + decl: lctx.lower_fn_decl(&f.decl, None, FnDeclKind::Pointer, None), + param_names: lctx.lower_fn_params_to_names(&f.decl), + })) + }) } TyKind::Never => hir::TyKind::Never, TyKind::Tup(ref tys) => hir::TyKind::Tup( @@ -2133,10 +2142,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { p: &PolyTraitRef, itctx: ImplTraitContext, ) -> hir::PolyTraitRef<'hir> { - let bound_generic_params = - self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params); - let trait_ref = self.lower_trait_ref(&p.trait_ref, itctx); - hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) } + self.lower_lifetime_binder( + p.trait_ref.ref_id, + &p.bound_generic_params, + |lctx, bound_generic_params| { + let trait_ref = lctx.lower_trait_ref(&p.trait_ref, itctx); + hir::PolyTraitRef { bound_generic_params, trait_ref, span: lctx.lower_span(p.span) } + }, + ) } fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {