Skip to content

Commit f7cabc6

Browse files
committed
Continue parsing function after finding ... arg
When encountering a variadic argument in a function definition that doesn't accept it, if immediately after there's a closing paren, continue parsing as normal. Otherwise keep current behavior of emitting error and stopping.
1 parent d0f1f42 commit f7cabc6

File tree

3 files changed

+43
-5
lines changed

3 files changed

+43
-5
lines changed

src/libsyntax/parse/parser.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -4859,19 +4859,30 @@ impl<'a> Parser<'a> {
48594859
|p| {
48604860
if p.token == token::DotDotDot {
48614861
p.bump();
4862+
variadic = true;
48624863
if allow_variadic {
48634864
if p.token != token::CloseDelim(token::Paren) {
48644865
let span = p.span;
48654866
p.span_err(span,
48664867
"`...` must be last in argument list for variadic function");
48674868
}
4869+
Ok(None)
48684870
} else {
4869-
let span = p.span;
4870-
p.span_err(span,
4871-
"only foreign functions are allowed to be variadic");
4871+
let span = p.prev_span;
4872+
if p.token == token::CloseDelim(token::Paren) {
4873+
// continue parsing to present any further errors
4874+
p.struct_span_err(
4875+
span,
4876+
"only foreign functions are allowed to be variadic"
4877+
).emit();
4878+
Ok(Some(dummy_arg(span)))
4879+
} else {
4880+
// this function definition looks beyond recovery, stop parsing
4881+
p.span_err(span,
4882+
"only foreign functions are allowed to be variadic");
4883+
Ok(None)
4884+
}
48724885
}
4873-
variadic = true;
4874-
Ok(None)
48754886
} else {
48764887
match p.parse_arg_general(named_args) {
48774888
Ok(arg) => Ok(Some(arg)),
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
extern "C" fn foo(x: u8, ...);
12+
//~^ ERROR only foreign functions are allowed to be variadic
13+
//~| ERROR expected one of `->`, `where`, or `{`, found `;`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: only foreign functions are allowed to be variadic
2+
--> $DIR/invalid-variadic-function.rs:11:26
3+
|
4+
11 | extern "C" fn foo(x: u8, ...);
5+
| ^^^
6+
7+
error: expected one of `->`, `where`, or `{`, found `;`
8+
--> $DIR/invalid-variadic-function.rs:11:30
9+
|
10+
11 | extern "C" fn foo(x: u8, ...);
11+
| ^ expected one of `->`, `where`, or `{` here
12+
13+
error: aborting due to 2 previous errors
14+

0 commit comments

Comments
 (0)