Skip to content

Commit

Permalink
Fix bad-c-variadic error being emitted multiple times
Browse files Browse the repository at this point in the history
If a function incorrectly contains multiple `...` args, and is also not
foreign or `unsafe extern "C"`, only emit the latter error once.
  • Loading branch information
nicholasbishop committed Oct 29, 2023
1 parent ec2b311 commit 690b017
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 39 deletions.
16 changes: 11 additions & 5 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,16 @@ impl<'a> AstValidator<'a> {
/// Reject C-variadic type unless the function is foreign,
/// or free and `unsafe extern "C"` semantically.
fn check_c_variadic_type(&self, fk: FnKind<'a>) {
let Some(variadic_span) = fk
.decl()
.inputs
.iter()
.find(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
.map(|arg| arg.span)
else {
return;
};

match (fk.ctxt(), fk.header()) {
(Some(FnCtxt::Foreign), _) => return,
(Some(FnCtxt::Free), Some(header)) => match header.ext {
Expand All @@ -499,11 +509,7 @@ impl<'a> AstValidator<'a> {
_ => {}
};

for Param { ty, span, .. } in &fk.decl().inputs {
if let TyKind::CVarArgs = ty.kind {
self.err_handler().emit_err(errors::BadCVariadic { span: *span });
}
}
self.err_handler().emit_err(errors::BadCVariadic { span: variadic_span });
}

fn check_item_named(&self, ident: Ident, kind: &str) {
Expand Down
8 changes: 1 addition & 7 deletions tests/ui/c-variadic/issue-86053-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,6 @@ error: only foreign or `unsafe extern "C"` functions may be C-variadic
LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
--> $DIR/issue-86053-1.rs:11:36
|
LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
| ^^^

error[E0412]: cannot find type `F` in this scope
--> $DIR/issue-86053-1.rs:11:48
|
Expand All @@ -76,6 +70,6 @@ help: you might be missing a type parameter
LL | fn ordering4 < 'a , 'b, F > ( a : , self , self , self ,
| +++

error: aborting due to 11 previous errors
error: aborting due to 10 previous errors

For more information about this error, try `rustc --explain E0412`.
2 changes: 0 additions & 2 deletions tests/ui/parser/variadic-ffi-semantic-restrictions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,9 @@ impl X {
//~| ERROR C-variadic function must be declared with at least one named argument
fn i_f3(..., x: isize, ...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~| ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~| ERROR `...` must be the last argument of a C-variadic function
fn i_f4(..., x: isize, ...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~| ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~| ERROR `...` must be the last argument of a C-variadic function
}

Expand Down
38 changes: 13 additions & 25 deletions tests/ui/parser/variadic-ffi-semantic-restrictions.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -118,89 +118,77 @@ error: only foreign or `unsafe extern "C"` functions may be C-variadic
LL | fn i_f3(..., x: isize, ...) {}
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
--> $DIR/variadic-ffi-semantic-restrictions.rs:50:28
|
LL | fn i_f3(..., x: isize, ...) {}
| ^^^

error: `...` must be the last argument of a C-variadic function
--> $DIR/variadic-ffi-semantic-restrictions.rs:54:13
--> $DIR/variadic-ffi-semantic-restrictions.rs:53:13
|
LL | fn i_f4(..., x: isize, ...) {}
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
--> $DIR/variadic-ffi-semantic-restrictions.rs:54:13
--> $DIR/variadic-ffi-semantic-restrictions.rs:53:13
|
LL | fn i_f4(..., x: isize, ...) {}
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
--> $DIR/variadic-ffi-semantic-restrictions.rs:54:28
|
LL | fn i_f4(..., x: isize, ...) {}
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
--> $DIR/variadic-ffi-semantic-restrictions.rs:61:23
--> $DIR/variadic-ffi-semantic-restrictions.rs:59:23
|
LL | fn t_f1(x: isize, ...) {}
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
--> $DIR/variadic-ffi-semantic-restrictions.rs:63:23
--> $DIR/variadic-ffi-semantic-restrictions.rs:61:23
|
LL | fn t_f2(x: isize, ...);
| ^^^

error: C-variadic function must be declared with at least one named argument
--> $DIR/variadic-ffi-semantic-restrictions.rs:65:13
--> $DIR/variadic-ffi-semantic-restrictions.rs:63:13
|
LL | fn t_f3(...) {}
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
--> $DIR/variadic-ffi-semantic-restrictions.rs:65:13
--> $DIR/variadic-ffi-semantic-restrictions.rs:63:13
|
LL | fn t_f3(...) {}
| ^^^

error: C-variadic function must be declared with at least one named argument
--> $DIR/variadic-ffi-semantic-restrictions.rs:68:13
--> $DIR/variadic-ffi-semantic-restrictions.rs:66:13
|
LL | fn t_f4(...);
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
--> $DIR/variadic-ffi-semantic-restrictions.rs:68:13
--> $DIR/variadic-ffi-semantic-restrictions.rs:66:13
|
LL | fn t_f4(...);
| ^^^

error: `...` must be the last argument of a C-variadic function
--> $DIR/variadic-ffi-semantic-restrictions.rs:71:13
--> $DIR/variadic-ffi-semantic-restrictions.rs:69:13
|
LL | fn t_f5(..., x: isize) {}
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
--> $DIR/variadic-ffi-semantic-restrictions.rs:71:13
--> $DIR/variadic-ffi-semantic-restrictions.rs:69:13
|
LL | fn t_f5(..., x: isize) {}
| ^^^

error: `...` must be the last argument of a C-variadic function
--> $DIR/variadic-ffi-semantic-restrictions.rs:74:13
--> $DIR/variadic-ffi-semantic-restrictions.rs:72:13
|
LL | fn t_f6(..., x: isize);
| ^^^

error: only foreign or `unsafe extern "C"` functions may be C-variadic
--> $DIR/variadic-ffi-semantic-restrictions.rs:74:13
--> $DIR/variadic-ffi-semantic-restrictions.rs:72:13
|
LL | fn t_f6(..., x: isize);
| ^^^

error: aborting due to 34 previous errors
error: aborting due to 32 previous errors

0 comments on commit 690b017

Please sign in to comment.