Skip to content

Commit 74d4fbc

Browse files
committed
De-fatalize ... parsing.
Also fix error the code description.
1 parent e52f902 commit 74d4fbc

File tree

4 files changed

+53
-12
lines changed

4 files changed

+53
-12
lines changed
+11-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1-
C-variadic has been used on a non-foreign function.
1+
The C-variadic type `...` has been nested inside another type.
22

33
Erroneous code example:
44

55
```compile_fail,E0743
6-
fn foo2(x: u8, ...) {} // error!
6+
#![feature(c_variadic)]
7+
8+
fn foo2(x: u8, y: &...) {} // error!
79
```
810

9-
Only foreign functions can use C-variadic (`...`). It is used to give an
10-
undefined number of parameters to a given function (like `printf` in C). The
11-
equivalent in Rust would be to use macros directly.
11+
Only foreign functions can use the C-variadic type (`...`).
12+
In such functions, `...` may only occur non-nested.
13+
That is, `y: &'a ...` is not allowed.
14+
15+
A C-variadic type is used to give an undefined number
16+
of parameters to a given function (like `printf` in C).
17+
The equivalent in Rust would be to use macros directly.

src/librustc_parse/parser/ty.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use syntax::ast::{self, Ty, TyKind, MutTy, BareFnTy, FunctionRetTy, GenericParam
1010
use syntax::ast::{TraitBoundModifier, TraitObjectSyntax, GenericBound, GenericBounds, PolyTraitRef};
1111
use syntax::ast::{Mutability, AnonConst, Mac};
1212
use syntax::token::{self, Token};
13-
use syntax::struct_span_fatal;
13+
use syntax::struct_span_err;
1414
use syntax_pos::source_map::Span;
1515
use syntax_pos::symbol::kw;
1616

@@ -209,19 +209,21 @@ impl<'a> Parser<'a> {
209209
TyKind::Path(None, path)
210210
}
211211
}
212-
} else if self.check(&token::DotDotDot) {
212+
} else if self.eat(&token::DotDotDot) {
213213
if allow_c_variadic {
214-
self.eat(&token::DotDotDot);
215214
TyKind::CVarArgs
216215
} else {
217216
// FIXME(Centril): Should we just allow `...` syntactically
218217
// anywhere in a type and use semantic restrictions instead?
219-
return Err(struct_span_fatal!(
218+
struct_span_err!(
220219
self.sess.span_diagnostic,
221-
self.token.span,
220+
lo.to(self.prev_span),
222221
E0743,
223-
"only foreign functions are allowed to be C-variadic",
224-
));
222+
"C-variadic type `...` may not be nested inside another type",
223+
)
224+
.emit();
225+
226+
TyKind::Err
225227
}
226228
} else {
227229
let msg = format!("expected type, found {}", self.this_token_descr());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
fn f1<'a>(x: u8, y: &'a ...) {}
2+
//~^ ERROR C-variadic type `...` may not be nested inside another type
3+
4+
fn f2<'a>(x: u8, y: Vec<&'a ...>) {}
5+
//~^ ERROR C-variadic type `...` may not be nested inside another type
6+
7+
fn main() {
8+
let _recovery_witness: () = 0; //~ ERROR mismatched types
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0743]: C-variadic type `...` may not be nested inside another type
2+
--> $DIR/variadic-ffi-nested-syntactic-fail.rs:1:25
3+
|
4+
LL | fn f1<'a>(x: u8, y: &'a ...) {}
5+
| ^^^
6+
7+
error[E0743]: C-variadic type `...` may not be nested inside another type
8+
--> $DIR/variadic-ffi-nested-syntactic-fail.rs:4:29
9+
|
10+
LL | fn f2<'a>(x: u8, y: Vec<&'a ...>) {}
11+
| ^^^
12+
13+
error[E0308]: mismatched types
14+
--> $DIR/variadic-ffi-nested-syntactic-fail.rs:8:33
15+
|
16+
LL | let _recovery_witness: () = 0;
17+
| -- ^ expected `()`, found integer
18+
| |
19+
| expected due to this
20+
21+
error: aborting due to 3 previous errors
22+
23+
Some errors have detailed explanations: E0308, E0743.
24+
For more information about an error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)