2018-07-31 20:13:08 +00:00
|
|
|
use super::*;
|
|
|
|
|
|
|
|
// test param_list
|
|
|
|
// fn a() {}
|
|
|
|
// fn b(x: i32) {}
|
|
|
|
// fn c(x: i32, ) {}
|
|
|
|
// fn d(x: i32, y: ()) {}
|
2018-07-31 20:16:07 +00:00
|
|
|
pub(super) fn param_list(p: &mut Parser) {
|
2018-08-08 15:13:30 +00:00
|
|
|
list_(p, Flavor::Normal)
|
|
|
|
}
|
|
|
|
|
|
|
|
// test param_list_opt_patterns
|
|
|
|
// fn foo<F: FnMut(&mut Foo<'a>)>(){}
|
|
|
|
pub(super) fn param_list_opt_patterns(p: &mut Parser) {
|
|
|
|
list_(p, Flavor::OptionalPattern)
|
2018-07-31 20:13:08 +00:00
|
|
|
}
|
|
|
|
|
2018-07-31 20:16:07 +00:00
|
|
|
pub(super) fn param_list_opt_types(p: &mut Parser) {
|
2018-08-08 15:13:30 +00:00
|
|
|
list_(p, Flavor::OptionalType)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Eq, PartialEq)]
|
|
|
|
enum Flavor {
|
|
|
|
OptionalType,
|
|
|
|
OptionalPattern,
|
|
|
|
Normal,
|
2018-07-31 20:13:08 +00:00
|
|
|
}
|
|
|
|
|
2018-08-08 15:13:30 +00:00
|
|
|
impl Flavor {
|
|
|
|
fn type_required(self) -> bool {
|
|
|
|
match self {
|
|
|
|
Flavor::OptionalType => false,
|
|
|
|
_ => true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn list_(p: &mut Parser, flavor: Flavor) {
|
2019-02-08 11:49:43 +00:00
|
|
|
let (bra, ket) = if flavor.type_required() { (L_PAREN, R_PAREN) } else { (PIPE, PIPE) };
|
2018-08-08 15:13:30 +00:00
|
|
|
assert!(p.at(bra));
|
2018-07-31 20:13:08 +00:00
|
|
|
let m = p.start();
|
|
|
|
p.bump();
|
2018-08-08 15:13:30 +00:00
|
|
|
if flavor.type_required() {
|
2018-08-23 23:14:10 +00:00
|
|
|
opt_self_param(p);
|
2018-07-31 20:13:08 +00:00
|
|
|
}
|
2018-08-08 15:13:30 +00:00
|
|
|
while !p.at(EOF) && !p.at(ket) {
|
2018-09-08 07:38:53 +00:00
|
|
|
if !p.at_ts(VALUE_PARAMETER_FIRST) {
|
2018-08-24 17:50:37 +00:00
|
|
|
p.error("expected value parameter");
|
|
|
|
break;
|
|
|
|
}
|
2018-08-08 15:13:30 +00:00
|
|
|
value_parameter(p, flavor);
|
|
|
|
if !p.at(ket) {
|
2018-07-31 20:13:08 +00:00
|
|
|
p.expect(COMMA);
|
|
|
|
}
|
|
|
|
}
|
2018-08-08 15:13:30 +00:00
|
|
|
p.expect(ket);
|
2018-07-31 20:13:08 +00:00
|
|
|
m.complete(p, PARAM_LIST);
|
|
|
|
}
|
|
|
|
|
2019-01-18 08:02:30 +00:00
|
|
|
const VALUE_PARAMETER_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST);
|
2018-08-24 17:50:37 +00:00
|
|
|
|
2018-08-08 15:13:30 +00:00
|
|
|
fn value_parameter(p: &mut Parser, flavor: Flavor) {
|
2018-07-31 20:13:08 +00:00
|
|
|
let m = p.start();
|
2018-08-08 15:34:26 +00:00
|
|
|
match flavor {
|
|
|
|
Flavor::OptionalType | Flavor::Normal => {
|
|
|
|
patterns::pattern(p);
|
|
|
|
if p.at(COLON) || flavor.type_required() {
|
|
|
|
types::ascription(p)
|
|
|
|
}
|
2018-10-15 21:44:23 +00:00
|
|
|
}
|
2018-08-08 15:34:26 +00:00
|
|
|
// test value_parameters_no_patterns
|
|
|
|
// type F = Box<Fn(a: i32, &b: &i32, &mut c: &i32, ())>;
|
|
|
|
Flavor::OptionalPattern => {
|
|
|
|
let la0 = p.current();
|
|
|
|
let la1 = p.nth(1);
|
|
|
|
let la2 = p.nth(2);
|
|
|
|
let la3 = p.nth(3);
|
2019-01-22 17:46:15 +00:00
|
|
|
|
|
|
|
// test trait_fn_placeholder_parameter
|
|
|
|
// trait Foo {
|
|
|
|
// fn bar(_: u64);
|
|
|
|
// }
|
2019-01-22 17:33:53 +00:00
|
|
|
if (la0 == IDENT || la0 == UNDERSCORE) && la1 == COLON
|
2018-08-08 15:34:26 +00:00
|
|
|
|| la0 == AMP && la1 == IDENT && la2 == COLON
|
2018-10-15 21:44:23 +00:00
|
|
|
|| la0 == AMP && la1 == MUT_KW && la2 == IDENT && la3 == COLON
|
|
|
|
{
|
2018-08-08 15:34:26 +00:00
|
|
|
patterns::pattern(p);
|
|
|
|
types::ascription(p);
|
|
|
|
} else {
|
|
|
|
types::type_(p);
|
|
|
|
}
|
2018-10-15 21:44:23 +00:00
|
|
|
}
|
2018-07-31 20:13:08 +00:00
|
|
|
}
|
2018-07-31 20:13:55 +00:00
|
|
|
m.complete(p, PARAM);
|
2018-07-31 20:13:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// test self_param
|
|
|
|
// impl S {
|
|
|
|
// fn a(self) {}
|
|
|
|
// fn b(&self,) {}
|
|
|
|
// fn c(&'a self,) {}
|
|
|
|
// fn d(&'a mut self, x: i32) {}
|
2018-08-23 22:19:38 +00:00
|
|
|
// fn e(mut self) {}
|
2018-07-31 20:13:08 +00:00
|
|
|
// }
|
2018-08-23 23:14:10 +00:00
|
|
|
fn opt_self_param(p: &mut Parser) {
|
2018-08-23 16:07:33 +00:00
|
|
|
let m;
|
2018-08-23 22:19:38 +00:00
|
|
|
if p.at(SELF_KW) || p.at(MUT_KW) && p.nth(1) == SELF_KW {
|
2018-08-23 16:07:33 +00:00
|
|
|
m = p.start();
|
2018-08-23 22:19:38 +00:00
|
|
|
p.eat(MUT_KW);
|
|
|
|
p.eat(SELF_KW);
|
2018-08-23 16:07:33 +00:00
|
|
|
// test arb_self_types
|
|
|
|
// impl S {
|
|
|
|
// fn a(self: &Self) {}
|
2018-08-23 22:19:38 +00:00
|
|
|
// fn b(mut self: Box<Self>) {}
|
2018-08-23 16:07:33 +00:00
|
|
|
// }
|
|
|
|
if p.at(COLON) {
|
|
|
|
types::ascription(p);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
let la1 = p.nth(1);
|
|
|
|
let la2 = p.nth(2);
|
|
|
|
let la3 = p.nth(3);
|
|
|
|
let n_toks = match (p.current(), la1, la2, la3) {
|
|
|
|
(AMP, SELF_KW, _, _) => 2,
|
|
|
|
(AMP, MUT_KW, SELF_KW, _) => 3,
|
|
|
|
(AMP, LIFETIME, SELF_KW, _) => 3,
|
|
|
|
(AMP, LIFETIME, MUT_KW, SELF_KW) => 4,
|
|
|
|
_ => return,
|
|
|
|
};
|
|
|
|
m = p.start();
|
|
|
|
for _ in 0..n_toks {
|
|
|
|
p.bump();
|
|
|
|
}
|
2018-07-31 20:13:08 +00:00
|
|
|
}
|
|
|
|
m.complete(p, SELF_PARAM);
|
|
|
|
if !p.at(R_PAREN) {
|
|
|
|
p.expect(COMMA);
|
|
|
|
}
|
|
|
|
}
|