about summary refs log tree commit diff
diff options
context:
space:
mode:
authorShoyu Vanilla <modulo641@gmail.com>2025-08-04 23:59:28 +0900
committerShoyu Vanilla <modulo641@gmail.com>2025-08-15 16:31:10 +0900
commit2218ff1940bc8baafcc1acf2c861d48499e20d06 (patch)
tree52c6dfd1cf390084ff6a5afba282d37cc8ee4a0f
parent3507a749b365aae4eefa96ab700a9315d3280ee7 (diff)
downloadrust-2218ff1940bc8baafcc1acf2c861d48499e20d06.tar.gz
rust-2218ff1940bc8baafcc1acf2c861d48499e20d06.zip
fix: Reject async assoc fns of const traits/impls in ast_passes
-rw-r--r--compiler/rustc_ast_passes/messages.ftl7
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs16
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs10
-rw-r--r--tests/crashes/117629.rs10
-rw-r--r--tests/ui/traits/const-traits/const-trait-async-assoc-fn.rs18
-rw-r--r--tests/ui/traits/const-traits/const-trait-async-assoc-fn.stderr18
6 files changed, 69 insertions, 10 deletions
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl
index 340a1a239c5..92ac04d1837 100644
--- a/compiler/rustc_ast_passes/messages.ftl
+++ b/compiler/rustc_ast_passes/messages.ftl
@@ -32,6 +32,13 @@ 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_or_trait_impl =
+    async functions are not allowed in `const` {$in_impl ->
+        [true] trait impls
+        *[false] 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 f62b8d1d576..de192aa1e5e 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -293,6 +293,21 @@ impl<'a> AstValidator<'a> {
         });
     }
 
+    fn check_async_fn_in_const_trait_or_impl(&self, sig: &FnSig, parent: &TraitOrTraitImpl) {
+        let Some(const_keyword) = parent.constness() else { return };
+
+        let Some(CoroutineKind::Async { span: async_keyword, .. }) = sig.header.coroutine_kind
+        else {
+            return;
+        };
+
+        self.dcx().emit_err(errors::AsyncFnInConstTraitOrTraitImpl {
+            async_keyword,
+            in_impl: matches!(parent, TraitOrTraitImpl::TraitImpl { .. }),
+            const_keyword,
+        });
+    }
+
     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);
@@ -1566,6 +1581,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_or_impl(sig, parent);
             }
         }
 
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 1cb2493afe8..5ecc0d21411 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -63,6 +63,16 @@ pub(crate) struct TraitFnConst {
 }
 
 #[derive(Diagnostic)]
+#[diag(ast_passes_async_fn_in_const_trait_or_trait_impl)]
+pub(crate) struct AsyncFnInConstTraitOrTraitImpl {
+    #[primary_span]
+    pub async_keyword: Span,
+    pub in_impl: bool,
+    #[label]
+    pub const_keyword: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(ast_passes_forbidden_bound)]
 pub(crate) struct ForbiddenBound {
     #[primary_span]
diff --git a/tests/crashes/117629.rs b/tests/crashes/117629.rs
deleted file mode 100644
index f63365395c6..00000000000
--- a/tests/crashes/117629.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ known-bug: #117629
-//@ edition:2021
-
-#![feature(const_trait_impl)]
-
-const trait Tr {
-    async fn ft1() {}
-}
-
-fn main() {}
diff --git a/tests/ui/traits/const-traits/const-trait-async-assoc-fn.rs b/tests/ui/traits/const-traits/const-trait-async-assoc-fn.rs
new file mode 100644
index 00000000000..00fdccc2ac8
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-trait-async-assoc-fn.rs
@@ -0,0 +1,18 @@
+//@ edition: 2021
+#![feature(const_trait_impl)]
+
+const trait Tr {
+    async fn ft1() {}
+//~^ ERROR async functions are not allowed in `const` traits
+}
+
+const trait Tr2 {
+    fn f() -> impl std::future::Future<Output = ()>;
+}
+
+impl const Tr2 for () {
+    async fn f() {}
+//~^ ERROR async functions are not allowed in `const` trait impls
+}
+
+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 00000000000..09ba0969dc9
--- /dev/null
+++ b/tests/ui/traits/const-traits/const-trait-async-assoc-fn.stderr
@@ -0,0 +1,18 @@
+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: async functions are not allowed in `const` trait impls
+  --> $DIR/const-trait-async-assoc-fn.rs:14:5
+   |
+LL | impl const Tr2 for () {
+   |      ----- associated functions of `const` cannot be declared `async`
+LL |     async fn f() {}
+   |     ^^^^^
+
+error: aborting due to 2 previous errors
+