about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-09-23 00:49:25 +0000
committerMichael Goulet <michael@errs.io>2022-09-24 19:26:54 +0000
commit3d7e9a7b27c735a8eb2fe05781bb7b4331572983 (patch)
treed9f903e8a61ad4254e1fa80d28a5f277a8932fdb
parent59c4a92bafaf19e2d9039436294aa805d748ce0f (diff)
downloadrust-3d7e9a7b27c735a8eb2fe05781bb7b4331572983.tar.gz
rust-3d7e9a7b27c735a8eb2fe05781bb7b4331572983.zip
Only record extra lifetime params for async trait fn with no body
-rw-r--r--compiler/rustc_resolve/src/late.rs78
-rw-r--r--src/test/ui/async-await/issue-102138.rs46
-rw-r--r--src/test/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs2
-rw-r--r--src/test/ui/resolve/issue-69401-trait-fn-no-body-ty-local.stderr6
4 files changed, 44 insertions, 88 deletions
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index d38eca23ade..558db003867 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -789,8 +789,9 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
         let previous_value = self.diagnostic_metadata.current_function;
         match fn_kind {
             // Bail if the function is foreign, and thus cannot validly have
-            // a body.
-            FnKind::Fn(FnCtxt::Foreign, _, sig, _, generics, _) => {
+            // a body, or if there's no body for some other reason.
+            FnKind::Fn(FnCtxt::Foreign, _, sig, _, generics, _)
+            | FnKind::Fn(_, _, sig, _, generics, None) => {
                 self.visit_fn_header(&sig.header);
                 self.visit_generics(generics);
                 self.with_lifetime_rib(
@@ -804,7 +805,12 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                             sig.decl.has_self(),
                             sig.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)),
                             &sig.decl.output,
-                        )
+                        );
+
+                        this.record_lifetime_params_for_async(
+                            fn_id,
+                            sig.header.asyncness.opt_return_id(),
+                        );
                     },
                 );
                 return;
@@ -846,41 +852,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                             },
                         );
 
-                        // Construct the list of in-scope lifetime parameters for async lowering.
-                        // We include all lifetime parameters, either named or "Fresh".
-                        // The order of those parameters does not matter, as long as it is
-                        // deterministic.
-                        if let Some((async_node_id, _)) = async_node_id {
-                            let mut extra_lifetime_params = this
-                                .r
-                                .extra_lifetime_params_map
-                                .get(&fn_id)
-                                .cloned()
-                                .unwrap_or_default();
-                            for rib in this.lifetime_ribs.iter().rev() {
-                                extra_lifetime_params.extend(
-                                    rib.bindings
-                                        .iter()
-                                        .map(|(&ident, &(node_id, res))| (ident, node_id, res)),
-                                );
-                                match rib.kind {
-                                    LifetimeRibKind::Item => break,
-                                    LifetimeRibKind::AnonymousCreateParameter {
-                                        binder, ..
-                                    } => {
-                                        if let Some(earlier_fresh) =
-                                            this.r.extra_lifetime_params_map.get(&binder)
-                                        {
-                                            extra_lifetime_params.extend(earlier_fresh);
-                                        }
-                                    }
-                                    _ => {}
-                                }
-                            }
-                            this.r
-                                .extra_lifetime_params_map
-                                .insert(async_node_id, extra_lifetime_params);
-                        }
+                        this.record_lifetime_params_for_async(fn_id, async_node_id);
 
                         if let Some(body) = body {
                             // Ignore errors in function bodies if this is rustdoc
@@ -3925,6 +3897,36 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             Some((ident.name, ns)),
         )
     }
+
+    /// Construct the list of in-scope lifetime parameters for async lowering.
+    /// We include all lifetime parameters, either named or "Fresh".
+    /// The order of those parameters does not matter, as long as it is
+    /// deterministic.
+    fn record_lifetime_params_for_async(
+        &mut self,
+        fn_id: NodeId,
+        async_node_id: Option<(NodeId, Span)>,
+    ) {
+        if let Some((async_node_id, _)) = async_node_id {
+            let mut extra_lifetime_params =
+                self.r.extra_lifetime_params_map.get(&fn_id).cloned().unwrap_or_default();
+            for rib in self.lifetime_ribs.iter().rev() {
+                extra_lifetime_params.extend(
+                    rib.bindings.iter().map(|(&ident, &(node_id, res))| (ident, node_id, res)),
+                );
+                match rib.kind {
+                    LifetimeRibKind::Item => break,
+                    LifetimeRibKind::AnonymousCreateParameter { binder, .. } => {
+                        if let Some(earlier_fresh) = self.r.extra_lifetime_params_map.get(&binder) {
+                            extra_lifetime_params.extend(earlier_fresh);
+                        }
+                    }
+                    _ => {}
+                }
+            }
+            self.r.extra_lifetime_params_map.insert(async_node_id, extra_lifetime_params);
+        }
+    }
 }
 
 struct LifetimeCountVisitor<'a, 'b> {
diff --git a/src/test/ui/async-await/issue-102138.rs b/src/test/ui/async-await/issue-102138.rs
deleted file mode 100644
index 91a14523c63..00000000000
--- a/src/test/ui/async-await/issue-102138.rs
+++ /dev/null
@@ -1,46 +0,0 @@
-// check-pass
-// edition:2021
-
-#![feature(return_position_impl_trait_in_trait)]
-#![allow(incomplete_features)]
-
-use std::future::Future;
-
-async fn yield_now() {}
-
-trait AsyncIterator {
-    type Item;
-    async fn next(&mut self) -> Option<Self::Item>;
-}
-
-struct YieldingRange {
-    counter: u32,
-    stop: u32,
-}
-
-impl AsyncIterator for YieldingRange {
-    type Item = u32;
-
-    async fn next(&mut self) -> Option<Self::Item> {
-        if self.counter == self.stop {
-            None
-        } else {
-            let c = self.counter;
-            self.counter += 1;
-            yield_now().await;
-            Some(c)
-        }
-    }
-}
-
-async fn async_main() {
-    let mut x = YieldingRange { counter: 0, stop: 10 };
-
-    while let Some(v) = x.next().await {
-        println!("Hi: {v}");
-    }
-}
-
-fn main() {
-    let _ = async_main();
-}
diff --git a/src/test/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs b/src/test/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs
index 4ec4472cc9a..c377ecea94d 100644
--- a/src/test/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs
+++ b/src/test/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs
@@ -2,5 +2,5 @@ fn main() {}
 
 trait Foo {
     fn fn_with_type_named_same_as_local_in_param(b: b);
-    //~^ ERROR expected type, found local variable `b`
+    //~^ ERROR cannot find type `b` in this scope [E0412]
 }
diff --git a/src/test/ui/resolve/issue-69401-trait-fn-no-body-ty-local.stderr b/src/test/ui/resolve/issue-69401-trait-fn-no-body-ty-local.stderr
index c53028e9b2a..109409d2731 100644
--- a/src/test/ui/resolve/issue-69401-trait-fn-no-body-ty-local.stderr
+++ b/src/test/ui/resolve/issue-69401-trait-fn-no-body-ty-local.stderr
@@ -1,9 +1,9 @@
-error[E0573]: expected type, found local variable `b`
+error[E0412]: cannot find type `b` in this scope
   --> $DIR/issue-69401-trait-fn-no-body-ty-local.rs:4:53
    |
 LL |     fn fn_with_type_named_same_as_local_in_param(b: b);
-   |                                                     ^ not a type
+   |                                                     ^ not found in this scope
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0573`.
+For more information about this error, try `rustc --explain E0412`.