aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_parser')
-rw-r--r--crates/ra_parser/src/grammar.rs42
-rw-r--r--crates/ra_parser/src/grammar/attributes.rs4
-rw-r--r--crates/ra_parser/src/grammar/expressions.rs271
-rw-r--r--crates/ra_parser/src/grammar/expressions/atom.rs61
-rw-r--r--crates/ra_parser/src/grammar/items.rs22
-rw-r--r--crates/ra_parser/src/grammar/items/consts.rs2
-rw-r--r--crates/ra_parser/src/grammar/items/nominal.rs12
-rw-r--r--crates/ra_parser/src/grammar/items/traits.rs8
-rw-r--r--crates/ra_parser/src/grammar/items/use_item.rs30
-rw-r--r--crates/ra_parser/src/grammar/params.rs13
-rw-r--r--crates/ra_parser/src/grammar/paths.rs11
-rw-r--r--crates/ra_parser/src/grammar/patterns.rs49
-rw-r--r--crates/ra_parser/src/grammar/type_args.rs29
-rw-r--r--crates/ra_parser/src/grammar/type_params.rs18
-rw-r--r--crates/ra_parser/src/grammar/types.rs24
-rw-r--r--crates/ra_parser/src/parser.rs324
16 files changed, 411 insertions, 509 deletions
diff --git a/crates/ra_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs
index a2ad580bc..0158f9b8a 100644
--- a/crates/ra_parser/src/grammar.rs
+++ b/crates/ra_parser/src/grammar.rs
@@ -93,12 +93,12 @@ pub(crate) mod fragments {
93 // https://doc.rust-lang.org/reference/paths.html#simple-paths 93 // https://doc.rust-lang.org/reference/paths.html#simple-paths
94 // The start of an meta must be a simple path 94 // The start of an meta must be a simple path
95 match p.current() { 95 match p.current() {
96 IDENT | T![::] | T![super] | T![self] | T![crate] => p.bump(), 96 IDENT | T![::] | T![super] | T![self] | T![crate] => p.bump_any(),
97 T![=] => { 97 T![=] => {
98 p.bump(); 98 p.bump_any();
99 match p.current() { 99 match p.current() {
100 c if c.is_literal() => p.bump(), 100 c if c.is_literal() => p.bump_any(),
101 T![true] | T![false] => p.bump(), 101 T![true] | T![false] => p.bump_any(),
102 _ => {} 102 _ => {}
103 } 103 }
104 break; 104 break;
@@ -126,7 +126,7 @@ pub(crate) mod fragments {
126 126
127 while !p.at(EOF) { 127 while !p.at(EOF) {
128 if p.at(T![;]) { 128 if p.at(T![;]) {
129 p.bump(); 129 p.bump(T![;]);
130 continue; 130 continue;
131 } 131 }
132 132
@@ -179,7 +179,7 @@ fn opt_visibility(p: &mut Parser) -> bool {
179 match p.current() { 179 match p.current() {
180 T![pub] => { 180 T![pub] => {
181 let m = p.start(); 181 let m = p.start();
182 p.bump(); 182 p.bump(T![pub]);
183 if p.at(T!['(']) { 183 if p.at(T!['(']) {
184 match p.nth(1) { 184 match p.nth(1) {
185 // test crate_visibility 185 // test crate_visibility
@@ -188,13 +188,13 @@ fn opt_visibility(p: &mut Parser) -> bool {
188 // pub(self) struct S; 188 // pub(self) struct S;
189 // pub(self) struct S; 189 // pub(self) struct S;
190 T![crate] | T![self] | T![super] => { 190 T![crate] | T![self] | T![super] => {
191 p.bump(); 191 p.bump_any();
192 p.bump(); 192 p.bump_any();
193 p.expect(T![')']); 193 p.expect(T![')']);
194 } 194 }
195 T![in] => { 195 T![in] => {
196 p.bump(); 196 p.bump_any();
197 p.bump(); 197 p.bump_any();
198 paths::use_path(p); 198 paths::use_path(p);
199 p.expect(T![')']); 199 p.expect(T![')']);
200 } 200 }
@@ -210,9 +210,9 @@ fn opt_visibility(p: &mut Parser) -> bool {
210 // 210 //
211 // test crate_keyword_path 211 // test crate_keyword_path
212 // fn foo() { crate::foo(); } 212 // fn foo() { crate::foo(); }
213 T![crate] if p.nth(1) != T![::] => { 213 T![crate] if !p.nth_at(1, T![::]) => {
214 let m = p.start(); 214 let m = p.start();
215 p.bump(); 215 p.bump_any();
216 m.complete(p, VISIBILITY); 216 m.complete(p, VISIBILITY);
217 } 217 }
218 _ => return false, 218 _ => return false,
@@ -223,7 +223,7 @@ fn opt_visibility(p: &mut Parser) -> bool {
223fn opt_alias(p: &mut Parser) { 223fn opt_alias(p: &mut Parser) {
224 if p.at(T![as]) { 224 if p.at(T![as]) {
225 let m = p.start(); 225 let m = p.start();
226 p.bump(); 226 p.bump_any();
227 if !p.eat(T![_]) { 227 if !p.eat(T![_]) {
228 name(p); 228 name(p);
229 } 229 }
@@ -234,9 +234,9 @@ fn opt_alias(p: &mut Parser) {
234fn abi(p: &mut Parser) { 234fn abi(p: &mut Parser) {
235 assert!(p.at(T![extern])); 235 assert!(p.at(T![extern]));
236 let abi = p.start(); 236 let abi = p.start();
237 p.bump(); 237 p.bump_any();
238 match p.current() { 238 match p.current() {
239 STRING | RAW_STRING => p.bump(), 239 STRING | RAW_STRING => p.bump_any(),
240 _ => (), 240 _ => (),
241 } 241 }
242 abi.complete(p, ABI); 242 abi.complete(p, ABI);
@@ -245,7 +245,7 @@ fn abi(p: &mut Parser) {
245fn opt_fn_ret_type(p: &mut Parser) -> bool { 245fn opt_fn_ret_type(p: &mut Parser) -> bool {
246 if p.at(T![->]) { 246 if p.at(T![->]) {
247 let m = p.start(); 247 let m = p.start();
248 p.bump(); 248 p.bump(T![->]);
249 types::type_(p); 249 types::type_(p);
250 m.complete(p, RET_TYPE); 250 m.complete(p, RET_TYPE);
251 true 251 true
@@ -257,7 +257,7 @@ fn opt_fn_ret_type(p: &mut Parser) -> bool {
257fn name_r(p: &mut Parser, recovery: TokenSet) { 257fn name_r(p: &mut Parser, recovery: TokenSet) {
258 if p.at(IDENT) { 258 if p.at(IDENT) {
259 let m = p.start(); 259 let m = p.start();
260 p.bump(); 260 p.bump_any();
261 m.complete(p, NAME); 261 m.complete(p, NAME);
262 } else { 262 } else {
263 p.err_recover("expected a name", recovery); 263 p.err_recover("expected a name", recovery);
@@ -271,11 +271,11 @@ fn name(p: &mut Parser) {
271fn name_ref(p: &mut Parser) { 271fn name_ref(p: &mut Parser) {
272 if p.at(IDENT) { 272 if p.at(IDENT) {
273 let m = p.start(); 273 let m = p.start();
274 p.bump(); 274 p.bump_any();
275 m.complete(p, NAME_REF); 275 m.complete(p, NAME_REF);
276 } else if p.at(T![self]) { 276 } else if p.at(T![self]) {
277 let m = p.start(); 277 let m = p.start();
278 p.bump(); 278 p.bump_any();
279 m.complete(p, T![self]); 279 m.complete(p, T![self]);
280 } else { 280 } else {
281 p.err_and_bump("expected identifier"); 281 p.err_and_bump("expected identifier");
@@ -285,7 +285,7 @@ fn name_ref(p: &mut Parser) {
285fn name_ref_or_index(p: &mut Parser) { 285fn name_ref_or_index(p: &mut Parser) {
286 if p.at(IDENT) || p.at(INT_NUMBER) { 286 if p.at(IDENT) || p.at(INT_NUMBER) {
287 let m = p.start(); 287 let m = p.start();
288 p.bump(); 288 p.bump_any();
289 m.complete(p, NAME_REF); 289 m.complete(p, NAME_REF);
290 } else { 290 } else {
291 p.err_and_bump("expected identifier"); 291 p.err_and_bump("expected identifier");
@@ -296,7 +296,7 @@ fn error_block(p: &mut Parser, message: &str) {
296 assert!(p.at(T!['{'])); 296 assert!(p.at(T!['{']));
297 let m = p.start(); 297 let m = p.start();
298 p.error(message); 298 p.error(message);
299 p.bump(); 299 p.bump_any();
300 expressions::expr_block_contents(p); 300 expressions::expr_block_contents(p);
301 p.eat(T!['}']); 301 p.eat(T!['}']);
302 m.complete(p, ERROR); 302 m.complete(p, ERROR);
diff --git a/crates/ra_parser/src/grammar/attributes.rs b/crates/ra_parser/src/grammar/attributes.rs
index e97170203..81a363a57 100644
--- a/crates/ra_parser/src/grammar/attributes.rs
+++ b/crates/ra_parser/src/grammar/attributes.rs
@@ -15,11 +15,11 @@ pub(super) fn outer_attributes(p: &mut Parser) {
15fn attribute(p: &mut Parser, inner: bool) { 15fn attribute(p: &mut Parser, inner: bool) {
16 let attr = p.start(); 16 let attr = p.start();
17 assert!(p.at(T![#])); 17 assert!(p.at(T![#]));
18 p.bump(); 18 p.bump_any();
19 19
20 if inner { 20 if inner {
21 assert!(p.at(T![!])); 21 assert!(p.at(T![!]));
22 p.bump(); 22 p.bump_any();
23 } 23 }
24 24
25 if p.at(T!['[']) { 25 if p.at(T!['[']) {
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs
index 855418f1c..1dd9a586c 100644
--- a/crates/ra_parser/src/grammar/expressions.rs
+++ b/crates/ra_parser/src/grammar/expressions.rs
@@ -14,20 +14,17 @@ const EXPR_FIRST: TokenSet = LHS_FIRST;
14 14
15pub(super) fn expr(p: &mut Parser) -> BlockLike { 15pub(super) fn expr(p: &mut Parser) -> BlockLike {
16 let r = Restrictions { forbid_structs: false, prefer_stmt: false }; 16 let r = Restrictions { forbid_structs: false, prefer_stmt: false };
17 let mut dollar_lvl = 0; 17 expr_bp(p, r, 1).1
18 expr_bp(p, r, 1, &mut dollar_lvl).1
19} 18}
20 19
21pub(super) fn expr_stmt(p: &mut Parser) -> (Option<CompletedMarker>, BlockLike) { 20pub(super) fn expr_stmt(p: &mut Parser) -> (Option<CompletedMarker>, BlockLike) {
22 let r = Restrictions { forbid_structs: false, prefer_stmt: true }; 21 let r = Restrictions { forbid_structs: false, prefer_stmt: true };
23 let mut dollar_lvl = 0; 22 expr_bp(p, r, 1)
24 expr_bp(p, r, 1, &mut dollar_lvl)
25} 23}
26 24
27fn expr_no_struct(p: &mut Parser) { 25fn expr_no_struct(p: &mut Parser) {
28 let r = Restrictions { forbid_structs: true, prefer_stmt: false }; 26 let r = Restrictions { forbid_structs: true, prefer_stmt: false };
29 let mut dollar_lvl = 0; 27 expr_bp(p, r, 1);
30 expr_bp(p, r, 1, &mut dollar_lvl);
31} 28}
32 29
33// test block 30// test block
@@ -46,7 +43,7 @@ pub(crate) fn block(p: &mut Parser) {
46pub(crate) fn naked_block(p: &mut Parser) { 43pub(crate) fn naked_block(p: &mut Parser) {
47 assert!(p.at(T!['{'])); 44 assert!(p.at(T!['{']));
48 let m = p.start(); 45 let m = p.start();
49 p.bump(); 46 p.bump_any();
50 expr_block_contents(p); 47 expr_block_contents(p);
51 p.expect(T!['}']); 48 p.expect(T!['}']);
52 m.complete(p, BLOCK); 49 m.complete(p, BLOCK);
@@ -153,7 +150,7 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi) {
153 // } 150 // }
154 fn let_stmt(p: &mut Parser, m: Marker, with_semi: StmtWithSemi) { 151 fn let_stmt(p: &mut Parser, m: Marker, with_semi: StmtWithSemi) {
155 assert!(p.at(T![let])); 152 assert!(p.at(T![let]));
156 p.bump(); 153 p.bump_any();
157 patterns::pattern(p); 154 patterns::pattern(p);
158 if p.at(T![:]) { 155 if p.at(T![:]) {
159 types::ascription(p); 156 types::ascription(p);
@@ -198,7 +195,7 @@ pub(crate) fn expr_block_contents(p: &mut Parser) {
198 // } 195 // }
199 196
200 if p.at(T![;]) { 197 if p.at(T![;]) {
201 p.bump(); 198 p.bump_any();
202 continue; 199 continue;
203 } 200 }
204 201
@@ -212,72 +209,53 @@ struct Restrictions {
212 prefer_stmt: bool, 209 prefer_stmt: bool,
213} 210}
214 211
215enum Op { 212/// Binding powers of operators for a Pratt parser.
216 Simple, 213///
217 Composite(SyntaxKind, u8), 214/// See https://www.oilshell.org/blog/2016/11/03.html
218} 215#[rustfmt::skip]
219 216fn current_op(p: &Parser) -> (u8, SyntaxKind) {
220fn current_op(p: &Parser) -> (u8, Op) { 217 const NOT_AN_OP: (u8, SyntaxKind) = (0, T![@]);
221 if let Some(t) = p.current3() { 218 match p.current() {
222 match t { 219 T![|] if p.at(T![||]) => (3, T![||]),
223 (T![<], T![<], T![=]) => return (1, Op::Composite(T![<<=], 3)), 220 T![|] if p.at(T![|=]) => (1, T![|=]),
224 (T![>], T![>], T![=]) => return (1, Op::Composite(T![>>=], 3)), 221 T![|] => (6, T![|]),
225 _ => (), 222 T![>] if p.at(T![>>=]) => (1, T![>>=]),
226 } 223 T![>] if p.at(T![>>]) => (9, T![>>]),
227 } 224 T![>] if p.at(T![>=]) => (5, T![>=]),
228 225 T![>] => (5, T![>]),
229 if let Some(t) = p.current2() { 226 T![=] if p.at(T![=>]) => NOT_AN_OP,
230 match t { 227 T![=] if p.at(T![==]) => (5, T![==]),
231 (T![+], T![=]) => return (1, Op::Composite(T![+=], 2)), 228 T![=] => (1, T![=]),
232 (T![-], T![=]) => return (1, Op::Composite(T![-=], 2)), 229 T![<] if p.at(T![<=]) => (5, T![<=]),
233 (T![*], T![=]) => return (1, Op::Composite(T![*=], 2)), 230 T![<] if p.at(T![<<=]) => (1, T![<<=]),
234 (T![%], T![=]) => return (1, Op::Composite(T![%=], 2)), 231 T![<] if p.at(T![<<]) => (9, T![<<]),
235 (T![/], T![=]) => return (1, Op::Composite(T![/=], 2)), 232 T![<] => (5, T![<]),
236 (T![|], T![=]) => return (1, Op::Composite(T![|=], 2)), 233 T![+] if p.at(T![+=]) => (1, T![+=]),
237 (T![&], T![=]) => return (1, Op::Composite(T![&=], 2)), 234 T![+] => (10, T![+]),
238 (T![^], T![=]) => return (1, Op::Composite(T![^=], 2)), 235 T![^] if p.at(T![^=]) => (1, T![^=]),
239 (T![|], T![|]) => return (3, Op::Composite(T![||], 2)), 236 T![^] => (7, T![^]),
240 (T![&], T![&]) => return (4, Op::Composite(T![&&], 2)), 237 T![%] if p.at(T![%=]) => (1, T![%=]),
241 (T![<], T![=]) => return (5, Op::Composite(T![<=], 2)), 238 T![%] => (11, T![%]),
242 (T![>], T![=]) => return (5, Op::Composite(T![>=], 2)), 239 T![&] if p.at(T![&=]) => (1, T![&=]),
243 (T![<], T![<]) => return (9, Op::Composite(T![<<], 2)), 240 T![&] if p.at(T![&&]) => (4, T![&&]),
244 (T![>], T![>]) => return (9, Op::Composite(T![>>], 2)), 241 T![&] => (8, T![&]),
245 _ => (), 242 T![/] if p.at(T![/=]) => (1, T![/=]),
246 } 243 T![/] => (11, T![/]),
244 T![*] if p.at(T![*=]) => (1, T![*=]),
245 T![*] => (11, T![*]),
246 T![.] if p.at(T![..=]) => (2, T![..=]),
247 T![.] if p.at(T![..]) => (2, T![..]),
248 T![!] if p.at(T![!=]) => (5, T![!=]),
249 T![-] if p.at(T![-=]) => (1, T![-=]),
250 T![-] => (10, T![-]),
251
252 _ => NOT_AN_OP
247 } 253 }
248
249 let bp = match p.current() {
250 T![=] => 1,
251 T![..] | T![..=] => 2,
252 T![==] | T![!=] | T![<] | T![>] => 5,
253 T![|] => 6,
254 T![^] => 7,
255 T![&] => 8,
256 T![-] | T![+] => 10,
257 T![*] | T![/] | T![%] => 11,
258 _ => 0,
259 };
260 (bp, Op::Simple)
261} 254}
262 255
263// Parses expression with binding power of at least bp. 256// Parses expression with binding power of at least bp.
264fn expr_bp( 257fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> (Option<CompletedMarker>, BlockLike) {
265 p: &mut Parser, 258 let mut lhs = match lhs(p, r) {
266 r: Restrictions,
267 mut bp: u8,
268 dollar_lvl: &mut usize,
269) -> (Option<CompletedMarker>, BlockLike) {
270 // `newly_dollar_open` is a flag indicated that dollar is just closed after lhs, e.g.
271 // `$1$ + a`
272 // We use this flag to skip handling it.
273 let mut newly_dollar_open = if p.at_l_dollar() {
274 *dollar_lvl += p.eat_l_dollars();
275 true
276 } else {
277 false
278 };
279
280 let mut lhs = match lhs(p, r, dollar_lvl) {
281 Some((lhs, blocklike)) => { 259 Some((lhs, blocklike)) => {
282 // test stmt_bin_expr_ambiguity 260 // test stmt_bin_expr_ambiguity
283 // fn foo() { 261 // fn foo() {
@@ -293,42 +271,23 @@ fn expr_bp(
293 }; 271 };
294 272
295 loop { 273 loop {
296 if *dollar_lvl > 0 && p.at_r_dollar() {
297 *dollar_lvl -= p.eat_r_dollars(*dollar_lvl);
298 if !newly_dollar_open {
299 // We "pump" bp for make it highest priority
300 bp = 255;
301 }
302 newly_dollar_open = false;
303 }
304
305 let is_range = p.at(T![..]) || p.at(T![..=]); 274 let is_range = p.at(T![..]) || p.at(T![..=]);
306 let (op_bp, op) = current_op(p); 275 let (op_bp, op) = current_op(p);
307 if op_bp < bp { 276 if op_bp < bp {
308 break; 277 break;
309 } 278 }
310 let m = lhs.precede(p); 279 let m = lhs.precede(p);
311 match op { 280 p.bump(op);
312 Op::Simple => p.bump(),
313 Op::Composite(kind, n) => {
314 p.bump_compound(kind, n);
315 }
316 }
317 281
318 expr_bp(p, r, op_bp + 1, dollar_lvl); 282 expr_bp(p, r, op_bp + 1);
319 lhs = m.complete(p, if is_range { RANGE_EXPR } else { BIN_EXPR }); 283 lhs = m.complete(p, if is_range { RANGE_EXPR } else { BIN_EXPR });
320 } 284 }
321 (Some(lhs), BlockLike::NotBlock) 285 (Some(lhs), BlockLike::NotBlock)
322} 286}
323 287
324const LHS_FIRST: TokenSet = 288const LHS_FIRST: TokenSet = atom::ATOM_EXPR_FIRST.union(token_set![AMP, STAR, EXCL, DOT, MINUS]);
325 atom::ATOM_EXPR_FIRST.union(token_set![AMP, STAR, EXCL, DOTDOT, DOTDOTEQ, MINUS]);
326 289
327fn lhs( 290fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> {
328 p: &mut Parser,
329 r: Restrictions,
330 dollar_lvl: &mut usize,
331) -> Option<(CompletedMarker, BlockLike)> {
332 let m; 291 let m;
333 let kind = match p.current() { 292 let kind = match p.current() {
334 // test ref_expr 293 // test ref_expr
@@ -338,7 +297,7 @@ fn lhs(
338 // } 297 // }
339 T![&] => { 298 T![&] => {
340 m = p.start(); 299 m = p.start();
341 p.bump(); 300 p.bump_any();
342 p.eat(T![mut]); 301 p.eat(T![mut]);
343 REF_EXPR 302 REF_EXPR
344 } 303 }
@@ -350,20 +309,23 @@ fn lhs(
350 // } 309 // }
351 T![*] | T![!] | T![-] => { 310 T![*] | T![!] | T![-] => {
352 m = p.start(); 311 m = p.start();
353 p.bump(); 312 p.bump_any();
354 PREFIX_EXPR 313 PREFIX_EXPR
355 } 314 }
356 // test full_range_expr
357 // fn foo() { xs[..]; }
358 T![..] | T![..=] => {
359 m = p.start();
360 p.bump();
361 if p.at_ts(EXPR_FIRST) {
362 expr_bp(p, r, 2, dollar_lvl);
363 }
364 return Some((m.complete(p, RANGE_EXPR), BlockLike::NotBlock));
365 }
366 _ => { 315 _ => {
316 // test full_range_expr
317 // fn foo() { xs[..]; }
318 for &op in [T![..=], T![..]].iter() {
319 if p.at(op) {
320 m = p.start();
321 p.bump(op);
322 if p.at_ts(EXPR_FIRST) {
323 expr_bp(p, r, 2);
324 }
325 return Some((m.complete(p, RANGE_EXPR), BlockLike::NotBlock));
326 }
327 }
328
367 // test expression_after_block 329 // test expression_after_block
368 // fn foo() { 330 // fn foo() {
369 // let mut p = F{x: 5}; 331 // let mut p = F{x: 5};
@@ -374,7 +336,7 @@ fn lhs(
374 return Some(postfix_expr(p, lhs, blocklike, !(r.prefer_stmt && blocklike.is_block()))); 336 return Some(postfix_expr(p, lhs, blocklike, !(r.prefer_stmt && blocklike.is_block())));
375 } 337 }
376 }; 338 };
377 expr_bp(p, r, 255, dollar_lvl); 339 expr_bp(p, r, 255);
378 Some((m.complete(p, kind), BlockLike::NotBlock)) 340 Some((m.complete(p, kind), BlockLike::NotBlock))
379} 341}
380 342
@@ -399,29 +361,13 @@ fn postfix_expr(
399 // } 361 // }
400 T!['('] if allow_calls => call_expr(p, lhs), 362 T!['('] if allow_calls => call_expr(p, lhs),
401 T!['['] if allow_calls => index_expr(p, lhs), 363 T!['['] if allow_calls => index_expr(p, lhs),
402 T![.] if p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth(2) == T![::]) => { 364 T![.] => match postfix_dot_expr(p, lhs) {
403 method_call_expr(p, lhs) 365 Ok(it) => it,
404 } 366 Err(it) => {
405 T![.] if p.nth(1) == AWAIT_KW => { 367 lhs = it;
406 // test await_expr 368 break;
407 // fn foo() { 369 }
408 // x.await; 370 },
409 // x.0.await;
410 // x.0().await?.hello();
411 // }
412 let m = lhs.precede(p);
413 p.bump();
414 p.bump();
415 m.complete(p, AWAIT_EXPR)
416 }
417 T![.] => field_expr(p, lhs),
418 // test postfix_range
419 // fn foo() { let x = 1..; }
420 T![..] | T![..=] if !EXPR_FIRST.contains(p.nth(1)) => {
421 let m = lhs.precede(p);
422 p.bump();
423 m.complete(p, RANGE_EXPR)
424 }
425 T![?] => try_expr(p, lhs), 371 T![?] => try_expr(p, lhs),
426 T![as] => cast_expr(p, lhs), 372 T![as] => cast_expr(p, lhs),
427 _ => break, 373 _ => break,
@@ -429,7 +375,46 @@ fn postfix_expr(
429 allow_calls = true; 375 allow_calls = true;
430 block_like = BlockLike::NotBlock; 376 block_like = BlockLike::NotBlock;
431 } 377 }
432 (lhs, block_like) 378 return (lhs, block_like);
379
380 fn postfix_dot_expr(
381 p: &mut Parser,
382 lhs: CompletedMarker,
383 ) -> Result<CompletedMarker, CompletedMarker> {
384 assert!(p.at(T![.]));
385 if p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth_at(2, T![::])) {
386 return Ok(method_call_expr(p, lhs));
387 }
388
389 // test await_expr
390 // fn foo() {
391 // x.await;
392 // x.0.await;
393 // x.0().await?.hello();
394 // }
395 if p.nth(1) == T![await] {
396 let m = lhs.precede(p);
397 p.bump(T![.]);
398 p.bump(T![await]);
399 return Ok(m.complete(p, AWAIT_EXPR));
400 }
401
402 // test postfix_range
403 // fn foo() { let x = 1..; }
404 for &(op, la) in [(T![..=], 3), (T![..], 2)].iter() {
405 if p.at(op) {
406 return if EXPR_FIRST.contains(p.nth(la)) {
407 Err(lhs)
408 } else {
409 let m = lhs.precede(p);
410 p.bump(op);
411 Ok(m.complete(p, RANGE_EXPR))
412 };
413 }
414 }
415
416 Ok(field_expr(p, lhs))
417 }
433} 418}
434 419
435// test call_expr 420// test call_expr
@@ -453,7 +438,7 @@ fn call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
453fn index_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { 438fn index_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
454 assert!(p.at(T!['['])); 439 assert!(p.at(T!['[']));
455 let m = lhs.precede(p); 440 let m = lhs.precede(p);
456 p.bump(); 441 p.bump_any();
457 expr(p); 442 expr(p);
458 p.expect(T![']']); 443 p.expect(T![']']);
459 m.complete(p, INDEX_EXPR) 444 m.complete(p, INDEX_EXPR)
@@ -465,9 +450,9 @@ fn index_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
465// y.bar::<T>(1, 2,); 450// y.bar::<T>(1, 2,);
466// } 451// }
467fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { 452fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
468 assert!(p.at(T![.]) && p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth(2) == T![::])); 453 assert!(p.at(T![.]) && p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth_at(2, T![::])));
469 let m = lhs.precede(p); 454 let m = lhs.precede(p);
470 p.bump(); 455 p.bump_any();
471 name_ref(p); 456 name_ref(p);
472 type_args::opt_type_arg_list(p, true); 457 type_args::opt_type_arg_list(p, true);
473 if p.at(T!['(']) { 458 if p.at(T!['(']) {
@@ -493,12 +478,12 @@ fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
493fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { 478fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
494 assert!(p.at(T![.])); 479 assert!(p.at(T![.]));
495 let m = lhs.precede(p); 480 let m = lhs.precede(p);
496 p.bump(); 481 p.bump_any();
497 if p.at(IDENT) || p.at(INT_NUMBER) { 482 if p.at(IDENT) || p.at(INT_NUMBER) {
498 name_ref_or_index(p) 483 name_ref_or_index(p)
499 } else if p.at(FLOAT_NUMBER) { 484 } else if p.at(FLOAT_NUMBER) {
500 // FIXME: How to recover and instead parse INT + T![.]? 485 // FIXME: How to recover and instead parse INT + T![.]?
501 p.bump(); 486 p.bump_any();
502 } else { 487 } else {
503 p.error("expected field name or number") 488 p.error("expected field name or number")
504 } 489 }
@@ -512,7 +497,7 @@ fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
512fn try_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { 497fn try_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
513 assert!(p.at(T![?])); 498 assert!(p.at(T![?]));
514 let m = lhs.precede(p); 499 let m = lhs.precede(p);
515 p.bump(); 500 p.bump_any();
516 m.complete(p, TRY_EXPR) 501 m.complete(p, TRY_EXPR)
517} 502}
518 503
@@ -526,7 +511,7 @@ fn try_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
526fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { 511fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
527 assert!(p.at(T![as])); 512 assert!(p.at(T![as]));
528 let m = lhs.precede(p); 513 let m = lhs.precede(p);
529 p.bump(); 514 p.bump_any();
530 // Use type_no_bounds(), because cast expressions are not 515 // Use type_no_bounds(), because cast expressions are not
531 // allowed to have bounds. 516 // allowed to have bounds.
532 types::type_no_bounds(p); 517 types::type_no_bounds(p);
@@ -536,7 +521,7 @@ fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
536fn arg_list(p: &mut Parser) { 521fn arg_list(p: &mut Parser) {
537 assert!(p.at(T!['('])); 522 assert!(p.at(T!['(']));
538 let m = p.start(); 523 let m = p.start();
539 p.bump(); 524 p.bump_any();
540 while !p.at(T![')']) && !p.at(EOF) { 525 while !p.at(T![')']) && !p.at(EOF) {
541 if !p.at_ts(EXPR_FIRST) { 526 if !p.at_ts(EXPR_FIRST) {
542 p.error("expected expression"); 527 p.error("expected expression");
@@ -567,7 +552,7 @@ fn path_expr(p: &mut Parser, r: Restrictions) -> (CompletedMarker, BlockLike) {
567 record_field_list(p); 552 record_field_list(p);
568 (m.complete(p, RECORD_LIT), BlockLike::NotBlock) 553 (m.complete(p, RECORD_LIT), BlockLike::NotBlock)
569 } 554 }
570 T![!] => { 555 T![!] if !p.at(T![!=]) => {
571 let block_like = items::macro_call_after_excl(p); 556 let block_like = items::macro_call_after_excl(p);
572 (m.complete(p, MACRO_CALL), block_like) 557 (m.complete(p, MACRO_CALL), block_like)
573 } 558 }
@@ -585,7 +570,7 @@ fn path_expr(p: &mut Parser, r: Restrictions) -> (CompletedMarker, BlockLike) {
585pub(crate) fn record_field_list(p: &mut Parser) { 570pub(crate) fn record_field_list(p: &mut Parser) {
586 assert!(p.at(T!['{'])); 571 assert!(p.at(T!['{']));
587 let m = p.start(); 572 let m = p.start();
588 p.bump(); 573 p.bump_any();
589 while !p.at(EOF) && !p.at(T!['}']) { 574 while !p.at(EOF) && !p.at(T!['}']) {
590 match p.current() { 575 match p.current() {
591 // test record_literal_field_with_attr 576 // test record_literal_field_with_attr
@@ -601,8 +586,8 @@ pub(crate) fn record_field_list(p: &mut Parser) {
601 } 586 }
602 m.complete(p, RECORD_FIELD); 587 m.complete(p, RECORD_FIELD);
603 } 588 }
604 T![..] => { 589 T![.] if p.at(T![..]) => {
605 p.bump(); 590 p.bump(T![..]);
606 expr(p); 591 expr(p);
607 } 592 }
608 T!['{'] => error_block(p, "expected a field"), 593 T!['{'] => error_block(p, "expected a field"),
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs
index ec7f2441d..6e295fbf9 100644
--- a/crates/ra_parser/src/grammar/expressions/atom.rs
+++ b/crates/ra_parser/src/grammar/expressions/atom.rs
@@ -31,7 +31,7 @@ pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> {
31 return None; 31 return None;
32 } 32 }
33 let m = p.start(); 33 let m = p.start();
34 p.bump(); 34 p.bump_any();
35 Some(m.complete(p, LITERAL)) 35 Some(m.complete(p, LITERAL))
36} 36}
37 37
@@ -69,6 +69,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
69 let done = match p.current() { 69 let done = match p.current() {
70 T!['('] => tuple_expr(p), 70 T!['('] => tuple_expr(p),
71 T!['['] => array_expr(p), 71 T!['['] => array_expr(p),
72 L_DOLLAR => meta_var_expr(p),
72 T![|] => lambda_expr(p), 73 T![|] => lambda_expr(p),
73 T![move] if la == T![|] => lambda_expr(p), 74 T![move] if la == T![|] => lambda_expr(p),
74 T![async] if la == T![|] || (la == T![move] && p.nth(2) == T![|]) => lambda_expr(p), 75 T![async] if la == T![|] || (la == T![move] && p.nth(2) == T![|]) => lambda_expr(p),
@@ -100,14 +101,14 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
100 } 101 }
101 T![async] if la == T!['{'] || (la == T![move] && p.nth(2) == T!['{']) => { 102 T![async] if la == T!['{'] || (la == T![move] && p.nth(2) == T!['{']) => {
102 let m = p.start(); 103 let m = p.start();
103 p.bump(); 104 p.bump_any();
104 p.eat(T![move]); 105 p.eat(T![move]);
105 block_expr(p, Some(m)) 106 block_expr(p, Some(m))
106 } 107 }
107 T![match] => match_expr(p), 108 T![match] => match_expr(p),
108 T![unsafe] if la == T!['{'] => { 109 T![unsafe] if la == T!['{'] => {
109 let m = p.start(); 110 let m = p.start();
110 p.bump(); 111 p.bump_any();
111 block_expr(p, Some(m)) 112 block_expr(p, Some(m))
112 } 113 }
113 T!['{'] => { 114 T!['{'] => {
@@ -179,7 +180,7 @@ fn tuple_expr(p: &mut Parser) -> CompletedMarker {
179fn array_expr(p: &mut Parser) -> CompletedMarker { 180fn array_expr(p: &mut Parser) -> CompletedMarker {
180 assert!(p.at(T!['['])); 181 assert!(p.at(T!['[']));
181 let m = p.start(); 182 let m = p.start();
182 p.bump(); 183 p.bump_any();
183 if p.eat(T![']']) { 184 if p.eat(T![']']) {
184 return m.complete(p, ARRAY_EXPR); 185 return m.complete(p, ARRAY_EXPR);
185 } 186 }
@@ -261,11 +262,11 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker {
261fn if_expr(p: &mut Parser) -> CompletedMarker { 262fn if_expr(p: &mut Parser) -> CompletedMarker {
262 assert!(p.at(T![if])); 263 assert!(p.at(T![if]));
263 let m = p.start(); 264 let m = p.start();
264 p.bump(); 265 p.bump_any();
265 cond(p); 266 cond(p);
266 block(p); 267 block(p);
267 if p.at(T![else]) { 268 if p.at(T![else]) {
268 p.bump(); 269 p.bump_any();
269 if p.at(T![if]) { 270 if p.at(T![if]) {
270 if_expr(p); 271 if_expr(p);
271 } else { 272 } else {
@@ -284,8 +285,8 @@ fn if_expr(p: &mut Parser) -> CompletedMarker {
284fn label(p: &mut Parser) { 285fn label(p: &mut Parser) {
285 assert!(p.at(LIFETIME) && p.nth(1) == T![:]); 286 assert!(p.at(LIFETIME) && p.nth(1) == T![:]);
286 let m = p.start(); 287 let m = p.start();
287 p.bump(); 288 p.bump_any();
288 p.bump(); 289 p.bump_any();
289 m.complete(p, LABEL); 290 m.complete(p, LABEL);
290} 291}
291 292
@@ -296,7 +297,7 @@ fn label(p: &mut Parser) {
296fn loop_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { 297fn loop_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
297 assert!(p.at(T![loop])); 298 assert!(p.at(T![loop]));
298 let m = m.unwrap_or_else(|| p.start()); 299 let m = m.unwrap_or_else(|| p.start());
299 p.bump(); 300 p.bump_any();
300 block(p); 301 block(p);
301 m.complete(p, LOOP_EXPR) 302 m.complete(p, LOOP_EXPR)
302} 303}
@@ -309,7 +310,7 @@ fn loop_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
309fn while_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { 310fn while_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
310 assert!(p.at(T![while])); 311 assert!(p.at(T![while]));
311 let m = m.unwrap_or_else(|| p.start()); 312 let m = m.unwrap_or_else(|| p.start());
312 p.bump(); 313 p.bump_any();
313 cond(p); 314 cond(p);
314 block(p); 315 block(p);
315 m.complete(p, WHILE_EXPR) 316 m.complete(p, WHILE_EXPR)
@@ -322,7 +323,7 @@ fn while_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
322fn for_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { 323fn for_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
323 assert!(p.at(T![for])); 324 assert!(p.at(T![for]));
324 let m = m.unwrap_or_else(|| p.start()); 325 let m = m.unwrap_or_else(|| p.start());
325 p.bump(); 326 p.bump_any();
326 patterns::pattern(p); 327 patterns::pattern(p);
327 p.expect(T![in]); 328 p.expect(T![in]);
328 expr_no_struct(p); 329 expr_no_struct(p);
@@ -356,7 +357,7 @@ fn cond(p: &mut Parser) {
356fn match_expr(p: &mut Parser) -> CompletedMarker { 357fn match_expr(p: &mut Parser) -> CompletedMarker {
357 assert!(p.at(T![match])); 358 assert!(p.at(T![match]));
358 let m = p.start(); 359 let m = p.start();
359 p.bump(); 360 p.bump_any();
360 expr_no_struct(p); 361 expr_no_struct(p);
361 if p.at(T!['{']) { 362 if p.at(T!['{']) {
362 match_arm_list(p); 363 match_arm_list(p);
@@ -452,7 +453,7 @@ fn match_arm(p: &mut Parser) -> BlockLike {
452fn match_guard(p: &mut Parser) -> CompletedMarker { 453fn match_guard(p: &mut Parser) -> CompletedMarker {
453 assert!(p.at(T![if])); 454 assert!(p.at(T![if]));
454 let m = p.start(); 455 let m = p.start();
455 p.bump(); 456 p.bump_any();
456 expr(p); 457 expr(p);
457 m.complete(p, MATCH_GUARD) 458 m.complete(p, MATCH_GUARD)
458} 459}
@@ -478,7 +479,7 @@ pub(super) fn block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
478fn return_expr(p: &mut Parser) -> CompletedMarker { 479fn return_expr(p: &mut Parser) -> CompletedMarker {
479 assert!(p.at(T![return])); 480 assert!(p.at(T![return]));
480 let m = p.start(); 481 let m = p.start();
481 p.bump(); 482 p.bump_any();
482 if p.at_ts(EXPR_FIRST) { 483 if p.at_ts(EXPR_FIRST) {
483 expr(p); 484 expr(p);
484 } 485 }
@@ -495,7 +496,7 @@ fn return_expr(p: &mut Parser) -> CompletedMarker {
495fn continue_expr(p: &mut Parser) -> CompletedMarker { 496fn continue_expr(p: &mut Parser) -> CompletedMarker {
496 assert!(p.at(T![continue])); 497 assert!(p.at(T![continue]));
497 let m = p.start(); 498 let m = p.start();
498 p.bump(); 499 p.bump_any();
499 p.eat(LIFETIME); 500 p.eat(LIFETIME);
500 m.complete(p, CONTINUE_EXPR) 501 m.complete(p, CONTINUE_EXPR)
501} 502}
@@ -512,7 +513,7 @@ fn continue_expr(p: &mut Parser) -> CompletedMarker {
512fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker { 513fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker {
513 assert!(p.at(T![break])); 514 assert!(p.at(T![break]));
514 let m = p.start(); 515 let m = p.start();
515 p.bump(); 516 p.bump_any();
516 p.eat(LIFETIME); 517 p.eat(LIFETIME);
517 // test break_ambiguity 518 // test break_ambiguity
518 // fn foo(){ 519 // fn foo(){
@@ -534,7 +535,7 @@ fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker {
534fn try_block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { 535fn try_block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
535 assert!(p.at(T![try])); 536 assert!(p.at(T![try]));
536 let m = m.unwrap_or_else(|| p.start()); 537 let m = m.unwrap_or_else(|| p.start());
537 p.bump(); 538 p.bump_any();
538 block(p); 539 block(p);
539 m.complete(p, TRY_EXPR) 540 m.complete(p, TRY_EXPR)
540} 541}
@@ -548,9 +549,33 @@ fn try_block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
548fn box_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { 549fn box_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
549 assert!(p.at(T![box])); 550 assert!(p.at(T![box]));
550 let m = m.unwrap_or_else(|| p.start()); 551 let m = m.unwrap_or_else(|| p.start());
551 p.bump(); 552 p.bump_any();
552 if p.at_ts(EXPR_FIRST) { 553 if p.at_ts(EXPR_FIRST) {
553 expr(p); 554 expr(p);
554 } 555 }
555 m.complete(p, BOX_EXPR) 556 m.complete(p, BOX_EXPR)
556} 557}
558
559/// Expression from `$var` macro expansion, wrapped in dollars
560fn meta_var_expr(p: &mut Parser) -> CompletedMarker {
561 assert!(p.at(L_DOLLAR));
562 let m = p.start();
563 p.bump(L_DOLLAR);
564 let (completed, _is_block) =
565 expr_bp(p, Restrictions { forbid_structs: false, prefer_stmt: false }, 1);
566
567 match (completed, p.current()) {
568 (Some(it), R_DOLLAR) => {
569 p.bump(R_DOLLAR);
570 m.abandon(p);
571 it
572 }
573 _ => {
574 while !p.at(R_DOLLAR) {
575 p.bump_any()
576 }
577 p.bump(R_DOLLAR);
578 m.complete(p, ERROR)
579 }
580 }
581}
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs
index b4327b78f..eff9d67e4 100644
--- a/crates/ra_parser/src/grammar/items.rs
+++ b/crates/ra_parser/src/grammar/items.rs
@@ -64,7 +64,7 @@ pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemF
64 } else if p.at(T!['}']) && !stop_on_r_curly { 64 } else if p.at(T!['}']) && !stop_on_r_curly {
65 let e = p.start(); 65 let e = p.start();
66 p.error("unmatched `}`"); 66 p.error("unmatched `}`");
67 p.bump(); 67 p.bump_any();
68 e.complete(p, ERROR); 68 e.complete(p, ERROR);
69 } else if !p.at(EOF) && !p.at(T!['}']) { 69 } else if !p.at(EOF) && !p.at(T!['}']) {
70 p.err_and_bump("expected an item"); 70 p.err_and_bump("expected an item");
@@ -276,9 +276,9 @@ fn items_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> {
276 276
277fn extern_crate_item(p: &mut Parser, m: Marker) { 277fn extern_crate_item(p: &mut Parser, m: Marker) {
278 assert!(p.at(T![extern])); 278 assert!(p.at(T![extern]));
279 p.bump(); 279 p.bump_any();
280 assert!(p.at(T![crate])); 280 assert!(p.at(T![crate]));
281 p.bump(); 281 p.bump_any();
282 name_ref(p); 282 name_ref(p);
283 opt_alias(p); 283 opt_alias(p);
284 p.expect(T![;]); 284 p.expect(T![;]);
@@ -288,7 +288,7 @@ fn extern_crate_item(p: &mut Parser, m: Marker) {
288pub(crate) fn extern_item_list(p: &mut Parser) { 288pub(crate) fn extern_item_list(p: &mut Parser) {
289 assert!(p.at(T!['{'])); 289 assert!(p.at(T!['{']));
290 let m = p.start(); 290 let m = p.start();
291 p.bump(); 291 p.bump_any();
292 mod_contents(p, true); 292 mod_contents(p, true);
293 p.expect(T!['}']); 293 p.expect(T!['}']);
294 m.complete(p, EXTERN_ITEM_LIST); 294 m.complete(p, EXTERN_ITEM_LIST);
@@ -296,7 +296,7 @@ pub(crate) fn extern_item_list(p: &mut Parser) {
296 296
297fn fn_def(p: &mut Parser, flavor: ItemFlavor) { 297fn fn_def(p: &mut Parser, flavor: ItemFlavor) {
298 assert!(p.at(T![fn])); 298 assert!(p.at(T![fn]));
299 p.bump(); 299 p.bump_any();
300 300
301 name_r(p, ITEM_RECOVERY_SET); 301 name_r(p, ITEM_RECOVERY_SET);
302 // test function_type_params 302 // test function_type_params
@@ -323,7 +323,7 @@ fn fn_def(p: &mut Parser, flavor: ItemFlavor) {
323 // test fn_decl 323 // test fn_decl
324 // trait T { fn foo(); } 324 // trait T { fn foo(); }
325 if p.at(T![;]) { 325 if p.at(T![;]) {
326 p.bump(); 326 p.bump_any();
327 } else { 327 } else {
328 expressions::block(p) 328 expressions::block(p)
329 } 329 }
@@ -333,7 +333,7 @@ fn fn_def(p: &mut Parser, flavor: ItemFlavor) {
333// type Foo = Bar; 333// type Foo = Bar;
334fn type_def(p: &mut Parser, m: Marker) { 334fn type_def(p: &mut Parser, m: Marker) {
335 assert!(p.at(T![type])); 335 assert!(p.at(T![type]));
336 p.bump(); 336 p.bump_any();
337 337
338 name(p); 338 name(p);
339 339
@@ -357,7 +357,7 @@ fn type_def(p: &mut Parser, m: Marker) {
357 357
358pub(crate) fn mod_item(p: &mut Parser, m: Marker) { 358pub(crate) fn mod_item(p: &mut Parser, m: Marker) {
359 assert!(p.at(T![mod])); 359 assert!(p.at(T![mod]));
360 p.bump(); 360 p.bump_any();
361 361
362 name(p); 362 name(p);
363 if p.at(T!['{']) { 363 if p.at(T!['{']) {
@@ -371,7 +371,7 @@ pub(crate) fn mod_item(p: &mut Parser, m: Marker) {
371pub(crate) fn mod_item_list(p: &mut Parser) { 371pub(crate) fn mod_item_list(p: &mut Parser) {
372 assert!(p.at(T!['{'])); 372 assert!(p.at(T!['{']));
373 let m = p.start(); 373 let m = p.start();
374 p.bump(); 374 p.bump_any();
375 mod_contents(p, true); 375 mod_contents(p, true);
376 p.expect(T!['}']); 376 p.expect(T!['}']);
377 m.complete(p, ITEM_LIST); 377 m.complete(p, ITEM_LIST);
@@ -412,7 +412,7 @@ pub(crate) fn token_tree(p: &mut Parser) {
412 _ => unreachable!(), 412 _ => unreachable!(),
413 }; 413 };
414 let m = p.start(); 414 let m = p.start();
415 p.bump(); 415 p.bump_any();
416 while !p.at(EOF) && !p.at(closing_paren_kind) { 416 while !p.at(EOF) && !p.at(closing_paren_kind) {
417 match p.current() { 417 match p.current() {
418 T!['{'] | T!['('] | T!['['] => token_tree(p), 418 T!['{'] | T!['('] | T!['['] => token_tree(p),
@@ -422,7 +422,7 @@ pub(crate) fn token_tree(p: &mut Parser) {
422 return; 422 return;
423 } 423 }
424 T![')'] | T![']'] => p.err_and_bump("unmatched brace"), 424 T![')'] | T![']'] => p.err_and_bump("unmatched brace"),
425 _ => p.bump_raw(), 425 _ => p.bump_any(),
426 } 426 }
427 } 427 }
428 p.expect(closing_paren_kind); 428 p.expect(closing_paren_kind);
diff --git a/crates/ra_parser/src/grammar/items/consts.rs b/crates/ra_parser/src/grammar/items/consts.rs
index b4908ebba..e11546333 100644
--- a/crates/ra_parser/src/grammar/items/consts.rs
+++ b/crates/ra_parser/src/grammar/items/consts.rs
@@ -10,7 +10,7 @@ pub(super) fn const_def(p: &mut Parser, m: Marker) {
10 10
11fn const_or_static(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) { 11fn const_or_static(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) {
12 assert!(p.at(kw)); 12 assert!(p.at(kw));
13 p.bump(); 13 p.bump_any();
14 p.eat(T![mut]); // FIXME: validator to forbid const mut 14 p.eat(T![mut]); // FIXME: validator to forbid const mut
15 name(p); 15 name(p);
16 types::ascription(p); 16 types::ascription(p);
diff --git a/crates/ra_parser/src/grammar/items/nominal.rs b/crates/ra_parser/src/grammar/items/nominal.rs
index 54f02c7c9..460acd65e 100644
--- a/crates/ra_parser/src/grammar/items/nominal.rs
+++ b/crates/ra_parser/src/grammar/items/nominal.rs
@@ -11,7 +11,7 @@ pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) {
11 type_params::opt_where_clause(p); 11 type_params::opt_where_clause(p);
12 match p.current() { 12 match p.current() {
13 T![;] => { 13 T![;] => {
14 p.bump(); 14 p.bump_any();
15 } 15 }
16 T!['{'] => record_field_def_list(p), 16 T!['{'] => record_field_def_list(p),
17 _ => { 17 _ => {
@@ -21,7 +21,7 @@ pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) {
21 } 21 }
22 } 22 }
23 T![;] if kind == T![struct] => { 23 T![;] if kind == T![struct] => {
24 p.bump(); 24 p.bump_any();
25 } 25 }
26 T!['{'] => record_field_def_list(p), 26 T!['{'] => record_field_def_list(p),
27 T!['('] if kind == T![struct] => { 27 T!['('] if kind == T![struct] => {
@@ -44,7 +44,7 @@ pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) {
44 44
45pub(super) fn enum_def(p: &mut Parser, m: Marker) { 45pub(super) fn enum_def(p: &mut Parser, m: Marker) {
46 assert!(p.at(T![enum])); 46 assert!(p.at(T![enum]));
47 p.bump(); 47 p.bump_any();
48 name_r(p, ITEM_RECOVERY_SET); 48 name_r(p, ITEM_RECOVERY_SET);
49 type_params::opt_type_param_list(p); 49 type_params::opt_type_param_list(p);
50 type_params::opt_where_clause(p); 50 type_params::opt_where_clause(p);
@@ -59,7 +59,7 @@ pub(super) fn enum_def(p: &mut Parser, m: Marker) {
59pub(crate) fn enum_variant_list(p: &mut Parser) { 59pub(crate) fn enum_variant_list(p: &mut Parser) {
60 assert!(p.at(T!['{'])); 60 assert!(p.at(T!['{']));
61 let m = p.start(); 61 let m = p.start();
62 p.bump(); 62 p.bump_any();
63 while !p.at(EOF) && !p.at(T!['}']) { 63 while !p.at(EOF) && !p.at(T!['}']) {
64 if p.at(T!['{']) { 64 if p.at(T!['{']) {
65 error_block(p, "expected enum variant"); 65 error_block(p, "expected enum variant");
@@ -73,7 +73,7 @@ pub(crate) fn enum_variant_list(p: &mut Parser) {
73 T!['{'] => record_field_def_list(p), 73 T!['{'] => record_field_def_list(p),
74 T!['('] => tuple_field_def_list(p), 74 T!['('] => tuple_field_def_list(p),
75 T![=] => { 75 T![=] => {
76 p.bump(); 76 p.bump_any();
77 expressions::expr(p); 77 expressions::expr(p);
78 } 78 }
79 _ => (), 79 _ => (),
@@ -94,7 +94,7 @@ pub(crate) fn enum_variant_list(p: &mut Parser) {
94pub(crate) fn record_field_def_list(p: &mut Parser) { 94pub(crate) fn record_field_def_list(p: &mut Parser) {
95 assert!(p.at(T!['{'])); 95 assert!(p.at(T!['{']));
96 let m = p.start(); 96 let m = p.start();
97 p.bump(); 97 p.bump_any();
98 while !p.at(T!['}']) && !p.at(EOF) { 98 while !p.at(T!['}']) && !p.at(EOF) {
99 if p.at(T!['{']) { 99 if p.at(T!['{']) {
100 error_block(p, "expected field"); 100 error_block(p, "expected field");
diff --git a/crates/ra_parser/src/grammar/items/traits.rs b/crates/ra_parser/src/grammar/items/traits.rs
index 5fcacfbff..b49221a4b 100644
--- a/crates/ra_parser/src/grammar/items/traits.rs
+++ b/crates/ra_parser/src/grammar/items/traits.rs
@@ -5,7 +5,7 @@ use super::*;
5// trait X<U: Debug + Display>: Hash + Clone where U: Copy {} 5// trait X<U: Debug + Display>: Hash + Clone where U: Copy {}
6pub(super) fn trait_def(p: &mut Parser) { 6pub(super) fn trait_def(p: &mut Parser) {
7 assert!(p.at(T![trait])); 7 assert!(p.at(T![trait]));
8 p.bump(); 8 p.bump_any();
9 name_r(p, ITEM_RECOVERY_SET); 9 name_r(p, ITEM_RECOVERY_SET);
10 type_params::opt_type_param_list(p); 10 type_params::opt_type_param_list(p);
11 if p.at(T![:]) { 11 if p.at(T![:]) {
@@ -29,7 +29,7 @@ pub(super) fn trait_def(p: &mut Parser) {
29pub(crate) fn trait_item_list(p: &mut Parser) { 29pub(crate) fn trait_item_list(p: &mut Parser) {
30 assert!(p.at(T!['{'])); 30 assert!(p.at(T!['{']));
31 let m = p.start(); 31 let m = p.start();
32 p.bump(); 32 p.bump_any();
33 while !p.at(EOF) && !p.at(T!['}']) { 33 while !p.at(EOF) && !p.at(T!['}']) {
34 if p.at(T!['{']) { 34 if p.at(T!['{']) {
35 error_block(p, "expected an item"); 35 error_block(p, "expected an item");
@@ -45,7 +45,7 @@ pub(crate) fn trait_item_list(p: &mut Parser) {
45// impl Foo {} 45// impl Foo {}
46pub(super) fn impl_block(p: &mut Parser) { 46pub(super) fn impl_block(p: &mut Parser) {
47 assert!(p.at(T![impl])); 47 assert!(p.at(T![impl]));
48 p.bump(); 48 p.bump_any();
49 if choose_type_params_over_qpath(p) { 49 if choose_type_params_over_qpath(p) {
50 type_params::opt_type_param_list(p); 50 type_params::opt_type_param_list(p);
51 } 51 }
@@ -78,7 +78,7 @@ pub(super) fn impl_block(p: &mut Parser) {
78pub(crate) fn impl_item_list(p: &mut Parser) { 78pub(crate) fn impl_item_list(p: &mut Parser) {
79 assert!(p.at(T!['{'])); 79 assert!(p.at(T!['{']));
80 let m = p.start(); 80 let m = p.start();
81 p.bump(); 81 p.bump_any();
82 // test impl_inner_attributes 82 // test impl_inner_attributes
83 // enum F{} 83 // enum F{}
84 // impl F { 84 // impl F {
diff --git a/crates/ra_parser/src/grammar/items/use_item.rs b/crates/ra_parser/src/grammar/items/use_item.rs
index 83a65e226..f28f522b8 100644
--- a/crates/ra_parser/src/grammar/items/use_item.rs
+++ b/crates/ra_parser/src/grammar/items/use_item.rs
@@ -2,7 +2,7 @@ use super::*;
2 2
3pub(super) fn use_item(p: &mut Parser, m: Marker) { 3pub(super) fn use_item(p: &mut Parser, m: Marker) {
4 assert!(p.at(T![use])); 4 assert!(p.at(T![use]));
5 p.bump(); 5 p.bump_any();
6 use_tree(p); 6 use_tree(p);
7 p.expect(T![;]); 7 p.expect(T![;]);
8 m.complete(p, USE_ITEM); 8 m.complete(p, USE_ITEM);
@@ -13,9 +13,8 @@ pub(super) fn use_item(p: &mut Parser, m: Marker) {
13/// so handles both `some::path::{inner::path}` and `inner::path` in 13/// so handles both `some::path::{inner::path}` and `inner::path` in
14/// `use some::path::{inner::path};` 14/// `use some::path::{inner::path};`
15fn use_tree(p: &mut Parser) { 15fn use_tree(p: &mut Parser) {
16 let la = p.nth(1);
17 let m = p.start(); 16 let m = p.start();
18 match (p.current(), la) { 17 match p.current() {
19 // Finish the use_tree for cases of e.g. 18 // Finish the use_tree for cases of e.g.
20 // `use some::path::{self, *};` or `use *;` 19 // `use some::path::{self, *};` or `use *;`
21 // This does not handle cases such as `use some::path::*` 20 // This does not handle cases such as `use some::path::*`
@@ -28,15 +27,15 @@ fn use_tree(p: &mut Parser) {
28 // use ::*; 27 // use ::*;
29 // use some::path::{*}; 28 // use some::path::{*};
30 // use some::path::{::*}; 29 // use some::path::{::*};
31 (T![*], _) => p.bump(), 30 T![*] => p.bump(T![*]),
32 (T![::], T![*]) => { 31 T![:] if p.at(T![::]) && p.nth(2) == T![*] => {
33 // Parse `use ::*;`, which imports all from the crate root in Rust 2015 32 // Parse `use ::*;`, which imports all from the crate root in Rust 2015
34 // This is invalid inside a use_tree_list, (e.g. `use some::path::{::*}`) 33 // This is invalid inside a use_tree_list, (e.g. `use some::path::{::*}`)
35 // but still parses and errors later: ('crate root in paths can only be used in start position') 34 // but still parses and errors later: ('crate root in paths can only be used in start position')
36 // FIXME: Add this error (if not out of scope) 35 // FIXME: Add this error (if not out of scope)
37 // In Rust 2018, it is always invalid (see above) 36 // In Rust 2018, it is always invalid (see above)
38 p.bump(); 37 p.bump(T![::]);
39 p.bump(); 38 p.bump(T![*]);
40 } 39 }
41 // Open a use tree list 40 // Open a use tree list
42 // Handles cases such as `use {some::path};` or `{inner::path}` in 41 // Handles cases such as `use {some::path};` or `{inner::path}` in
@@ -47,10 +46,11 @@ fn use_tree(p: &mut Parser) {
47 // use {path::from::root}; // Rust 2015 46 // use {path::from::root}; // Rust 2015
48 // use ::{some::arbritrary::path}; // Rust 2015 47 // use ::{some::arbritrary::path}; // Rust 2015
49 // use ::{{{crate::export}}}; // Nonsensical but perfectly legal nestnig 48 // use ::{{{crate::export}}}; // Nonsensical but perfectly legal nestnig
50 (T!['{'], _) | (T![::], T!['{']) => { 49 T!['{'] => {
51 if p.at(T![::]) { 50 use_tree_list(p);
52 p.bump(); 51 }
53 } 52 T![:] if p.at(T![::]) && p.nth(2) == T!['{'] => {
53 p.bump(T![::]);
54 use_tree_list(p); 54 use_tree_list(p);
55 } 55 }
56 // Parse a 'standard' path. 56 // Parse a 'standard' path.
@@ -80,11 +80,11 @@ fn use_tree(p: &mut Parser) {
80 // use Trait as _; 80 // use Trait as _;
81 opt_alias(p); 81 opt_alias(p);
82 } 82 }
83 T![::] => { 83 T![:] if p.at(T![::]) => {
84 p.bump(); 84 p.bump(T![::]);
85 match p.current() { 85 match p.current() {
86 T![*] => { 86 T![*] => {
87 p.bump(); 87 p.bump_any();
88 } 88 }
89 // test use_tree_list_after_path 89 // test use_tree_list_after_path
90 // use crate::{Item}; 90 // use crate::{Item};
@@ -114,7 +114,7 @@ fn use_tree(p: &mut Parser) {
114pub(crate) fn use_tree_list(p: &mut Parser) { 114pub(crate) fn use_tree_list(p: &mut Parser) {
115 assert!(p.at(T!['{'])); 115 assert!(p.at(T!['{']));
116 let m = p.start(); 116 let m = p.start();
117 p.bump(); 117 p.bump_any();
118 while !p.at(EOF) && !p.at(T!['}']) { 118 while !p.at(EOF) && !p.at(T!['}']) {
119 use_tree(p); 119 use_tree(p);
120 if !p.at(T!['}']) { 120 if !p.at(T!['}']) {
diff --git a/crates/ra_parser/src/grammar/params.rs b/crates/ra_parser/src/grammar/params.rs
index 0b09f1874..5893b22fd 100644
--- a/crates/ra_parser/src/grammar/params.rs
+++ b/crates/ra_parser/src/grammar/params.rs
@@ -39,7 +39,7 @@ fn list_(p: &mut Parser, flavor: Flavor) {
39 let (bra, ket) = if flavor.type_required() { (T!['('], T![')']) } else { (T![|], T![|]) }; 39 let (bra, ket) = if flavor.type_required() { (T!['('], T![')']) } else { (T![|], T![|]) };
40 assert!(p.at(bra)); 40 assert!(p.at(bra));
41 let m = p.start(); 41 let m = p.start();
42 p.bump(); 42 p.bump_any();
43 if flavor.type_required() { 43 if flavor.type_required() {
44 // test self_param_outer_attr 44 // test self_param_outer_attr
45 // fn f(#[must_use] self) {} 45 // fn f(#[must_use] self) {}
@@ -80,7 +80,7 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) {
80 match flavor { 80 match flavor {
81 Flavor::OptionalType | Flavor::Normal => { 81 Flavor::OptionalType | Flavor::Normal => {
82 patterns::pattern(p); 82 patterns::pattern(p);
83 if p.at(T![:]) || flavor.type_required() { 83 if p.at(T![:]) && !p.at(T![::]) || flavor.type_required() {
84 types::ascription(p) 84 types::ascription(p)
85 } 85 }
86 } 86 }
@@ -96,10 +96,11 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) {
96 // trait Foo { 96 // trait Foo {
97 // fn bar(_: u64, mut x: i32); 97 // fn bar(_: u64, mut x: i32);
98 // } 98 // }
99 if (la0 == IDENT || la0 == T![_]) && la1 == T![:] 99 if (la0 == IDENT || la0 == T![_]) && la1 == T![:] && !p.nth_at(1, T![::])
100 || la0 == T![mut] && la1 == IDENT && la2 == T![:] 100 || la0 == T![mut] && la1 == IDENT && la2 == T![:]
101 || la0 == T![&] && la1 == IDENT && la2 == T![:] 101 || la0 == T![&]
102 || la0 == T![&] && la1 == T![mut] && la2 == IDENT && la3 == T![:] 102 && (la1 == IDENT && la2 == T![:] && !p.nth_at(2, T![::])
103 || la1 == T![mut] && la2 == IDENT && la3 == T![:] && !p.nth_at(3, T![::]))
103 { 104 {
104 patterns::pattern(p); 105 patterns::pattern(p);
105 types::ascription(p); 106 types::ascription(p);
@@ -146,7 +147,7 @@ fn opt_self_param(p: &mut Parser) {
146 }; 147 };
147 m = p.start(); 148 m = p.start();
148 for _ in 0..n_toks { 149 for _ in 0..n_toks {
149 p.bump(); 150 p.bump_any();
150 } 151 }
151 } 152 }
152 m.complete(p, SELF_PARAM); 153 m.complete(p, SELF_PARAM);
diff --git a/crates/ra_parser/src/grammar/paths.rs b/crates/ra_parser/src/grammar/paths.rs
index 28c35a67d..24b65128e 100644
--- a/crates/ra_parser/src/grammar/paths.rs
+++ b/crates/ra_parser/src/grammar/paths.rs
@@ -1,7 +1,7 @@
1use super::*; 1use super::*;
2 2
3pub(super) const PATH_FIRST: TokenSet = 3pub(super) const PATH_FIRST: TokenSet =
4 token_set![IDENT, SELF_KW, SUPER_KW, CRATE_KW, COLONCOLON, L_ANGLE]; 4 token_set![IDENT, SELF_KW, SUPER_KW, CRATE_KW, COLON, L_ANGLE];
5 5
6pub(super) fn is_path_start(p: &Parser) -> bool { 6pub(super) fn is_path_start(p: &Parser) -> bool {
7 is_use_path_start(p) || p.at(T![<]) 7 is_use_path_start(p) || p.at(T![<])
@@ -9,7 +9,8 @@ pub(super) fn is_path_start(p: &Parser) -> bool {
9 9
10pub(super) fn is_use_path_start(p: &Parser) -> bool { 10pub(super) fn is_use_path_start(p: &Parser) -> bool {
11 match p.current() { 11 match p.current() {
12 IDENT | T![self] | T![super] | T![crate] | T![::] => true, 12 IDENT | T![self] | T![super] | T![crate] => true,
13 T![:] if p.at(T![::]) => true,
13 _ => false, 14 _ => false,
14 } 15 }
15} 16}
@@ -38,13 +39,13 @@ fn path(p: &mut Parser, mode: Mode) {
38 path_segment(p, mode, true); 39 path_segment(p, mode, true);
39 let mut qual = path.complete(p, PATH); 40 let mut qual = path.complete(p, PATH);
40 loop { 41 loop {
41 let use_tree = match p.nth(1) { 42 let use_tree = match p.nth(2) {
42 T![*] | T!['{'] => true, 43 T![*] | T!['{'] => true,
43 _ => false, 44 _ => false,
44 }; 45 };
45 if p.at(T![::]) && !use_tree { 46 if p.at(T![::]) && !use_tree {
46 let path = qual.precede(p); 47 let path = qual.precede(p);
47 p.bump(); 48 p.bump(T![::]);
48 path_segment(p, mode, false); 49 path_segment(p, mode, false);
49 let path = path.complete(p, PATH); 50 let path = path.complete(p, PATH);
50 qual = path; 51 qual = path;
@@ -80,7 +81,7 @@ fn path_segment(p: &mut Parser, mode: Mode, first: bool) {
80 } 81 }
81 // test crate_path 82 // test crate_path
82 // use crate::foo; 83 // use crate::foo;
83 T![self] | T![super] | T![crate] => p.bump(), 84 T![self] | T![super] | T![crate] => p.bump_any(),
84 _ => { 85 _ => {
85 p.err_recover("expected identifier", items::ITEM_RECOVERY_SET); 86 p.err_recover("expected identifier", items::ITEM_RECOVERY_SET);
86 } 87 }
diff --git a/crates/ra_parser/src/grammar/patterns.rs b/crates/ra_parser/src/grammar/patterns.rs
index 32cde7de6..dd1d25b07 100644
--- a/crates/ra_parser/src/grammar/patterns.rs
+++ b/crates/ra_parser/src/grammar/patterns.rs
@@ -34,17 +34,20 @@ pub(super) fn pattern_r(p: &mut Parser, recovery_set: TokenSet) {
34 // 200 .. 301=> (), 34 // 200 .. 301=> (),
35 // } 35 // }
36 // } 36 // }
37 if p.at(T![...]) || p.at(T![..=]) || p.at(T![..]) { 37 for &range_op in [T![...], T![..=], T![..]].iter() {
38 let m = lhs.precede(p); 38 if p.at(range_op) {
39 p.bump(); 39 let m = lhs.precede(p);
40 atom_pat(p, recovery_set); 40 p.bump(range_op);
41 m.complete(p, RANGE_PAT); 41 atom_pat(p, recovery_set);
42 m.complete(p, RANGE_PAT);
43 return;
44 }
42 } 45 }
43 // test marco_pat 46 // test marco_pat
44 // fn main() { 47 // fn main() {
45 // let m!(x) = 0; 48 // let m!(x) = 0;
46 // } 49 // }
47 else if lhs.kind() == PATH_PAT && p.at(T![!]) { 50 if lhs.kind() == PATH_PAT && p.at(T![!]) {
48 let m = lhs.precede(p); 51 let m = lhs.precede(p);
49 items::macro_call_after_excl(p); 52 items::macro_call_after_excl(p);
50 m.complete(p, MACRO_CALL); 53 m.complete(p, MACRO_CALL);
@@ -56,14 +59,16 @@ const PAT_RECOVERY_SET: TokenSet =
56 token_set![LET_KW, IF_KW, WHILE_KW, LOOP_KW, MATCH_KW, R_PAREN, COMMA]; 59 token_set![LET_KW, IF_KW, WHILE_KW, LOOP_KW, MATCH_KW, R_PAREN, COMMA];
57 60
58fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> { 61fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> {
59 // Checks the token after an IDENT to see if a pattern is a path (Struct { .. }) or macro
60 // (T![x]).
61 let is_path_or_macro_pat =
62 |la1| la1 == T![::] || la1 == T!['('] || la1 == T!['{'] || la1 == T![!];
63
64 let m = match p.nth(0) { 62 let m = match p.nth(0) {
65 T![box] => box_pat(p), 63 T![box] => box_pat(p),
66 T![ref] | T![mut] | IDENT if !is_path_or_macro_pat(p.nth(1)) => bind_pat(p, true), 64 T![ref] | T![mut] => bind_pat(p, true),
65 IDENT => match p.nth(1) {
66 // Checks the token after an IDENT to see if a pattern is a path (Struct { .. }) or macro
67 // (T![x]).
68 T!['('] | T!['{'] | T![!] => path_pat(p),
69 T![:] if p.nth_at(1, T![::]) => path_pat(p),
70 _ => bind_pat(p, true),
71 },
67 72
68 _ if paths::is_use_path_start(p) => path_pat(p), 73 _ if paths::is_use_path_start(p) => path_pat(p),
69 _ if is_literal_pat_start(p) => literal_pat(p), 74 _ if is_literal_pat_start(p) => literal_pat(p),
@@ -100,7 +105,7 @@ fn literal_pat(p: &mut Parser) -> CompletedMarker {
100 assert!(is_literal_pat_start(p)); 105 assert!(is_literal_pat_start(p));
101 let m = p.start(); 106 let m = p.start();
102 if p.at(T![-]) { 107 if p.at(T![-]) {
103 p.bump(); 108 p.bump_any();
104 } 109 }
105 expressions::literal(p); 110 expressions::literal(p);
106 m.complete(p, LITERAL_PAT) 111 m.complete(p, LITERAL_PAT)
@@ -140,7 +145,7 @@ fn path_pat(p: &mut Parser) -> CompletedMarker {
140// } 145// }
141fn tuple_pat_fields(p: &mut Parser) { 146fn tuple_pat_fields(p: &mut Parser) {
142 assert!(p.at(T!['('])); 147 assert!(p.at(T!['(']));
143 p.bump(); 148 p.bump_any();
144 pat_list(p, T![')']); 149 pat_list(p, T![')']);
145 p.expect(T![')']); 150 p.expect(T![')']);
146} 151}
@@ -155,10 +160,10 @@ fn tuple_pat_fields(p: &mut Parser) {
155fn record_field_pat_list(p: &mut Parser) { 160fn record_field_pat_list(p: &mut Parser) {
156 assert!(p.at(T!['{'])); 161 assert!(p.at(T!['{']));
157 let m = p.start(); 162 let m = p.start();
158 p.bump(); 163 p.bump_any();
159 while !p.at(EOF) && !p.at(T!['}']) { 164 while !p.at(EOF) && !p.at(T!['}']) {
160 match p.current() { 165 match p.current() {
161 T![..] => p.bump(), 166 T![.] if p.at(T![..]) => p.bump(T![..]),
162 IDENT if p.nth(1) == T![:] => record_field_pat(p), 167 IDENT if p.nth(1) == T![:] => record_field_pat(p),
163 T!['{'] => error_block(p, "expected ident"), 168 T!['{'] => error_block(p, "expected ident"),
164 T![box] => { 169 T![box] => {
@@ -182,7 +187,7 @@ fn record_field_pat(p: &mut Parser) {
182 187
183 let m = p.start(); 188 let m = p.start();
184 name(p); 189 name(p);
185 p.bump(); 190 p.bump_any();
186 pattern(p); 191 pattern(p);
187 m.complete(p, RECORD_FIELD_PAT); 192 m.complete(p, RECORD_FIELD_PAT);
188} 193}
@@ -192,7 +197,7 @@ fn record_field_pat(p: &mut Parser) {
192fn placeholder_pat(p: &mut Parser) -> CompletedMarker { 197fn placeholder_pat(p: &mut Parser) -> CompletedMarker {
193 assert!(p.at(T![_])); 198 assert!(p.at(T![_]));
194 let m = p.start(); 199 let m = p.start();
195 p.bump(); 200 p.bump_any();
196 m.complete(p, PLACEHOLDER_PAT) 201 m.complete(p, PLACEHOLDER_PAT)
197} 202}
198 203
@@ -204,7 +209,7 @@ fn placeholder_pat(p: &mut Parser) -> CompletedMarker {
204fn ref_pat(p: &mut Parser) -> CompletedMarker { 209fn ref_pat(p: &mut Parser) -> CompletedMarker {
205 assert!(p.at(T![&])); 210 assert!(p.at(T![&]));
206 let m = p.start(); 211 let m = p.start();
207 p.bump(); 212 p.bump_any();
208 p.eat(T![mut]); 213 p.eat(T![mut]);
209 pattern(p); 214 pattern(p);
210 m.complete(p, REF_PAT) 215 m.complete(p, REF_PAT)
@@ -228,7 +233,7 @@ fn tuple_pat(p: &mut Parser) -> CompletedMarker {
228fn slice_pat(p: &mut Parser) -> CompletedMarker { 233fn slice_pat(p: &mut Parser) -> CompletedMarker {
229 assert!(p.at(T!['['])); 234 assert!(p.at(T!['[']));
230 let m = p.start(); 235 let m = p.start();
231 p.bump(); 236 p.bump_any();
232 pat_list(p, T![']']); 237 pat_list(p, T![']']);
233 p.expect(T![']']); 238 p.expect(T![']']);
234 m.complete(p, SLICE_PAT) 239 m.complete(p, SLICE_PAT)
@@ -237,7 +242,7 @@ fn slice_pat(p: &mut Parser) -> CompletedMarker {
237fn pat_list(p: &mut Parser, ket: SyntaxKind) { 242fn pat_list(p: &mut Parser, ket: SyntaxKind) {
238 while !p.at(EOF) && !p.at(ket) { 243 while !p.at(EOF) && !p.at(ket) {
239 match p.current() { 244 match p.current() {
240 T![..] => p.bump(), 245 T![.] if p.at(T![..]) => p.bump(T![..]),
241 _ => { 246 _ => {
242 if !p.at_ts(PATTERN_FIRST) { 247 if !p.at_ts(PATTERN_FIRST) {
243 p.error("expected a pattern"); 248 p.error("expected a pattern");
@@ -281,7 +286,7 @@ fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker {
281fn box_pat(p: &mut Parser) -> CompletedMarker { 286fn box_pat(p: &mut Parser) -> CompletedMarker {
282 assert!(p.at(T![box])); 287 assert!(p.at(T![box]));
283 let m = p.start(); 288 let m = p.start();
284 p.bump(); 289 p.bump_any();
285 pattern(p); 290 pattern(p);
286 m.complete(p, BOX_PAT) 291 m.complete(p, BOX_PAT)
287} 292}
diff --git a/crates/ra_parser/src/grammar/type_args.rs b/crates/ra_parser/src/grammar/type_args.rs
index 3db08b280..edc7d4ff2 100644
--- a/crates/ra_parser/src/grammar/type_args.rs
+++ b/crates/ra_parser/src/grammar/type_args.rs
@@ -2,19 +2,16 @@ use super::*;
2 2
3pub(super) fn opt_type_arg_list(p: &mut Parser, colon_colon_required: bool) { 3pub(super) fn opt_type_arg_list(p: &mut Parser, colon_colon_required: bool) {
4 let m; 4 let m;
5 match (colon_colon_required, p.nth(0), p.nth(1)) { 5 if p.at(T![::]) && p.nth(2) == T![<] {
6 (_, T![::], T![<]) => { 6 m = p.start();
7 m = p.start(); 7 p.bump(T![::]);
8 p.bump(); 8 p.bump(T![<]);
9 p.bump(); 9 } else if !colon_colon_required && p.at(T![<]) && p.nth(1) != T![=] {
10 } 10 m = p.start();
11 (false, T![<], T![=]) => return, 11 p.bump(T![<]);
12 (false, T![<], _) => { 12 } else {
13 m = p.start(); 13 return;
14 p.bump(); 14 }
15 }
16 _ => return,
17 };
18 15
19 while !p.at(EOF) && !p.at(T![>]) { 16 while !p.at(EOF) && !p.at(T![>]) {
20 type_arg(p); 17 type_arg(p);
@@ -32,19 +29,19 @@ fn type_arg(p: &mut Parser) {
32 let m = p.start(); 29 let m = p.start();
33 match p.current() { 30 match p.current() {
34 LIFETIME => { 31 LIFETIME => {
35 p.bump(); 32 p.bump_any();
36 m.complete(p, LIFETIME_ARG); 33 m.complete(p, LIFETIME_ARG);
37 } 34 }
38 // test associated_type_bounds 35 // test associated_type_bounds
39 // fn print_all<T: Iterator<Item: Display>>(printables: T) {} 36 // fn print_all<T: Iterator<Item: Display>>(printables: T) {}
40 IDENT if p.nth(1) == T![:] => { 37 IDENT if p.nth(1) == T![:] && p.nth(2) != T![:] => {
41 name_ref(p); 38 name_ref(p);
42 type_params::bounds(p); 39 type_params::bounds(p);
43 m.complete(p, ASSOC_TYPE_ARG); 40 m.complete(p, ASSOC_TYPE_ARG);
44 } 41 }
45 IDENT if p.nth(1) == T![=] => { 42 IDENT if p.nth(1) == T![=] => {
46 name_ref(p); 43 name_ref(p);
47 p.bump(); 44 p.bump_any();
48 types::type_(p); 45 types::type_(p);
49 m.complete(p, ASSOC_TYPE_ARG); 46 m.complete(p, ASSOC_TYPE_ARG);
50 } 47 }
diff --git a/crates/ra_parser/src/grammar/type_params.rs b/crates/ra_parser/src/grammar/type_params.rs
index cf54344c6..31d709d81 100644
--- a/crates/ra_parser/src/grammar/type_params.rs
+++ b/crates/ra_parser/src/grammar/type_params.rs
@@ -10,7 +10,7 @@ pub(super) fn opt_type_param_list(p: &mut Parser) {
10fn type_param_list(p: &mut Parser) { 10fn type_param_list(p: &mut Parser) {
11 assert!(p.at(T![<])); 11 assert!(p.at(T![<]));
12 let m = p.start(); 12 let m = p.start();
13 p.bump(); 13 p.bump_any();
14 14
15 while !p.at(EOF) && !p.at(T![>]) { 15 while !p.at(EOF) && !p.at(T![>]) {
16 let m = p.start(); 16 let m = p.start();
@@ -38,7 +38,7 @@ fn type_param_list(p: &mut Parser) {
38 38
39fn lifetime_param(p: &mut Parser, m: Marker) { 39fn lifetime_param(p: &mut Parser, m: Marker) {
40 assert!(p.at(LIFETIME)); 40 assert!(p.at(LIFETIME));
41 p.bump(); 41 p.bump_any();
42 if p.at(T![:]) { 42 if p.at(T![:]) {
43 lifetime_bounds(p); 43 lifetime_bounds(p);
44 } 44 }
@@ -54,7 +54,7 @@ fn type_param(p: &mut Parser, m: Marker) {
54 // test type_param_default 54 // test type_param_default
55 // struct S<T = i32>; 55 // struct S<T = i32>;
56 if p.at(T![=]) { 56 if p.at(T![=]) {
57 p.bump(); 57 p.bump_any();
58 types::type_(p) 58 types::type_(p)
59 } 59 }
60 m.complete(p, TYPE_PARAM); 60 m.complete(p, TYPE_PARAM);
@@ -64,15 +64,15 @@ fn type_param(p: &mut Parser, m: Marker) {
64// struct S<T: 'a + ?Sized + (Copy)>; 64// struct S<T: 'a + ?Sized + (Copy)>;
65pub(super) fn bounds(p: &mut Parser) { 65pub(super) fn bounds(p: &mut Parser) {
66 assert!(p.at(T![:])); 66 assert!(p.at(T![:]));
67 p.bump(); 67 p.bump_any();
68 bounds_without_colon(p); 68 bounds_without_colon(p);
69} 69}
70 70
71fn lifetime_bounds(p: &mut Parser) { 71fn lifetime_bounds(p: &mut Parser) {
72 assert!(p.at(T![:])); 72 assert!(p.at(T![:]));
73 p.bump(); 73 p.bump_any();
74 while p.at(LIFETIME) { 74 while p.at(LIFETIME) {
75 p.bump(); 75 p.bump_any();
76 if !p.eat(T![+]) { 76 if !p.eat(T![+]) {
77 break; 77 break;
78 } 78 }
@@ -99,7 +99,7 @@ fn type_bound(p: &mut Parser) -> bool {
99 let has_paren = p.eat(T!['(']); 99 let has_paren = p.eat(T!['(']);
100 p.eat(T![?]); 100 p.eat(T![?]);
101 match p.current() { 101 match p.current() {
102 LIFETIME => p.bump(), 102 LIFETIME => p.bump_any(),
103 T![for] => types::for_type(p), 103 T![for] => types::for_type(p),
104 _ if paths::is_use_path_start(p) => types::path_type_(p, false), 104 _ if paths::is_use_path_start(p) => types::path_type_(p, false),
105 _ => { 105 _ => {
@@ -128,7 +128,7 @@ pub(super) fn opt_where_clause(p: &mut Parser) {
128 return; 128 return;
129 } 129 }
130 let m = p.start(); 130 let m = p.start();
131 p.bump(); 131 p.bump_any();
132 132
133 while is_where_predicate(p) { 133 while is_where_predicate(p) {
134 where_predicate(p); 134 where_predicate(p);
@@ -166,7 +166,7 @@ fn where_predicate(p: &mut Parser) {
166 let m = p.start(); 166 let m = p.start();
167 match p.current() { 167 match p.current() {
168 LIFETIME => { 168 LIFETIME => {
169 p.bump(); 169 p.bump_any();
170 if p.at(T![:]) { 170 if p.at(T![:]) {
171 bounds(p); 171 bounds(p);
172 } else { 172 } else {
diff --git a/crates/ra_parser/src/grammar/types.rs b/crates/ra_parser/src/grammar/types.rs
index 9e321b2a6..0eb28ef09 100644
--- a/crates/ra_parser/src/grammar/types.rs
+++ b/crates/ra_parser/src/grammar/types.rs
@@ -44,7 +44,7 @@ pub(super) fn ascription(p: &mut Parser) {
44fn paren_or_tuple_type(p: &mut Parser) { 44fn paren_or_tuple_type(p: &mut Parser) {
45 assert!(p.at(T!['('])); 45 assert!(p.at(T!['(']));
46 let m = p.start(); 46 let m = p.start();
47 p.bump(); 47 p.bump_any();
48 let mut n_types: u32 = 0; 48 let mut n_types: u32 = 0;
49 let mut trailing_comma: bool = false; 49 let mut trailing_comma: bool = false;
50 while !p.at(EOF) && !p.at(T![')']) { 50 while !p.at(EOF) && !p.at(T![')']) {
@@ -79,20 +79,20 @@ fn paren_or_tuple_type(p: &mut Parser) {
79fn never_type(p: &mut Parser) { 79fn never_type(p: &mut Parser) {
80 assert!(p.at(T![!])); 80 assert!(p.at(T![!]));
81 let m = p.start(); 81 let m = p.start();
82 p.bump(); 82 p.bump_any();
83 m.complete(p, NEVER_TYPE); 83 m.complete(p, NEVER_TYPE);
84} 84}
85 85
86fn pointer_type(p: &mut Parser) { 86fn pointer_type(p: &mut Parser) {
87 assert!(p.at(T![*])); 87 assert!(p.at(T![*]));
88 let m = p.start(); 88 let m = p.start();
89 p.bump(); 89 p.bump_any();
90 90
91 match p.current() { 91 match p.current() {
92 // test pointer_type_mut 92 // test pointer_type_mut
93 // type M = *mut (); 93 // type M = *mut ();
94 // type C = *mut (); 94 // type C = *mut ();
95 T![mut] | T![const] => p.bump(), 95 T![mut] | T![const] => p.bump_any(),
96 _ => { 96 _ => {
97 // test_err pointer_type_no_mutability 97 // test_err pointer_type_no_mutability
98 // type T = *(); 98 // type T = *();
@@ -110,21 +110,21 @@ fn pointer_type(p: &mut Parser) {
110fn array_or_slice_type(p: &mut Parser) { 110fn array_or_slice_type(p: &mut Parser) {
111 assert!(p.at(T!['['])); 111 assert!(p.at(T!['[']));
112 let m = p.start(); 112 let m = p.start();
113 p.bump(); 113 p.bump_any();
114 114
115 type_(p); 115 type_(p);
116 let kind = match p.current() { 116 let kind = match p.current() {
117 // test slice_type 117 // test slice_type
118 // type T = [()]; 118 // type T = [()];
119 T![']'] => { 119 T![']'] => {
120 p.bump(); 120 p.bump_any();
121 SLICE_TYPE 121 SLICE_TYPE
122 } 122 }
123 123
124 // test array_type 124 // test array_type
125 // type T = [(); 92]; 125 // type T = [(); 92];
126 T![;] => { 126 T![;] => {
127 p.bump(); 127 p.bump_any();
128 expressions::expr(p); 128 expressions::expr(p);
129 p.expect(T![']']); 129 p.expect(T![']']);
130 ARRAY_TYPE 130 ARRAY_TYPE
@@ -146,7 +146,7 @@ fn array_or_slice_type(p: &mut Parser) {
146fn reference_type(p: &mut Parser) { 146fn reference_type(p: &mut Parser) {
147 assert!(p.at(T![&])); 147 assert!(p.at(T![&]));
148 let m = p.start(); 148 let m = p.start();
149 p.bump(); 149 p.bump_any();
150 p.eat(LIFETIME); 150 p.eat(LIFETIME);
151 p.eat(T![mut]); 151 p.eat(T![mut]);
152 type_no_bounds(p); 152 type_no_bounds(p);
@@ -158,7 +158,7 @@ fn reference_type(p: &mut Parser) {
158fn placeholder_type(p: &mut Parser) { 158fn placeholder_type(p: &mut Parser) {
159 assert!(p.at(T![_])); 159 assert!(p.at(T![_]));
160 let m = p.start(); 160 let m = p.start();
161 p.bump(); 161 p.bump_any();
162 m.complete(p, PLACEHOLDER_TYPE); 162 m.complete(p, PLACEHOLDER_TYPE);
163} 163}
164 164
@@ -193,7 +193,7 @@ fn fn_pointer_type(p: &mut Parser) {
193 193
194pub(super) fn for_binder(p: &mut Parser) { 194pub(super) fn for_binder(p: &mut Parser) {
195 assert!(p.at(T![for])); 195 assert!(p.at(T![for]));
196 p.bump(); 196 p.bump_any();
197 if p.at(T![<]) { 197 if p.at(T![<]) {
198 type_params::opt_type_param_list(p); 198 type_params::opt_type_param_list(p);
199 } else { 199 } else {
@@ -224,7 +224,7 @@ pub(super) fn for_type(p: &mut Parser) {
224fn impl_trait_type(p: &mut Parser) { 224fn impl_trait_type(p: &mut Parser) {
225 assert!(p.at(T![impl])); 225 assert!(p.at(T![impl]));
226 let m = p.start(); 226 let m = p.start();
227 p.bump(); 227 p.bump_any();
228 type_params::bounds_without_colon(p); 228 type_params::bounds_without_colon(p);
229 m.complete(p, IMPL_TRAIT_TYPE); 229 m.complete(p, IMPL_TRAIT_TYPE);
230} 230}
@@ -234,7 +234,7 @@ fn impl_trait_type(p: &mut Parser) {
234fn dyn_trait_type(p: &mut Parser) { 234fn dyn_trait_type(p: &mut Parser) {
235 assert!(p.at(T![dyn ])); 235 assert!(p.at(T![dyn ]));
236 let m = p.start(); 236 let m = p.start();
237 p.bump(); 237 p.bump_any();
238 type_params::bounds_without_colon(p); 238 type_params::bounds_without_colon(p);
239 m.complete(p, DYN_TRAIT_TYPE); 239 m.complete(p, DYN_TRAIT_TYPE);
240} 240}
diff --git a/crates/ra_parser/src/parser.rs b/crates/ra_parser/src/parser.rs
index 393586561..a2ac363fb 100644
--- a/crates/ra_parser/src/parser.rs
+++ b/crates/ra_parser/src/parser.rs
@@ -5,8 +5,8 @@ use drop_bomb::DropBomb;
5use crate::{ 5use crate::{
6 event::Event, 6 event::Event,
7 ParseError, 7 ParseError,
8 SyntaxKind::{self, EOF, ERROR, TOMBSTONE}, 8 SyntaxKind::{self, EOF, ERROR, L_DOLLAR, R_DOLLAR, TOMBSTONE},
9 Token, TokenSet, TokenSource, T, 9 TokenSet, TokenSource, T,
10}; 10};
11 11
12/// `Parser` struct provides the low-level API for 12/// `Parser` struct provides the low-level API for
@@ -40,38 +40,6 @@ impl<'t> Parser<'t> {
40 self.nth(0) 40 self.nth(0)
41 } 41 }
42 42
43 /// Returns the kinds of the current two tokens, if they are not separated
44 /// by trivia.
45 ///
46 /// Useful for parsing things like `>>`.
47 pub(crate) fn current2(&self) -> Option<(SyntaxKind, SyntaxKind)> {
48 let c1 = self.nth(0);
49 let c2 = self.nth(1);
50
51 if self.token_source.current().is_jointed_to_next {
52 Some((c1, c2))
53 } else {
54 None
55 }
56 }
57
58 /// Returns the kinds of the current three tokens, if they are not separated
59 /// by trivia.
60 ///
61 /// Useful for parsing things like `=>>`.
62 pub(crate) fn current3(&self) -> Option<(SyntaxKind, SyntaxKind, SyntaxKind)> {
63 let c1 = self.nth(0);
64 let c2 = self.nth(1);
65 let c3 = self.nth(2);
66 if self.token_source.current().is_jointed_to_next
67 && self.token_source.lookahead_nth(1).is_jointed_to_next
68 {
69 Some((c1, c2, c3))
70 } else {
71 None
72 }
73 }
74
75 /// Lookahead operation: returns the kind of the next nth 43 /// Lookahead operation: returns the kind of the next nth
76 /// token. 44 /// token.
77 pub(crate) fn nth(&self, n: usize) -> SyntaxKind { 45 pub(crate) fn nth(&self, n: usize) -> SyntaxKind {
@@ -81,33 +49,93 @@ impl<'t> Parser<'t> {
81 assert!(steps <= 10_000_000, "the parser seems stuck"); 49 assert!(steps <= 10_000_000, "the parser seems stuck");
82 self.steps.set(steps + 1); 50 self.steps.set(steps + 1);
83 51
84 // It is beecause the Dollar will appear between nth 52 self.token_source.lookahead_nth(n).kind
85 // Following code skips through it
86 let mut non_dollars_count = 0;
87 let mut i = 0;
88
89 loop {
90 let token = self.token_source.lookahead_nth(i);
91 let mut kind = token.kind;
92 if let Some((composited, step)) = self.is_composite(token, i) {
93 kind = composited;
94 i += step;
95 } else {
96 i += 1;
97 }
98
99 match kind {
100 EOF => return EOF,
101 SyntaxKind::L_DOLLAR | SyntaxKind::R_DOLLAR => {}
102 _ if non_dollars_count == n => return kind,
103 _ => non_dollars_count += 1,
104 }
105 }
106 } 53 }
107 54
108 /// Checks if the current token is `kind`. 55 /// Checks if the current token is `kind`.
109 pub(crate) fn at(&self, kind: SyntaxKind) -> bool { 56 pub(crate) fn at(&self, kind: SyntaxKind) -> bool {
110 self.current() == kind 57 self.nth_at(0, kind)
58 }
59
60 pub(crate) fn nth_at(&self, n: usize, kind: SyntaxKind) -> bool {
61 match kind {
62 T![-=] => self.at_composite2(n, T![-], T![=]),
63 T![->] => self.at_composite2(n, T![-], T![>]),
64 T![::] => self.at_composite2(n, T![:], T![:]),
65 T![!=] => self.at_composite2(n, T![!], T![=]),
66 T![..] => self.at_composite2(n, T![.], T![.]),
67 T![*=] => self.at_composite2(n, T![*], T![=]),
68 T![/=] => self.at_composite2(n, T![/], T![=]),
69 T![&&] => self.at_composite2(n, T![&], T![&]),
70 T![&=] => self.at_composite2(n, T![&], T![=]),
71 T![%=] => self.at_composite2(n, T![%], T![=]),
72 T![^=] => self.at_composite2(n, T![^], T![=]),
73 T![+=] => self.at_composite2(n, T![+], T![=]),
74 T![<<] => self.at_composite2(n, T![<], T![<]),
75 T![<=] => self.at_composite2(n, T![<], T![=]),
76 T![==] => self.at_composite2(n, T![=], T![=]),
77 T![=>] => self.at_composite2(n, T![=], T![>]),
78 T![>=] => self.at_composite2(n, T![>], T![=]),
79 T![>>] => self.at_composite2(n, T![>], T![>]),
80 T![|=] => self.at_composite2(n, T![|], T![=]),
81 T![||] => self.at_composite2(n, T![|], T![|]),
82
83 T![...] => self.at_composite3(n, T![.], T![.], T![.]),
84 T![..=] => self.at_composite3(n, T![.], T![.], T![=]),
85 T![<<=] => self.at_composite3(n, T![<], T![<], T![=]),
86 T![>>=] => self.at_composite3(n, T![>], T![>], T![=]),
87
88 _ => self.token_source.lookahead_nth(n).kind == kind,
89 }
90 }
91
92 /// Consume the next token if `kind` matches.
93 pub(crate) fn eat(&mut self, kind: SyntaxKind) -> bool {
94 if !self.at(kind) {
95 return false;
96 }
97 let n_raw_tokens = match kind {
98 T![-=]
99 | T![->]
100 | T![::]
101 | T![!=]
102 | T![..]
103 | T![*=]
104 | T![/=]
105 | T![&&]
106 | T![&=]
107 | T![%=]
108 | T![^=]
109 | T![+=]
110 | T![<<]
111 | T![<=]
112 | T![==]
113 | T![=>]
114 | T![>=]
115 | T![>>]
116 | T![|=]
117 | T![||] => 2,
118
119 T![...] | T![..=] | T![<<=] | T![>>=] => 3,
120 _ => 1,
121 };
122 self.do_bump(kind, n_raw_tokens);
123 true
124 }
125
126 fn at_composite2(&self, n: usize, k1: SyntaxKind, k2: SyntaxKind) -> bool {
127 let t1 = self.token_source.lookahead_nth(n + 0);
128 let t2 = self.token_source.lookahead_nth(n + 1);
129 t1.kind == k1 && t1.is_jointed_to_next && t2.kind == k2
130 }
131
132 fn at_composite3(&self, n: usize, k1: SyntaxKind, k2: SyntaxKind, k3: SyntaxKind) -> bool {
133 let t1 = self.token_source.lookahead_nth(n + 0);
134 let t2 = self.token_source.lookahead_nth(n + 1);
135 let t3 = self.token_source.lookahead_nth(n + 2);
136 (t1.kind == k1 && t1.is_jointed_to_next)
137 && (t2.kind == k2 && t2.is_jointed_to_next)
138 && t3.kind == k3
111 } 139 }
112 140
113 /// Checks if the current token is in `kinds`. 141 /// Checks if the current token is in `kinds`.
@@ -129,45 +157,18 @@ impl<'t> Parser<'t> {
129 Marker::new(pos) 157 Marker::new(pos)
130 } 158 }
131 159
132 /// Advances the parser by one token unconditionally 160 /// Consume the next token if `kind` matches.
133 /// Mainly use in `token_tree` parsing 161 pub(crate) fn bump(&mut self, kind: SyntaxKind) {
134 pub(crate) fn bump_raw(&mut self) { 162 assert!(self.eat(kind));
135 let mut kind = self.token_source.current().kind;
136
137 // Skip dollars, do_bump will eat these later
138 let mut i = 0;
139 while kind == SyntaxKind::L_DOLLAR || kind == SyntaxKind::R_DOLLAR {
140 kind = self.token_source.lookahead_nth(i).kind;
141 i += 1;
142 }
143
144 if kind == EOF {
145 return;
146 }
147 self.do_bump(kind, 1);
148 } 163 }
149 164
150 /// Advances the parser by one token with composite puncts handled 165 /// Advances the parser by one token with composite puncts handled
151 pub(crate) fn bump(&mut self) { 166 pub(crate) fn bump_any(&mut self) {
152 let kind = self.nth(0); 167 let kind = self.nth(0);
153 if kind == EOF { 168 if kind == EOF {
154 return; 169 return;
155 } 170 }
156 171 self.do_bump(kind, 1)
157 use SyntaxKind::*;
158
159 // Handle parser composites
160 match kind {
161 T![...] | T![..=] => {
162 self.bump_compound(kind, 3);
163 }
164 T![..] | T![::] | T![==] | T![=>] | T![!=] | T![->] => {
165 self.bump_compound(kind, 2);
166 }
167 _ => {
168 self.do_bump(kind, 1);
169 }
170 }
171 } 172 }
172 173
173 /// Advances the parser by one token, remapping its kind. 174 /// Advances the parser by one token, remapping its kind.
@@ -184,13 +185,6 @@ impl<'t> Parser<'t> {
184 self.do_bump(kind, 1); 185 self.do_bump(kind, 1);
185 } 186 }
186 187
187 /// Advances the parser by `n` tokens, remapping its kind.
188 /// This is useful to create compound tokens from parts. For
189 /// example, an `<<` token is two consecutive remapped `<` tokens
190 pub(crate) fn bump_compound(&mut self, kind: SyntaxKind, n: u8) {
191 self.do_bump(kind, n);
192 }
193
194 /// Emit error with the `message` 188 /// Emit error with the `message`
195 /// FIXME: this should be much more fancy and support 189 /// FIXME: this should be much more fancy and support
196 /// structured errors with spans and notes, like rustc 190 /// structured errors with spans and notes, like rustc
@@ -200,15 +194,6 @@ impl<'t> Parser<'t> {
200 self.push_event(Event::Error { msg }) 194 self.push_event(Event::Error { msg })
201 } 195 }
202 196
203 /// Consume the next token if `kind` matches.
204 pub(crate) fn eat(&mut self, kind: SyntaxKind) -> bool {
205 if !self.at(kind) {
206 return false;
207 }
208 self.bump();
209 true
210 }
211
212 /// Consume the next token if it is `kind` or emit an error 197 /// Consume the next token if it is `kind` or emit an error
213 /// otherwise. 198 /// otherwise.
214 pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool { 199 pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool {
@@ -226,19 +211,26 @@ impl<'t> Parser<'t> {
226 211
227 /// Create an error node and consume the next token. 212 /// Create an error node and consume the next token.
228 pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) { 213 pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) {
229 if self.at(T!['{']) || self.at(T!['}']) || self.at_ts(recovery) { 214 match self.current() {
230 self.error(message); 215 T!['{'] | T!['}'] | L_DOLLAR | R_DOLLAR => {
231 } else { 216 self.error(message);
232 let m = self.start(); 217 return;
218 }
219 _ => (),
220 }
221
222 if self.at_ts(recovery) {
233 self.error(message); 223 self.error(message);
234 self.bump(); 224 return;
235 m.complete(self, ERROR); 225 }
236 }; 226
227 let m = self.start();
228 self.error(message);
229 self.bump_any();
230 m.complete(self, ERROR);
237 } 231 }
238 232
239 fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) { 233 fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) {
240 self.eat_dollars();
241
242 for _ in 0..n_raw_tokens { 234 for _ in 0..n_raw_tokens {
243 self.token_source.bump(); 235 self.token_source.bump();
244 } 236 }
@@ -249,110 +241,6 @@ impl<'t> Parser<'t> {
249 fn push_event(&mut self, event: Event) { 241 fn push_event(&mut self, event: Event) {
250 self.events.push(event) 242 self.events.push(event)
251 } 243 }
252
253 /// helper function for check if it is composite.
254 fn is_composite(&self, first: Token, n: usize) -> Option<(SyntaxKind, usize)> {
255 // We assume the dollars will not occuried between
256 // mult-byte tokens
257
258 let jn1 = first.is_jointed_to_next;
259 if !jn1 && first.kind != T![-] {
260 return None;
261 }
262
263 let second = self.token_source.lookahead_nth(n + 1);
264 if first.kind == T![-] && second.kind == T![>] {
265 return Some((T![->], 2));
266 }
267 if !jn1 {
268 return None;
269 }
270
271 match (first.kind, second.kind) {
272 (T![:], T![:]) => return Some((T![::], 2)),
273 (T![=], T![=]) => return Some((T![==], 2)),
274 (T![=], T![>]) => return Some((T![=>], 2)),
275 (T![!], T![=]) => return Some((T![!=], 2)),
276 _ => {}
277 }
278
279 if first.kind != T![.] || second.kind != T![.] {
280 return None;
281 }
282
283 let third = self.token_source.lookahead_nth(n + 2);
284
285 let jn2 = second.is_jointed_to_next;
286 let la3 = third.kind;
287
288 if jn2 && la3 == T![.] {
289 return Some((T![...], 3));
290 }
291 if la3 == T![=] {
292 return Some((T![..=], 3));
293 }
294 return Some((T![..], 2));
295 }
296
297 fn eat_dollars(&mut self) {
298 loop {
299 match self.token_source.current().kind {
300 k @ SyntaxKind::L_DOLLAR | k @ SyntaxKind::R_DOLLAR => {
301 self.token_source.bump();
302 self.push_event(Event::Token { kind: k, n_raw_tokens: 1 });
303 }
304 _ => {
305 return;
306 }
307 }
308 }
309 }
310
311 pub(crate) fn eat_l_dollars(&mut self) -> usize {
312 let mut ate_count = 0;
313 loop {
314 match self.token_source.current().kind {
315 k @ SyntaxKind::L_DOLLAR => {
316 self.token_source.bump();
317 self.push_event(Event::Token { kind: k, n_raw_tokens: 1 });
318 ate_count += 1;
319 }
320 _ => {
321 return ate_count;
322 }
323 }
324 }
325 }
326
327 pub(crate) fn eat_r_dollars(&mut self, max_count: usize) -> usize {
328 let mut ate_count = 0;
329 loop {
330 match self.token_source.current().kind {
331 k @ SyntaxKind::R_DOLLAR => {
332 self.token_source.bump();
333 self.push_event(Event::Token { kind: k, n_raw_tokens: 1 });
334 ate_count += 1;
335
336 if max_count >= ate_count {
337 return ate_count;
338 }
339 }
340 _ => {
341 return ate_count;
342 }
343 }
344 }
345 }
346
347 pub(crate) fn at_l_dollar(&self) -> bool {
348 let kind = self.token_source.current().kind;
349 (kind == SyntaxKind::L_DOLLAR)
350 }
351
352 pub(crate) fn at_r_dollar(&self) -> bool {
353 let kind = self.token_source.current().kind;
354 (kind == SyntaxKind::R_DOLLAR)
355 }
356} 244}
357 245
358/// See `Parser::start`. 246/// See `Parser::start`.