Skip to content

Commit

Permalink
Merge #11863
Browse files Browse the repository at this point in the history
11863: fix: allow varargs in any param position r=jonas-schievink a=jonas-schievink

Fixes #3578 and aligns us with the Rust reference.

bors r+

Co-authored-by: Jonas Schievink <jonas.schievink@ferrous-systems.com>
  • Loading branch information
bors[bot] and Jonas Schievink committed Mar 31, 2022
2 parents 9b000b5 + 42ecf40 commit a1d684e
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 28 deletions.
45 changes: 19 additions & 26 deletions crates/parser/src/grammar/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,10 @@ fn list_(p: &mut Parser, flavor: Flavor) {
m.abandon(p);
break;
}
let param = param(p, m, flavor);
param(p, m, flavor);
if !p.at(ket) {
p.expect(T![,]);
}
if let Variadic(true) = param {
break;
}
}

if let Some(m) = param_marker {
Expand All @@ -90,27 +87,24 @@ fn list_(p: &mut Parser, flavor: Flavor) {

const PARAM_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST);

struct Variadic(bool);

fn param(p: &mut Parser, m: Marker, flavor: Flavor) -> Variadic {
let mut res = Variadic(false);
fn param(p: &mut Parser, m: Marker, flavor: Flavor) {
match flavor {
// test param_list_vararg
// extern "C" { fn printf(format: *const i8, ...) -> i32; }
Flavor::FnDef | Flavor::FnPointer if p.eat(T![...]) => res = Variadic(true),
// extern "C" { fn printf(format: *const i8, ..., _: u8) -> i32; }
Flavor::FnDef | Flavor::FnPointer if p.eat(T![...]) => {}

// test fn_def_param
// fn foo((x, y): (i32, i32)) {}
// fn foo(..., (x, y): (i32, i32)) {}
Flavor::FnDef => {
patterns::pattern(p);
if variadic_param(p) {
res = Variadic(true);
} else if p.at(T![:]) {
types::ascription(p);
} else {
// test_err missing_fn_param_type
// fn f(x y: i32, z, t: i32) {}
p.error("missing type for function parameter");
if !variadic_param(p) {
if p.at(T![:]) {
types::ascription(p);
} else {
// test_err missing_fn_param_type
// fn f(x y: i32, z, t: i32) {}
p.error("missing type for function parameter");
}
}
}
// test value_parameters_no_patterns
Expand All @@ -127,12 +121,12 @@ fn param(p: &mut Parser, m: Marker, flavor: Flavor) -> Variadic {
Flavor::FnPointer => {
if (p.at(IDENT) || p.at(UNDERSCORE)) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) {
patterns::pattern_single(p);
if variadic_param(p) {
res = Variadic(true);
} else if p.at(T![:]) {
types::ascription(p);
} else {
p.error("missing type for function parameter");
if !variadic_param(p) {
if p.at(T![:]) {
types::ascription(p);
} else {
p.error("missing type for function parameter");
}
}
} else {
types::type_(p);
Expand All @@ -150,7 +144,6 @@ fn param(p: &mut Parser, m: Marker, flavor: Flavor) -> Variadic {
}
}
m.complete(p, PARAM);
res
}

fn variadic_param(p: &mut Parser) -> bool {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@ SOURCE_FILE
WHITESPACE " "
PARAM
DOT3 "..."
COMMA ","
WHITESPACE " "
PARAM
WILDCARD_PAT
UNDERSCORE "_"
COLON ":"
WHITESPACE " "
PATH_TYPE
PATH
PATH_SEGMENT
NAME_REF
IDENT "u8"
R_PAREN ")"
WHITESPACE " "
RET_TYPE
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
extern "C" { fn printf(format: *const i8, ...) -> i32; }
extern "C" { fn printf(format: *const i8, ..., _: u8) -> i32; }
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ SOURCE_FILE
IDENT "foo"
PARAM_LIST
L_PAREN "("
PARAM
DOT3 "..."
COMMA ","
WHITESPACE " "
PARAM
TUPLE_PAT
L_PAREN "("
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
fn foo((x, y): (i32, i32)) {}
fn foo(..., (x, y): (i32, i32)) {}

0 comments on commit a1d684e

Please sign in to comment.