Explicitly gather lifetimes and definitions for bare async fns
This commit is contained in:
parent
25825cd4fa
commit
19dcbd151b
1 changed files with 30 additions and 39 deletions
|
@ -751,31 +751,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Setup lifetime capture for and impl-trait.
|
||||
/// The captures will be added to `captures`.
|
||||
fn while_capturing_lifetimes<T>(
|
||||
&mut self,
|
||||
parent_def_id: LocalDefId,
|
||||
captures: &mut FxHashMap<LocalDefId, (Span, NodeId, ParamName, LifetimeRes)>,
|
||||
f: impl FnOnce(&mut Self) -> T,
|
||||
) -> T {
|
||||
let lifetime_stash = std::mem::replace(
|
||||
&mut self.captured_lifetimes,
|
||||
Some(LifetimeCaptureContext {
|
||||
parent_def_id,
|
||||
captures: std::mem::take(captures),
|
||||
binders_to_ignore: Default::default(),
|
||||
}),
|
||||
);
|
||||
|
||||
let ret = f(self);
|
||||
|
||||
let ctxt = std::mem::replace(&mut self.captured_lifetimes, lifetime_stash).unwrap();
|
||||
*captures = ctxt.captures;
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
/// Register a binder to be ignored for lifetime capture.
|
||||
#[tracing::instrument(level = "debug", skip(self, f))]
|
||||
#[inline]
|
||||
|
@ -1786,8 +1761,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
debug!(?captures);
|
||||
|
||||
self.with_hir_id_owner(opaque_ty_node_id, |this| {
|
||||
let future_bound =
|
||||
this.while_capturing_lifetimes(opaque_ty_def_id, &mut captures, |this| {
|
||||
let lifetime_stash = std::mem::replace(
|
||||
&mut this.captured_lifetimes,
|
||||
Some(LifetimeCaptureContext {
|
||||
parent_def_id: opaque_ty_def_id,
|
||||
captures: std::mem::take(&mut captures),
|
||||
binders_to_ignore: Default::default(),
|
||||
}),
|
||||
);
|
||||
|
||||
let (lifetimes_in_bounds, binders_to_ignore) = ast::lifetimes_in_ret_ty(output);
|
||||
debug!(?lifetimes_in_bounds);
|
||||
debug!(?binders_to_ignore);
|
||||
|
||||
this.create_and_capture_lifetime_defs(&lifetimes_in_bounds, &binders_to_ignore);
|
||||
|
||||
// We have to be careful to get elision right here. The
|
||||
// idea is that we create a lifetime parameter for each
|
||||
// lifetime in the return type. So, given a return type
|
||||
|
@ -1796,10 +1784,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
//
|
||||
// Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
|
||||
// hence the elision takes place at the fn site.
|
||||
this.lower_async_fn_output_type_to_future_bound(output, fn_def_id, span)
|
||||
});
|
||||
debug!("lower_async_fn_ret_ty: future_bound={:#?}", future_bound);
|
||||
debug!("lower_async_fn_ret_ty: captures={:#?}", captures);
|
||||
let ret = this.lower_async_fn_output_type_to_future_bound(output, fn_def_id, span);
|
||||
|
||||
let ctxt = std::mem::replace(&mut this.captured_lifetimes, lifetime_stash).unwrap();
|
||||
|
||||
captures = ctxt.captures;
|
||||
|
||||
let future_bound = ret;
|
||||
|
||||
let generic_params =
|
||||
this.arena.alloc_from_iter(captures.iter().map(|(_, &(span, p_id, p_name, _))| {
|
||||
|
|
Loading…
Add table
Reference in a new issue