mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 12:33:33 +00:00
Remove parser restriction on varargs positioning
This commit is contained in:
parent
9b000b544b
commit
42ecf406e8
5 changed files with 37 additions and 28 deletions
|
@ -71,13 +71,10 @@ fn list_(p: &mut Parser, flavor: Flavor) {
|
||||||
m.abandon(p);
|
m.abandon(p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let param = param(p, m, flavor);
|
param(p, m, flavor);
|
||||||
if !p.at(ket) {
|
if !p.at(ket) {
|
||||||
p.expect(T![,]);
|
p.expect(T![,]);
|
||||||
}
|
}
|
||||||
if let Variadic(true) = param {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(m) = param_marker {
|
if let Some(m) = param_marker {
|
||||||
|
@ -90,27 +87,24 @@ fn list_(p: &mut Parser, flavor: Flavor) {
|
||||||
|
|
||||||
const PARAM_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST);
|
const PARAM_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST);
|
||||||
|
|
||||||
struct Variadic(bool);
|
fn param(p: &mut Parser, m: Marker, flavor: Flavor) {
|
||||||
|
|
||||||
fn param(p: &mut Parser, m: Marker, flavor: Flavor) -> Variadic {
|
|
||||||
let mut res = Variadic(false);
|
|
||||||
match flavor {
|
match flavor {
|
||||||
// test param_list_vararg
|
// test param_list_vararg
|
||||||
// extern "C" { fn printf(format: *const i8, ...) -> i32; }
|
// extern "C" { fn printf(format: *const i8, ..., _: u8) -> i32; }
|
||||||
Flavor::FnDef | Flavor::FnPointer if p.eat(T![...]) => res = Variadic(true),
|
Flavor::FnDef | Flavor::FnPointer if p.eat(T![...]) => {}
|
||||||
|
|
||||||
// test fn_def_param
|
// test fn_def_param
|
||||||
// fn foo((x, y): (i32, i32)) {}
|
// fn foo(..., (x, y): (i32, i32)) {}
|
||||||
Flavor::FnDef => {
|
Flavor::FnDef => {
|
||||||
patterns::pattern(p);
|
patterns::pattern(p);
|
||||||
if variadic_param(p) {
|
if !variadic_param(p) {
|
||||||
res = Variadic(true);
|
if p.at(T![:]) {
|
||||||
} else if p.at(T![:]) {
|
types::ascription(p);
|
||||||
types::ascription(p);
|
} else {
|
||||||
} else {
|
// test_err missing_fn_param_type
|
||||||
// test_err missing_fn_param_type
|
// fn f(x y: i32, z, t: i32) {}
|
||||||
// fn f(x y: i32, z, t: i32) {}
|
p.error("missing type for function parameter");
|
||||||
p.error("missing type for function parameter");
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// test value_parameters_no_patterns
|
// test value_parameters_no_patterns
|
||||||
|
@ -127,12 +121,12 @@ fn param(p: &mut Parser, m: Marker, flavor: Flavor) -> Variadic {
|
||||||
Flavor::FnPointer => {
|
Flavor::FnPointer => {
|
||||||
if (p.at(IDENT) || p.at(UNDERSCORE)) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) {
|
if (p.at(IDENT) || p.at(UNDERSCORE)) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) {
|
||||||
patterns::pattern_single(p);
|
patterns::pattern_single(p);
|
||||||
if variadic_param(p) {
|
if !variadic_param(p) {
|
||||||
res = Variadic(true);
|
if p.at(T![:]) {
|
||||||
} else if p.at(T![:]) {
|
types::ascription(p);
|
||||||
types::ascription(p);
|
} else {
|
||||||
} else {
|
p.error("missing type for function parameter");
|
||||||
p.error("missing type for function parameter");
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
types::type_(p);
|
types::type_(p);
|
||||||
|
@ -150,7 +144,6 @@ fn param(p: &mut Parser, m: Marker, flavor: Flavor) -> Variadic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m.complete(p, PARAM);
|
m.complete(p, PARAM);
|
||||||
res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn variadic_param(p: &mut Parser) -> bool {
|
fn variadic_param(p: &mut Parser) -> bool {
|
||||||
|
|
|
@ -34,6 +34,18 @@ SOURCE_FILE
|
||||||
WHITESPACE " "
|
WHITESPACE " "
|
||||||
PARAM
|
PARAM
|
||||||
DOT3 "..."
|
DOT3 "..."
|
||||||
|
COMMA ","
|
||||||
|
WHITESPACE " "
|
||||||
|
PARAM
|
||||||
|
WILDCARD_PAT
|
||||||
|
UNDERSCORE "_"
|
||||||
|
COLON ":"
|
||||||
|
WHITESPACE " "
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "u8"
|
||||||
R_PAREN ")"
|
R_PAREN ")"
|
||||||
WHITESPACE " "
|
WHITESPACE " "
|
||||||
RET_TYPE
|
RET_TYPE
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
extern "C" { fn printf(format: *const i8, ...) -> i32; }
|
extern "C" { fn printf(format: *const i8, ..., _: u8) -> i32; }
|
||||||
|
|
|
@ -6,6 +6,10 @@ SOURCE_FILE
|
||||||
IDENT "foo"
|
IDENT "foo"
|
||||||
PARAM_LIST
|
PARAM_LIST
|
||||||
L_PAREN "("
|
L_PAREN "("
|
||||||
|
PARAM
|
||||||
|
DOT3 "..."
|
||||||
|
COMMA ","
|
||||||
|
WHITESPACE " "
|
||||||
PARAM
|
PARAM
|
||||||
TUPLE_PAT
|
TUPLE_PAT
|
||||||
L_PAREN "("
|
L_PAREN "("
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
fn foo((x, y): (i32, i32)) {}
|
fn foo(..., (x, y): (i32, i32)) {}
|
||||||
|
|
Loading…
Reference in a new issue