Skip to content

Commit

Permalink
Allow lower_lifetime_binder receive a closure
Browse files Browse the repository at this point in the history
  • Loading branch information
spastorino committed Sep 7, 2022
1 parent 3c72788 commit 36fa12f
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 51 deletions.
63 changes: 32 additions & 31 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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.
Expand Down
53 changes: 33 additions & 20 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<R>(
&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<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T {
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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> {
Expand Down

0 comments on commit 36fa12f

Please sign in to comment.