Skip to content

Commit 333fd0b

Browse files
committed
fix: Reject async assoc fns of const traits/impls in ast_passes
1 parent 3507a74 commit 333fd0b

File tree

6 files changed

+74
-10
lines changed

6 files changed

+74
-10
lines changed

compiler/rustc_ast_passes/messages.ftl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ ast_passes_assoc_type_without_body =
3232
associated type in `impl` without body
3333
.suggestion = provide a definition for the type
3434
35+
ast_passes_async_fn_in_const_trait_or_trait_impl =
36+
async functions are not allowed in `const` {
37+
$in_impl ->
38+
[true] trait impls
39+
*[false] traits
40+
}
41+
.label = associated functions of `const` cannot be declared `async`
42+
3543
ast_passes_at_least_one_trait = at least one trait must be specified
3644
3745
ast_passes_auto_generic = auto traits cannot have generic parameters

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,25 @@ impl<'a> AstValidator<'a> {
293293
});
294294
}
295295

296+
fn check_async_fn_in_const_trait(&self, sig: &FnSig, parent: &TraitOrTraitImpl) {
297+
let (TraitOrTraitImpl::Trait { constness: Const::Yes(const_keyword), .. }
298+
| TraitOrTraitImpl::TraitImpl { constness: Const::Yes(const_keyword), .. }) = parent
299+
else {
300+
return;
301+
};
302+
303+
let Some(CoroutineKind::Async { span: async_keyword, .. }) = sig.header.coroutine_kind
304+
else {
305+
return;
306+
};
307+
308+
self.dcx().emit_err(errors::AsyncFnInConstTraitOrTraitImpl {
309+
async_keyword,
310+
in_impl: matches!(parent, TraitOrTraitImpl::TraitImpl { .. }),
311+
const_keyword: *const_keyword,
312+
});
313+
}
314+
296315
fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
297316
self.check_decl_num_args(fn_decl);
298317
self.check_decl_cvariadic_pos(fn_decl);
@@ -1566,6 +1585,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
15661585
self.visibility_not_permitted(&item.vis, errors::VisibilityNotPermittedNote::TraitImpl);
15671586
if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {
15681587
self.check_trait_fn_not_const(sig.header.constness, parent);
1588+
self.check_async_fn_in_const_trait(sig, parent);
15691589
}
15701590
}
15711591

compiler/rustc_ast_passes/src/errors.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ pub(crate) struct TraitFnConst {
6262
pub make_trait_const_sugg: Option<Span>,
6363
}
6464

65+
#[derive(Diagnostic)]
66+
#[diag(ast_passes_async_fn_in_const_trait_or_trait_impl)]
67+
pub(crate) struct AsyncFnInConstTraitOrTraitImpl {
68+
#[primary_span]
69+
pub async_keyword: Span,
70+
pub in_impl: bool,
71+
#[label]
72+
pub const_keyword: Span,
73+
}
74+
6575
#[derive(Diagnostic)]
6676
#[diag(ast_passes_forbidden_bound)]
6777
pub(crate) struct ForbiddenBound {

tests/crashes/117629.rs

Lines changed: 0 additions & 10 deletions
This file was deleted.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@ edition: 2021
2+
#![feature(const_trait_impl)]
3+
4+
const trait Tr {
5+
async fn ft1() {}
6+
//~^ ERROR async functions are not allowed in `const` traits
7+
}
8+
9+
const trait Tr2 {
10+
fn f() -> impl std::future::Future<Output = ()>;
11+
}
12+
13+
impl const Tr2 for () {
14+
async fn f() {}
15+
//~^ ERROR async functions are not allowed in `const` trait impls
16+
}
17+
18+
fn main() {}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error: async functions are not allowed in `const` traits
2+
--> $DIR/const-trait-async-assoc-fn.rs:5:5
3+
|
4+
LL | const trait Tr {
5+
| ----- associated functions of `const` cannot be declared `async`
6+
LL | async fn ft1() {}
7+
| ^^^^^
8+
9+
error: async functions are not allowed in `const` trait impls
10+
--> $DIR/const-trait-async-assoc-fn.rs:14:5
11+
|
12+
LL | impl const Tr2 for () {
13+
| ----- associated functions of `const` cannot be declared `async`
14+
LL | async fn f() {}
15+
| ^^^^^
16+
17+
error: aborting due to 2 previous errors
18+

0 commit comments

Comments
 (0)