Skip to content

Commit 8508e65

Browse files
Fix bad-c-variadic error being emitted multiple times
If a function incorrectly contains multiple `...` args, and is also not foreign or `unsafe extern "C"`, only emit the latter error once.
1 parent ec2b311 commit 8508e65

File tree

5 files changed

+31
-43
lines changed

5 files changed

+31
-43
lines changed

compiler/rustc_ast_passes/src/ast_validation.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,18 @@ impl<'a> AstValidator<'a> {
485485
/// Reject C-variadic type unless the function is foreign,
486486
/// or free and `unsafe extern "C"` semantically.
487487
fn check_c_variadic_type(&self, fk: FnKind<'a>) {
488+
let variadic_spans: Vec<_> = fk
489+
.decl()
490+
.inputs
491+
.iter()
492+
.filter(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
493+
.map(|arg| arg.span)
494+
.collect();
495+
496+
if variadic_spans.is_empty() {
497+
return;
498+
}
499+
488500
match (fk.ctxt(), fk.header()) {
489501
(Some(FnCtxt::Foreign), _) => return,
490502
(Some(FnCtxt::Free), Some(header)) => match header.ext {
@@ -499,11 +511,7 @@ impl<'a> AstValidator<'a> {
499511
_ => {}
500512
};
501513

502-
for Param { ty, span, .. } in &fk.decl().inputs {
503-
if let TyKind::CVarArgs = ty.kind {
504-
self.err_handler().emit_err(errors::BadCVariadic { span: *span });
505-
}
506-
}
514+
self.err_handler().emit_err(errors::BadCVariadic { span: variadic_spans });
507515
}
508516

509517
fn check_item_named(&self, ident: Ident, kind: &str) {

compiler/rustc_ast_passes/src/errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ pub struct ExternItemAscii {
271271
#[diag(ast_passes_bad_c_variadic)]
272272
pub struct BadCVariadic {
273273
#[primary_span]
274-
pub span: Span,
274+
pub span: Vec<Span>,
275275
}
276276

277277
#[derive(Diagnostic)]

tests/ui/c-variadic/issue-86053-1.stderr

+2-8
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,7 @@ error: only foreign or `unsafe extern "C"` functions may be C-variadic
5050
--> $DIR/issue-86053-1.rs:11:12
5151
|
5252
LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
53-
| ^^^
54-
55-
error: only foreign or `unsafe extern "C"` functions may be C-variadic
56-
--> $DIR/issue-86053-1.rs:11:36
57-
|
58-
LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
59-
| ^^^
53+
| ^^^ ^^^
6054

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

79-
error: aborting due to 11 previous errors
73+
error: aborting due to 10 previous errors
8074

8175
For more information about this error, try `rustc --explain E0412`.

tests/ui/parser/variadic-ffi-semantic-restrictions.rs

-2
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,9 @@ impl X {
4949
//~| ERROR C-variadic function must be declared with at least one named argument
5050
fn i_f3(..., x: isize, ...) {}
5151
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
52-
//~| ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
5352
//~| ERROR `...` must be the last argument of a C-variadic function
5453
fn i_f4(..., x: isize, ...) {}
5554
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
56-
//~| ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
5755
//~| ERROR `...` must be the last argument of a C-variadic function
5856
}
5957

tests/ui/parser/variadic-ffi-semantic-restrictions.stderr

+15-27
Original file line numberDiff line numberDiff line change
@@ -116,91 +116,79 @@ error: only foreign or `unsafe extern "C"` functions may be C-variadic
116116
--> $DIR/variadic-ffi-semantic-restrictions.rs:50:13
117117
|
118118
LL | fn i_f3(..., x: isize, ...) {}
119-
| ^^^
120-
121-
error: only foreign or `unsafe extern "C"` functions may be C-variadic
122-
--> $DIR/variadic-ffi-semantic-restrictions.rs:50:28
123-
|
124-
LL | fn i_f3(..., x: isize, ...) {}
125-
| ^^^
119+
| ^^^ ^^^
126120

127121
error: `...` must be the last argument of a C-variadic function
128-
--> $DIR/variadic-ffi-semantic-restrictions.rs:54:13
129-
|
130-
LL | fn i_f4(..., x: isize, ...) {}
131-
| ^^^
132-
133-
error: only foreign or `unsafe extern "C"` functions may be C-variadic
134-
--> $DIR/variadic-ffi-semantic-restrictions.rs:54:13
122+
--> $DIR/variadic-ffi-semantic-restrictions.rs:53:13
135123
|
136124
LL | fn i_f4(..., x: isize, ...) {}
137125
| ^^^
138126

139127
error: only foreign or `unsafe extern "C"` functions may be C-variadic
140-
--> $DIR/variadic-ffi-semantic-restrictions.rs:54:28
128+
--> $DIR/variadic-ffi-semantic-restrictions.rs:53:13
141129
|
142130
LL | fn i_f4(..., x: isize, ...) {}
143-
| ^^^
131+
| ^^^ ^^^
144132

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

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

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

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

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

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

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

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

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

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

205-
error: aborting due to 34 previous errors
193+
error: aborting due to 32 previous errors
206194

0 commit comments

Comments
 (0)