about summary refs log tree commit diff
path: root/compiler/rustc_resolve/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-02-12 21:42:10 +0000
committerbors <bors@rust-lang.org>2022-02-12 21:42:10 +0000
commit3cfa4def7c87d571bd46d92fed608edf8fad236e (patch)
tree43fadb34acfa47419ac74221dbca1161938dbeee /compiler/rustc_resolve/src
parent5d8767cb229b097fedb1dd4bd9420d463c37774f (diff)
parent10cf626d0ea7be3eb971691772b5eb30013d4f02 (diff)
downloadrust-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.rs34
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;