From c700d015b433024ab9123ad9a36f9af3a65d81f4 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Mon, 4 Aug 2025 23:59:28 +0900 Subject: [PATCH] fix: Reject async assoc fns of `#[const_trait]` in ast_passes --- compiler/rustc_ast_passes/messages.ftl | 4 ++++ compiler/rustc_ast_passes/src/ast_validation.rs | 15 +++++++++++++++ compiler/rustc_ast_passes/src/errors.rs | 9 +++++++++ .../const-traits/const-trait-async-assoc-fn.rs} | 5 ++--- .../const-trait-async-assoc-fn.stderr | 10 ++++++++++ 5 files changed, 40 insertions(+), 3 deletions(-) rename tests/{crashes/117629.rs => ui/traits/const-traits/const-trait-async-assoc-fn.rs} (52%) create mode 100644 tests/ui/traits/const-traits/const-trait-async-assoc-fn.stderr diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index af93d55c89826..0c2ca24f48a75 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -32,6 +32,10 @@ ast_passes_assoc_type_without_body = associated type in `impl` without body .suggestion = provide a definition for the type +ast_passes_async_fn_in_const_trait = + async functions are not allowed in `const` traits + .label = associated functions of `const` cannot be declared `async` + ast_passes_at_least_one_trait = at least one trait must be specified ast_passes_auto_generic = auto traits cannot have generic parameters diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 895a457ec1d56..e8400bee979d0 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -294,6 +294,20 @@ impl<'a> AstValidator<'a> { }); } + fn check_async_fn_in_const_trait(&self, sig: &FnSig, parent: &TraitOrTraitImpl) { + let TraitOrTraitImpl::Trait { constness: Const::Yes(const_trait), .. } = parent else { + return; + }; + + let Some(CoroutineKind::Async { span: async_keyword, .. }) = sig.header.coroutine_kind + else { + return; + }; + + self.dcx() + .emit_err(errors::AsyncFnInConstTrait { async_keyword, const_trait: *const_trait }); + } + fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) { self.check_decl_num_args(fn_decl); self.check_decl_cvariadic_pos(fn_decl); @@ -1586,6 +1600,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.visibility_not_permitted(&item.vis, errors::VisibilityNotPermittedNote::TraitImpl); if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind { self.check_trait_fn_not_const(sig.header.constness, parent); + self.check_async_fn_in_const_trait(sig, parent); } } diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index fd4b2528541e3..2eb065d3436b6 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -62,6 +62,15 @@ pub(crate) struct TraitFnConst { pub make_trait_const_sugg: Option, } +#[derive(Diagnostic)] +#[diag(ast_passes_async_fn_in_const_trait)] +pub(crate) struct AsyncFnInConstTrait { + #[primary_span] + pub async_keyword: Span, + #[label] + pub const_trait: Span, +} + #[derive(Diagnostic)] #[diag(ast_passes_forbidden_bound)] pub(crate) struct ForbiddenBound { diff --git a/tests/crashes/117629.rs b/tests/ui/traits/const-traits/const-trait-async-assoc-fn.rs similarity index 52% rename from tests/crashes/117629.rs rename to tests/ui/traits/const-traits/const-trait-async-assoc-fn.rs index f63365395c6b4..ccd5b1ae8c01f 100644 --- a/tests/crashes/117629.rs +++ b/tests/ui/traits/const-traits/const-trait-async-assoc-fn.rs @@ -1,10 +1,9 @@ -//@ known-bug: #117629 -//@ edition:2021 - +//@ edition: 2021 #![feature(const_trait_impl)] const trait Tr { async fn ft1() {} +//~^ ERROR async functions are not allowed in `const` traits } fn main() {} diff --git a/tests/ui/traits/const-traits/const-trait-async-assoc-fn.stderr b/tests/ui/traits/const-traits/const-trait-async-assoc-fn.stderr new file mode 100644 index 0000000000000..48f0ff92a9e85 --- /dev/null +++ b/tests/ui/traits/const-traits/const-trait-async-assoc-fn.stderr @@ -0,0 +1,10 @@ +error: async functions are not allowed in `const` traits + --> $DIR/const-trait-async-assoc-fn.rs:5:5 + | +LL | const trait Tr { + | ----- associated functions of `const` cannot be declared `async` +LL | async fn ft1() {} + | ^^^^^ + +error: aborting due to 1 previous error +