From 730ead80479d98de5cc1b555c558b5b0176fded8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 24 Sep 2022 18:53:53 +0000 Subject: [PATCH 1/2] Only generate closure def id for async fns with body --- compiler/rustc_resolve/src/def_collector.rs | 10 +++++++--- src/test/ui/async-await/in-trait/issue-102219.rs | 10 ++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/async-await/in-trait/issue-102219.rs diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 3f88f44ff21a3..7e83f2a722107 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -1,6 +1,5 @@ use crate::{ImplTraitContext, Resolver}; use rustc_ast::visit::{self, FnKind}; -use rustc_ast::walk_list; use rustc_ast::*; use rustc_expand::expand::AstFragment; use rustc_hir::def_id::LocalDefId; @@ -148,8 +147,13 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { self.with_parent(return_impl_trait_id, |this| { this.visit_fn_ret_ty(&sig.decl.output) }); - let closure_def = self.create_def(closure_id, DefPathData::ClosureExpr, span); - self.with_parent(closure_def, |this| walk_list!(this, visit_block, body)); + // If this async fn has no body (i.e. it's an async fn signature in a trait) + // then the closure_def will never be used, and we should avoid generating a + // def-id for it. + if let Some(body) = body { + let closure_def = self.create_def(closure_id, DefPathData::ClosureExpr, span); + self.with_parent(closure_def, |this| this.visit_block(body)); + } return; } } diff --git a/src/test/ui/async-await/in-trait/issue-102219.rs b/src/test/ui/async-await/in-trait/issue-102219.rs new file mode 100644 index 0000000000000..9a35f6515cb1a --- /dev/null +++ b/src/test/ui/async-await/in-trait/issue-102219.rs @@ -0,0 +1,10 @@ +// compile-flags:--crate-type=lib +// edition:2021 +// check-pass + +#![feature(async_fn_in_trait)] +#![allow(incomplete_features)] + +trait T { + async fn foo(); +} From e99f6fee441dfa71d58b37a10366bf8c5c9d52ac Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 24 Sep 2022 19:22:01 +0000 Subject: [PATCH 2/2] Only lower async fn body if it actually has a body --- compiler/rustc_ast_lowering/src/item.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 1251702c1ff6b..d9b18d68e537f 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1055,9 +1055,9 @@ impl<'hir> LoweringContext<'_, 'hir> { asyncness: Async, body: Option<&Block>, ) -> hir::BodyId { - let closure_id = match asyncness { - Async::Yes { closure_id, .. } => closure_id, - Async::No => return self.lower_fn_body_block(span, decl, body), + let (closure_id, body) = match (asyncness, body) { + (Async::Yes { closure_id, .. }, Some(body)) => (closure_id, body), + _ => return self.lower_fn_body_block(span, decl, body), }; self.lower_body(|this| { @@ -1199,16 +1199,15 @@ impl<'hir> LoweringContext<'_, 'hir> { parameters.push(new_parameter); } - let body_span = body.map_or(span, |b| b.span); let async_expr = this.make_async_expr( CaptureBy::Value, closure_id, None, - body_span, + body.span, hir::AsyncGeneratorKind::Fn, |this| { // Create a block from the user's function body: - let user_body = this.lower_block_expr_opt(body_span, body); + let user_body = this.lower_block_expr(body); // Transform into `drop-temps { }`, an expression: let desugared_span = @@ -1240,7 +1239,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ( this.arena.alloc_from_iter(parameters), - this.expr(body_span, async_expr, AttrVec::new()), + this.expr(body.span, async_expr, AttrVec::new()), ) }) }