diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 0b06af22365..190fae95652 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2450,6 +2450,14 @@ pub fn is_gen(self) -> bool { matches!(self, CoroutineKind::Gen { .. }) } + pub fn closure_id(self) -> NodeId { + match self { + CoroutineKind::Async { closure_id, .. } + | CoroutineKind::Gen { closure_id, .. } + | CoroutineKind::AsyncGen { closure_id, .. } => closure_id, + } + } + /// In this case this is an `async` or `gen` return, the `NodeId` for the generated `impl Trait` /// item. pub fn return_id(self) -> (NodeId, Span) { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 9d1f2684c39..a4effb99e71 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1035,10 +1035,7 @@ fn lower_maybe_coroutine_body( let (Some(coroutine_kind), Some(body)) = (coroutine_kind, body) else { return self.lower_fn_body_block(span, decl, body); }; - // FIXME(gen_blocks): Introduce `closure_id` method and remove ALL destructuring. - let (CoroutineKind::Async { closure_id, .. } - | CoroutineKind::Gen { closure_id, .. } - | CoroutineKind::AsyncGen { closure_id, .. }) = coroutine_kind; + let closure_id = coroutine_kind.closure_id(); self.lower_body(|this| { let mut parameters: Vec> = Vec::new(); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 753650f7324..0c71165deed 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -177,7 +177,8 @@ fn new(tcx: TyCtxt<'hir>, resolver: &'a mut ResolverAstLowering) -> Self { } else { [sym::gen_future].into() }, - // FIXME(gen_blocks): how does `closure_track_caller` + // FIXME(gen_blocks): how does `closure_track_caller`/`async_fn_track_caller` + // interact with `gen`/`async gen` blocks allow_async_iterator: [sym::gen_future, sym::async_iterator].into(), generics_def_id_map: Default::default(), host_param_id: None, diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 0644c4cd6be..1f9bc09f5f7 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1271,11 +1271,11 @@ fn visit_fn(&mut self, fk: FnKind<'a>, span: Span, id: NodeId) { // Functions cannot both be `const async` or `const gen` if let Some(&FnHeader { constness: Const::Yes(cspan), - coroutine_kind: Some(coro_kind), + coroutine_kind: Some(coroutine_kind), .. }) = fk.header() { - let aspan = match coro_kind { + let aspan = match coroutine_kind { CoroutineKind::Async { span: aspan, .. } | CoroutineKind::Gen { span: aspan, .. } | CoroutineKind::AsyncGen { span: aspan, .. } => aspan, diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 794be25955d..e5b274304e7 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -541,8 +541,8 @@ fn check_test_signature( return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "unsafe" })); } - if let Some(coro_kind) = f.sig.header.coroutine_kind { - match coro_kind { + if let Some(coroutine_kind) = f.sig.header.coroutine_kind { + match coroutine_kind { ast::CoroutineKind::Async { span, .. } => { return Err(sd.emit_err(errors::TestBadFn { span: i.span, diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 80c6feaa269..4c7f9eeff8c 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -162,11 +162,8 @@ fn visit_fn(&mut self, fk: ast_visit::FnKind<'a>, span: Span, id: ast::NodeId) { // Explicitly check for lints associated with 'closure_id', since // it does not have a corresponding AST node if let ast_visit::FnKind::Fn(_, _, sig, _, _, _) = fk { - if let Some(coro_kind) = sig.header.coroutine_kind { - let (ast::CoroutineKind::Async { closure_id, .. } - | ast::CoroutineKind::Gen { closure_id, .. } - | ast::CoroutineKind::AsyncGen { closure_id, .. }) = coro_kind; - self.check_id(closure_id); + if let Some(coroutine_kind) = sig.header.coroutine_kind { + self.check_id(coroutine_kind.closure_id()); } } } @@ -226,12 +223,10 @@ fn visit_expr_post(&mut self, e: &'a ast::Expr) { // it does not have a corresponding AST node match e.kind { ast::ExprKind::Closure(box ast::Closure { - coroutine_kind: Some(coro_kind), .. + coroutine_kind: Some(coroutine_kind), + .. }) => { - let (ast::CoroutineKind::Async { closure_id, .. } - | ast::CoroutineKind::Gen { closure_id, .. } - | ast::CoroutineKind::AsyncGen { closure_id, .. }) = coro_kind; - self.check_id(closure_id); + self.check_id(coroutine_kind.closure_id()); } _ => {} } diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 186dd28b142..02553d50071 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -157,11 +157,7 @@ fn visit_item(&mut self, i: &'a Item) { fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) { if let FnKind::Fn(_, _, sig, _, generics, body) = fn_kind { match sig.header.coroutine_kind { - Some( - CoroutineKind::Async { closure_id, .. } - | CoroutineKind::Gen { closure_id, .. } - | CoroutineKind::AsyncGen { closure_id, .. }, - ) => { + Some(coroutine_kind) => { self.visit_generics(generics); // For async functions, we need to create their inner defs inside of a @@ -176,8 +172,12 @@ fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) { // 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, kw::Empty, DefKind::Closure, span); + let closure_def = self.create_def( + coroutine_kind.closure_id(), + kw::Empty, + DefKind::Closure, + span, + ); self.with_parent(closure_def, |this| this.visit_block(body)); } return; @@ -289,11 +289,12 @@ fn visit_expr(&mut self, expr: &'a Expr) { // we must create two defs. let closure_def = self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span); match closure.coroutine_kind { - Some( - CoroutineKind::Async { closure_id, .. } - | CoroutineKind::Gen { closure_id, .. } - | CoroutineKind::AsyncGen { closure_id, .. }, - ) => self.create_def(closure_id, kw::Empty, DefKind::Closure, expr.span), + Some(coroutine_kind) => self.create_def( + coroutine_kind.closure_id(), + kw::Empty, + DefKind::Closure, + expr.span, + ), None => closure_def, } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 7bf37cf7980..95ffd07e397 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -3144,10 +3144,9 @@ fn note_obligation_cause_code( let what = match self.tcx.coroutine_kind(coroutine_def_id) { None | Some(hir::CoroutineKind::Coroutine) - | Some(hir::CoroutineKind::Gen(_)) - // FIXME(gen_blocks): This could be yield or await... - | Some(hir::CoroutineKind::AsyncGen(_)) => "yield", + | Some(hir::CoroutineKind::Gen(_)) => "yield", Some(hir::CoroutineKind::Async(..)) => "await", + Some(hir::CoroutineKind::AsyncGen(_)) => "yield`/`await", }; err.note(format!( "all values live across `{what}` must have a statically known size"