Skip to content

Commit 1656f6c

Browse files
committed
disallow c-variadic coroutines
1 parent 68baa87 commit 1656f6c

File tree

7 files changed

+60
-2
lines changed

7 files changed

+60
-2
lines changed

compiler/rustc_ast_passes/messages.ftl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ ast_passes_const_without_body =
8484
ast_passes_constraint_on_negative_bound =
8585
associated type constraints not allowed on negative bounds
8686
87+
ast_passes_coroutine_and_c_variadic = functions cannot be both `{$coroutine_kind}` and C-variadic
88+
.const = `{$coroutine_kind}` because of this
89+
.variadic = C-variadic because of this
90+
8791
ast_passes_equality_in_where = equality constraints are not yet supported in `where` clauses
8892
.label = not supported
8993
.suggestion = if `{$ident}` is an associated type you're trying to set, use the associated type binding syntax

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,15 @@ impl<'a> AstValidator<'a> {
685685
});
686686
}
687687

688+
if let Some(coroutine_kind) = sig.header.coroutine_kind {
689+
self.dcx().emit_err(errors::CoroutineAndCVariadic {
690+
spans: vec![coroutine_kind.span(), variadic_param.span],
691+
coroutine_kind: coroutine_kind.as_str(),
692+
coroutine_span: coroutine_kind.span(),
693+
variadic_span: variadic_param.span,
694+
});
695+
}
696+
688697
match fn_ctxt {
689698
FnCtxt::Foreign => return,
690699
FnCtxt::Free => match sig.header.ext {

compiler/rustc_ast_passes/src/errors.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,18 @@ pub(crate) struct ConstAndCVariadic {
659659
pub variadic_span: Span,
660660
}
661661

662+
#[derive(Diagnostic)]
663+
#[diag(ast_passes_coroutine_and_c_variadic)]
664+
pub(crate) struct CoroutineAndCVariadic {
665+
#[primary_span]
666+
pub spans: Vec<Span>,
667+
pub coroutine_kind: &'static str,
668+
#[label(ast_passes_const)]
669+
pub coroutine_span: Span,
670+
#[label(ast_passes_variadic)]
671+
pub variadic_span: Span,
672+
}
673+
662674
#[derive(Diagnostic)]
663675
#[diag(ast_passes_pattern_in_foreign, code = E0130)]
664676
// FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`)

tests/ui/c-variadic/not-async.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//@ edition: 2021
2+
#![feature(c_variadic)]
3+
#![crate_type = "lib"]
4+
5+
async unsafe extern "C" fn cannot_be_async(x: isize, ...) {}
6+
//~^ ERROR functions cannot be both `async` and C-variadic
7+
//~| ERROR hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error: functions cannot be both `async` and C-variadic
2+
--> $DIR/not-async.rs:5:1
3+
|
4+
LL | async unsafe extern "C" fn cannot_be_async(x: isize, ...) {}
5+
| ^^^^^ `async` because of this ^^^ C-variadic because of this
6+
7+
error[E0700]: hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds
8+
--> $DIR/not-async.rs:5:59
9+
|
10+
LL | async unsafe extern "C" fn cannot_be_async(x: isize, ...) {}
11+
| --------------------------------------------------------- ^^
12+
| |
13+
| opaque type defined here
14+
|
15+
= note: hidden type `{async fn body of cannot_be_async()}` captures lifetime `'_`
16+
17+
error: aborting due to 2 previous errors
18+
19+
For more information about this error, try `rustc --explain E0700`.

tests/ui/inference/note-and-explain-ReVar-124973.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#![feature(c_variadic)]
44

55
async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, ...) {}
6-
//~^ ERROR hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds
6+
//~^ ERROR functions cannot be both `async` and C-variadic
7+
//~| ERROR hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds
78

89
fn main() {}

tests/ui/inference/note-and-explain-ReVar-124973.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
error: functions cannot be both `async` and C-variadic
2+
--> $DIR/note-and-explain-ReVar-124973.rs:5:1
3+
|
4+
LL | async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, ...) {}
5+
| ^^^^^ `async` because of this ^^^ C-variadic because of this
6+
17
error[E0700]: hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds
28
--> $DIR/note-and-explain-ReVar-124973.rs:5:73
39
|
@@ -8,6 +14,6 @@ LL | async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, ...) {}
814
|
915
= note: hidden type `{async fn body of multiple_named_lifetimes<'a, 'b>()}` captures lifetime `'_`
1016

11-
error: aborting due to 1 previous error
17+
error: aborting due to 2 previous errors
1218

1319
For more information about this error, try `rustc --explain E0700`.

0 commit comments

Comments
 (0)