From c108451faf1fe034a09c02e8d5b217beafeddea6 Mon Sep 17 00:00:00 2001 From: lapla Date: Thu, 20 Nov 2025 21:25:54 +0900 Subject: [PATCH] Reject `async fn` in `const impl` during AST validation --- compiler/rustc_ast_passes/messages.ftl | 7 ++++--- compiler/rustc_ast_passes/src/ast_validation.rs | 11 +++++++++-- compiler/rustc_ast_passes/src/errors.rs | 2 +- .../const-traits/ice-149083-async-in-const-impl.rs | 9 +++++++++ .../ice-149083-async-in-const-impl.stderr | 10 ++++++++++ 5 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 tests/ui/traits/const-traits/ice-149083-async-in-const-impl.rs create mode 100644 tests/ui/traits/const-traits/ice-149083-async-in-const-impl.stderr diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index 3858bc80d4318..9bdbcf6ab9071 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -37,9 +37,10 @@ ast_passes_assoc_type_without_body = .suggestion = provide a definition for the type ast_passes_async_fn_in_const_trait_or_trait_impl = - async functions are not allowed in `const` {$in_impl -> - [true] trait impls - *[false] traits + async functions are not allowed in `const` {$context -> + [trait_impl] trait impls + [impl] impls + *[trait] traits } .label = associated functions of `const` cannot be declared `async` diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 425ba407fd61e..163dbc3350ba2 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -312,9 +312,15 @@ impl<'a> AstValidator<'a> { return; }; + let context = match parent { + TraitOrImpl::Trait { .. } => "trait", + TraitOrImpl::TraitImpl { .. } => "trait_impl", + TraitOrImpl::Impl { .. } => "impl", + }; + self.dcx().emit_err(errors::AsyncFnInConstTraitOrTraitImpl { async_keyword, - in_impl: matches!(parent, TraitOrImpl::TraitImpl { .. }), + context, const_keyword, }); } @@ -1714,9 +1720,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_async_fn_in_const_trait_or_impl(sig, parent); } } - Some(TraitOrImpl::Impl { constness }) => { + Some(parent @ TraitOrImpl::Impl { constness }) => { if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind { self.check_impl_fn_not_const(sig.header.constness, *constness); + self.check_async_fn_in_const_trait_or_impl(sig, parent); } } None => {} diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 48fd6a7cdd5d0..02e6ecfbaee74 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -76,7 +76,7 @@ pub(crate) struct TraitFnConst { pub(crate) struct AsyncFnInConstTraitOrTraitImpl { #[primary_span] pub async_keyword: Span, - pub in_impl: bool, + pub context: &'static str, #[label] pub const_keyword: Span, } diff --git a/tests/ui/traits/const-traits/ice-149083-async-in-const-impl.rs b/tests/ui/traits/const-traits/ice-149083-async-in-const-impl.rs new file mode 100644 index 0000000000000..0880ae509111a --- /dev/null +++ b/tests/ui/traits/const-traits/ice-149083-async-in-const-impl.rs @@ -0,0 +1,9 @@ +//@ edition:2024 + +#![feature(const_trait_impl)] +struct Foo; +const impl Foo { + async fn e() {} + //~^ ERROR async functions are not allowed in `const` impls +} +fn main() {} diff --git a/tests/ui/traits/const-traits/ice-149083-async-in-const-impl.stderr b/tests/ui/traits/const-traits/ice-149083-async-in-const-impl.stderr new file mode 100644 index 0000000000000..447222ea4abbd --- /dev/null +++ b/tests/ui/traits/const-traits/ice-149083-async-in-const-impl.stderr @@ -0,0 +1,10 @@ +error: async functions are not allowed in `const` impls + --> $DIR/ice-149083-async-in-const-impl.rs:6:5 + | +LL | const impl Foo { + | ----- associated functions of `const` cannot be declared `async` +LL | async fn e() {} + | ^^^^^ + +error: aborting due to 1 previous error +