aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar/params.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_parser/src/grammar/params.rs')
-rw-r--r--crates/ra_parser/src/grammar/params.rs64
1 files changed, 34 insertions, 30 deletions
diff --git a/crates/ra_parser/src/grammar/params.rs b/crates/ra_parser/src/grammar/params.rs
index 272661b1d..f0da173cc 100644
--- a/crates/ra_parser/src/grammar/params.rs
+++ b/crates/ra_parser/src/grammar/params.rs
@@ -56,21 +56,17 @@ fn list_(p: &mut Parser, flavor: Flavor) {
56 // fn f(#[attr1] pat: Type) {} 56 // fn f(#[attr1] pat: Type) {}
57 attributes::outer_attributes(p); 57 attributes::outer_attributes(p);
58 58
59 // test param_list_vararg
60 // extern "C" { fn printf(format: *const i8, ...) -> i32; }
61 match flavor {
62 FnDef | FnPointer if p.eat(T![...]) => break,
63 _ => (),
64 }
65
66 if !p.at_ts(VALUE_PARAMETER_FIRST) { 59 if !p.at_ts(VALUE_PARAMETER_FIRST) {
67 p.error("expected value parameter"); 60 p.error("expected value parameter");
68 break; 61 break;
69 } 62 }
70 value_parameter(p, flavor); 63 let param = value_parameter(p, flavor);
71 if !p.at(ket) { 64 if !p.at(ket) {
72 p.expect(T![,]); 65 p.expect(T![,]);
73 } 66 }
67 if let Variadic(true) = param {
68 break;
69 }
74 } 70 }
75 71
76 p.expect(ket); 72 p.expect(ket);
@@ -79,32 +75,25 @@ fn list_(p: &mut Parser, flavor: Flavor) {
79 75
80const VALUE_PARAMETER_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST); 76const VALUE_PARAMETER_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST);
81 77
82fn value_parameter(p: &mut Parser, flavor: Flavor) { 78struct Variadic(bool);
79
80fn value_parameter(p: &mut Parser, flavor: Flavor) -> Variadic {
81 let mut res = Variadic(false);
83 let m = p.start(); 82 let m = p.start();
84 match flavor { 83 match flavor {
85 // test trait_fn_placeholder_parameter 84 // test param_list_vararg
86 // trait Foo { 85 // extern "C" { fn printf(format: *const i8, ...) -> i32; }
87 // fn bar(_: u64, mut x: i32); 86 Flavor::FnDef | Flavor::FnPointer if p.eat(T![...]) => res = Variadic(true),
88 // }
89
90 // test trait_fn_patterns
91 // trait T {
92 // fn f1((a, b): (usize, usize)) {}
93 // fn f2(S { a, b }: S) {}
94 // fn f3(NewType(a): NewType) {}
95 // fn f4(&&a: &&usize) {}
96 // }
97 87
98 // test fn_patterns 88 // test fn_def_param
99 // impl U { 89 // fn foo((x, y): (i32, i32)) {}
100 // fn f1((a, b): (usize, usize)) {}
101 // fn f2(S { a, b }: S) {}
102 // fn f3(NewType(a): NewType) {}
103 // fn f4(&&a: &&usize) {}
104 // }
105 Flavor::FnDef => { 90 Flavor::FnDef => {
106 patterns::pattern(p); 91 patterns::pattern(p);
107 types::ascription(p); 92 if variadic_param(p) {
93 res = Variadic(true)
94 } else {
95 types::ascription(p);
96 }
108 } 97 }
109 // test value_parameters_no_patterns 98 // test value_parameters_no_patterns
110 // type F = Box<Fn(i32, &i32, &i32, ())>; 99 // type F = Box<Fn(i32, &i32, &i32, ())>;
@@ -120,7 +109,11 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) {
120 Flavor::FnPointer => { 109 Flavor::FnPointer => {
121 if (p.at(IDENT) || p.at(UNDERSCORE)) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) { 110 if (p.at(IDENT) || p.at(UNDERSCORE)) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) {
122 patterns::pattern_single(p); 111 patterns::pattern_single(p);
123 types::ascription(p); 112 if variadic_param(p) {
113 res = Variadic(true)
114 } else {
115 types::ascription(p);
116 }
124 } else { 117 } else {
125 types::type_(p); 118 types::type_(p);
126 } 119 }
@@ -137,6 +130,17 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) {
137 } 130 }
138 } 131 }
139 m.complete(p, PARAM); 132 m.complete(p, PARAM);
133 res
134}
135
136fn variadic_param(p: &mut Parser) -> bool {
137 if p.at(T![:]) && p.nth_at(1, T![...]) {
138 p.bump(T![:]);
139 p.bump(T![...]);
140 true
141 } else {
142 false
143 }
140} 144}
141 145
142// test self_param 146// test self_param