diff options
Diffstat (limited to 'crates/ra_parser/src/grammar')
-rw-r--r-- | crates/ra_parser/src/grammar/attributes.rs | 4 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/expressions.rs | 271 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/expressions/atom.rs | 61 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/items.rs | 22 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/items/consts.rs | 2 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/items/nominal.rs | 12 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/items/traits.rs | 8 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/items/use_item.rs | 30 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/params.rs | 13 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/paths.rs | 11 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/patterns.rs | 49 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/type_args.rs | 29 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/type_params.rs | 18 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/types.rs | 24 |
14 files changed, 284 insertions, 270 deletions
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) { | |||
15 | fn attribute(p: &mut Parser, inner: bool) { | 15 | fn 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 | ||
15 | pub(super) fn expr(p: &mut Parser) -> BlockLike { | 15 | pub(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 | ||
21 | pub(super) fn expr_stmt(p: &mut Parser) -> (Option<CompletedMarker>, BlockLike) { | 20 | pub(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 | ||
27 | fn expr_no_struct(p: &mut Parser) { | 25 | fn 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) { | |||
46 | pub(crate) fn naked_block(p: &mut Parser) { | 43 | pub(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 | ||
215 | enum 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 | 216 | fn current_op(p: &Parser) -> (u8, SyntaxKind) { | |
220 | fn 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. |
264 | fn expr_bp( | 257 | fn 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 | ||
324 | const LHS_FIRST: TokenSet = | 288 | const 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 | ||
327 | fn lhs( | 290 | fn 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 { | |||
453 | fn index_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | 438 | fn 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 | // } |
467 | fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | 452 | fn 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 { | |||
493 | fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | 478 | fn 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 { | |||
512 | fn try_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | 497 | fn 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 { | |||
526 | fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | 511 | fn 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 { | |||
536 | fn arg_list(p: &mut Parser) { | 521 | fn 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) { | |||
585 | pub(crate) fn record_field_list(p: &mut Parser) { | 570 | pub(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 { | |||
179 | fn array_expr(p: &mut Parser) -> CompletedMarker { | 180 | fn 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 { | |||
261 | fn if_expr(p: &mut Parser) -> CompletedMarker { | 262 | fn 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 { | |||
284 | fn label(p: &mut Parser) { | 285 | fn 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) { | |||
296 | fn loop_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { | 297 | fn 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 { | |||
309 | fn while_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { | 310 | fn 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 { | |||
322 | fn for_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { | 323 | fn 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) { | |||
356 | fn match_expr(p: &mut Parser) -> CompletedMarker { | 357 | fn 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 { | |||
452 | fn match_guard(p: &mut Parser) -> CompletedMarker { | 453 | fn 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 { | |||
478 | fn return_expr(p: &mut Parser) -> CompletedMarker { | 479 | fn 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 { | |||
495 | fn continue_expr(p: &mut Parser) -> CompletedMarker { | 496 | fn 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 { | |||
512 | fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker { | 513 | fn 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 { | |||
534 | fn try_block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { | 535 | fn 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 { | |||
548 | fn box_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { | 549 | fn 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 | ||
560 | fn 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 | ||
277 | fn extern_crate_item(p: &mut Parser, m: Marker) { | 277 | fn 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) { | |||
288 | pub(crate) fn extern_item_list(p: &mut Parser) { | 288 | pub(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 | ||
297 | fn fn_def(p: &mut Parser, flavor: ItemFlavor) { | 297 | fn 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; |
334 | fn type_def(p: &mut Parser, m: Marker) { | 334 | fn 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 | ||
358 | pub(crate) fn mod_item(p: &mut Parser, m: Marker) { | 358 | pub(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) { | |||
371 | pub(crate) fn mod_item_list(p: &mut Parser) { | 371 | pub(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 | ||
11 | fn const_or_static(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) { | 11 | fn 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 | ||
45 | pub(super) fn enum_def(p: &mut Parser, m: Marker) { | 45 | pub(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) { | |||
59 | pub(crate) fn enum_variant_list(p: &mut Parser) { | 59 | pub(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) { | |||
94 | pub(crate) fn record_field_def_list(p: &mut Parser) { | 94 | pub(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 {} |
6 | pub(super) fn trait_def(p: &mut Parser) { | 6 | pub(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) { | |||
29 | pub(crate) fn trait_item_list(p: &mut Parser) { | 29 | pub(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 {} |
46 | pub(super) fn impl_block(p: &mut Parser) { | 46 | pub(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) { | |||
78 | pub(crate) fn impl_item_list(p: &mut Parser) { | 78 | pub(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 | ||
3 | pub(super) fn use_item(p: &mut Parser, m: Marker) { | 3 | pub(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};` |
15 | fn use_tree(p: &mut Parser) { | 15 | fn 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) { | |||
114 | pub(crate) fn use_tree_list(p: &mut Parser) { | 114 | pub(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 @@ | |||
1 | use super::*; | 1 | use super::*; |
2 | 2 | ||
3 | pub(super) const PATH_FIRST: TokenSet = | 3 | pub(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 | ||
6 | pub(super) fn is_path_start(p: &Parser) -> bool { | 6 | pub(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 | ||
10 | pub(super) fn is_use_path_start(p: &Parser) -> bool { | 10 | pub(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 | ||
58 | fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> { | 61 | fn 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 | // } |
141 | fn tuple_pat_fields(p: &mut Parser) { | 146 | fn 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) { | |||
155 | fn record_field_pat_list(p: &mut Parser) { | 160 | fn 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) { | |||
192 | fn placeholder_pat(p: &mut Parser) -> CompletedMarker { | 197 | fn 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 { | |||
204 | fn ref_pat(p: &mut Parser) -> CompletedMarker { | 209 | fn 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 { | |||
228 | fn slice_pat(p: &mut Parser) -> CompletedMarker { | 233 | fn 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 { | |||
237 | fn pat_list(p: &mut Parser, ket: SyntaxKind) { | 242 | fn 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 { | |||
281 | fn box_pat(p: &mut Parser) -> CompletedMarker { | 286 | fn 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 | ||
3 | pub(super) fn opt_type_arg_list(p: &mut Parser, colon_colon_required: bool) { | 3 | pub(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) { | |||
10 | fn type_param_list(p: &mut Parser) { | 10 | fn 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 | ||
39 | fn lifetime_param(p: &mut Parser, m: Marker) { | 39 | fn 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)>; |
65 | pub(super) fn bounds(p: &mut Parser) { | 65 | pub(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 | ||
71 | fn lifetime_bounds(p: &mut Parser) { | 71 | fn 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) { | |||
44 | fn paren_or_tuple_type(p: &mut Parser) { | 44 | fn 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) { | |||
79 | fn never_type(p: &mut Parser) { | 79 | fn 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 | ||
86 | fn pointer_type(p: &mut Parser) { | 86 | fn 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) { | |||
110 | fn array_or_slice_type(p: &mut Parser) { | 110 | fn 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) { | |||
146 | fn reference_type(p: &mut Parser) { | 146 | fn 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) { | |||
158 | fn placeholder_type(p: &mut Parser) { | 158 | fn 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 | ||
194 | pub(super) fn for_binder(p: &mut Parser) { | 194 | pub(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) { | |||
224 | fn impl_trait_type(p: &mut Parser) { | 224 | fn 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) { | |||
234 | fn dyn_trait_type(p: &mut Parser) { | 234 | fn 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 | } |