diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 0477c7b2ba9..f59f7d389cd 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -485,6 +485,18 @@ fn check_foreign_item_ascii_only(&self, ident: Ident) { /// 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 variadic_spans: Vec<_> = fk + .decl() + .inputs + .iter() + .filter(|arg| matches!(arg.ty.kind, TyKind::CVarArgs)) + .map(|arg| arg.span) + .collect(); + + if variadic_spans.is_empty() { + return; + } + match (fk.ctxt(), fk.header()) { (Some(FnCtxt::Foreign), _) => return, (Some(FnCtxt::Free), Some(header)) => match header.ext { @@ -499,11 +511,7 @@ fn check_c_variadic_type(&self, fk: FnKind<'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_spans }); } fn check_item_named(&self, ident: Ident, kind: &str) { diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index e74d94e4347..579f528e20f 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -271,7 +271,7 @@ pub struct ExternItemAscii { #[diag(ast_passes_bad_c_variadic)] pub struct BadCVariadic { #[primary_span] - pub span: Span, + pub span: Vec, } #[derive(Diagnostic)] diff --git a/tests/ui/c-variadic/issue-86053-1.stderr b/tests/ui/c-variadic/issue-86053-1.stderr index 5a02f4aa93a..69e19e1d4d2 100644 --- a/tests/ui/c-variadic/issue-86053-1.stderr +++ b/tests/ui/c-variadic/issue-86053-1.stderr @@ -50,13 +50,7 @@ error: only foreign or `unsafe extern "C"` functions may be C-variadic --> $DIR/issue-86053-1.rs:11:12 | 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 @@ -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`. diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs index 0b61e267da8..8e382314ca2 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs @@ -49,11 +49,9 @@ fn i_f2(...) {} //~| 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 } diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr index f1cbbb279c8..95e381f06fc 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr @@ -116,91 +116,79 @@ error: only foreign or `unsafe extern "C"` functions may be C-variadic --> $DIR/variadic-ffi-semantic-restrictions.rs:50:13 | 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