Rollup merge of #144907 - ShoyuVanilla:no-const-async, r=fmease

fix: Reject async assoc fns of const traits/impls in ast_passes

Fixes rust-lang/rust#117629
This commit is contained in:
Jacob Pratt
2025-08-15 18:13:28 -04:00
committed by GitHub
6 changed files with 69 additions and 10 deletions

View File

@@ -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

View File

@@ -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);
@@ -1578,6 +1593,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);
}
}

View File

@@ -62,6 +62,16 @@ pub(crate) struct TraitFnConst {
pub make_trait_const_sugg: Option<Span>,
}
#[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 {

View File

@@ -1,10 +0,0 @@
//@ known-bug: #117629
//@ edition:2021
#![feature(const_trait_impl)]
const trait Tr {
async fn ft1() {}
}
fn main() {}

View File

@@ -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() {}

View File

@@ -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