Auto merge of #91403 - cjgillot:inherit-async, r=oli-obk
Inherit lifetimes for async fn instead of duplicating them. The current desugaring of `async fn foo<'a>(&usize) -> &u8` is equivalent to ```rust fn foo<'a, '0>(&'0 usize) -> foo<'static, 'static>::Opaque<'a, '0, '_>; type foo<'_a, '_0>::Opaque<'a, '0, '1> = impl Future<Output = &'1 u8>; ``` following the RPIT model. Duplicating all the inherited lifetime parameters and setting the inherited version to `'static` makes lowering more complex and causes issues like #61949. This PR removes the duplication of inherited lifetimes to directly use ```rust fn foo<'a, '0>(&'0 usize) -> foo<'a, '0>::Opaque<'_>; type foo<'a, '0>::Opaque<'1> = impl Future<Output = &'1 u8>; ``` following the TAIT model. Fixes https://github.com/rust-lang/rust/issues/61949
This commit is contained in:
commit
3cfa4def7c
34 changed files with 227 additions and 281 deletions
|
@ -729,9 +729,16 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
match item.kind {
|
||||
hir::ItemKind::Fn(ref sig, ref generics, _) => {
|
||||
self.missing_named_lifetime_spots.push(generics.into());
|
||||
self.visit_early_late(None, item.hir_id(), &sig.decl, generics, |this| {
|
||||
intravisit::walk_item(this, item);
|
||||
});
|
||||
self.visit_early_late(
|
||||
None,
|
||||
item.hir_id(),
|
||||
&sig.decl,
|
||||
generics,
|
||||
sig.header.asyncness,
|
||||
|this| {
|
||||
intravisit::walk_item(this, item);
|
||||
},
|
||||
);
|
||||
self.missing_named_lifetime_spots.pop();
|
||||
}
|
||||
|
||||
|
@ -849,11 +856,16 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
|
||||
fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
|
||||
match item.kind {
|
||||
hir::ForeignItemKind::Fn(ref decl, _, ref generics) => {
|
||||
self.visit_early_late(None, item.hir_id(), decl, generics, |this| {
|
||||
hir::ForeignItemKind::Fn(ref decl, _, ref generics) => self.visit_early_late(
|
||||
None,
|
||||
item.hir_id(),
|
||||
decl,
|
||||
generics,
|
||||
hir::IsAsync::NotAsync,
|
||||
|this| {
|
||||
intravisit::walk_foreign_item(this, item);
|
||||
})
|
||||
}
|
||||
},
|
||||
),
|
||||
hir::ForeignItemKind::Static(..) => {
|
||||
intravisit::walk_foreign_item(self, item);
|
||||
}
|
||||
|
@ -1130,6 +1142,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
trait_item.hir_id(),
|
||||
&sig.decl,
|
||||
&trait_item.generics,
|
||||
sig.header.asyncness,
|
||||
|this| intravisit::walk_trait_item(this, trait_item),
|
||||
);
|
||||
self.missing_named_lifetime_spots.pop();
|
||||
|
@ -1199,6 +1212,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
impl_item.hir_id(),
|
||||
&sig.decl,
|
||||
&impl_item.generics,
|
||||
sig.header.asyncness,
|
||||
|this| intravisit::walk_impl_item(this, impl_item),
|
||||
);
|
||||
self.missing_named_lifetime_spots.pop();
|
||||
|
@ -2159,11 +2173,15 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
hir_id: hir::HirId,
|
||||
decl: &'tcx hir::FnDecl<'tcx>,
|
||||
generics: &'tcx hir::Generics<'tcx>,
|
||||
asyncness: hir::IsAsync,
|
||||
walk: F,
|
||||
) where
|
||||
F: for<'b, 'c> FnOnce(&'b mut LifetimeContext<'c, 'tcx>),
|
||||
{
|
||||
insert_late_bound_lifetimes(self.map, decl, generics);
|
||||
// Async fns need all their lifetime parameters to be early bound.
|
||||
if asyncness != hir::IsAsync::Async {
|
||||
insert_late_bound_lifetimes(self.map, decl, generics);
|
||||
}
|
||||
|
||||
// Find the start of nested early scopes, e.g., in methods.
|
||||
let mut next_early_index = 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue