diff options
| author | bors <bors@rust-lang.org> | 2022-02-12 21:42:10 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-02-12 21:42:10 +0000 |
| commit | 3cfa4def7c87d571bd46d92fed608edf8fad236e (patch) | |
| tree | 43fadb34acfa47419ac74221dbca1161938dbeee /compiler/rustc_resolve/src | |
| parent | 5d8767cb229b097fedb1dd4bd9420d463c37774f (diff) | |
| parent | 10cf626d0ea7be3eb971691772b5eb30013d4f02 (diff) | |
| download | rust-3cfa4def7c87d571bd46d92fed608edf8fad236e.tar.gz rust-3cfa4def7c87d571bd46d92fed608edf8fad236e.zip | |
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
Diffstat (limited to 'compiler/rustc_resolve/src')
| -rw-r--r-- | compiler/rustc_resolve/src/late/lifetimes.rs | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 5a1378a3686..d25bee67d4e 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -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; |
