diff options
Diffstat (limited to 'crates/ra_parser')
-rw-r--r-- | crates/ra_parser/src/grammar/expressions.rs | 21 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/expressions/atom.rs | 16 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/items.rs | 4 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/items/use_item.rs | 2 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/paths.rs | 6 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/patterns.rs | 4 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/type_params.rs | 2 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/types.rs | 7 |
8 files changed, 42 insertions, 20 deletions
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index 9fd3a235d..0495f34ae 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs | |||
@@ -359,11 +359,14 @@ fn lhs( | |||
359 | return Some((m.complete(p, RANGE_EXPR), BlockLike::NotBlock)); | 359 | return Some((m.complete(p, RANGE_EXPR), BlockLike::NotBlock)); |
360 | } | 360 | } |
361 | _ => { | 361 | _ => { |
362 | // test expression_after_block | ||
363 | // fn foo() { | ||
364 | // let mut p = F{x: 5}; | ||
365 | // {p}.x = 10; | ||
366 | // } | ||
367 | // | ||
362 | let (lhs, blocklike) = atom::atom_expr(p, r)?; | 368 | let (lhs, blocklike) = atom::atom_expr(p, r)?; |
363 | return Some(( | 369 | return Some(postfix_expr(p, lhs, blocklike, !(r.prefer_stmt && blocklike.is_block()))); |
364 | postfix_expr(p, lhs, !(r.prefer_stmt && blocklike.is_block())), | ||
365 | blocklike, | ||
366 | )); | ||
367 | } | 370 | } |
368 | }; | 371 | }; |
369 | expr_bp(p, r, 255, dollar_lvl); | 372 | expr_bp(p, r, 255, dollar_lvl); |
@@ -376,8 +379,9 @@ fn postfix_expr( | |||
376 | // Calls are disallowed if the type is a block and we prefer statements because the call cannot be disambiguated from a tuple | 379 | // Calls are disallowed if the type is a block and we prefer statements because the call cannot be disambiguated from a tuple |
377 | // E.g. `while true {break}();` is parsed as | 380 | // E.g. `while true {break}();` is parsed as |
378 | // `while true {break}; ();` | 381 | // `while true {break}; ();` |
382 | mut block_like: BlockLike, | ||
379 | mut allow_calls: bool, | 383 | mut allow_calls: bool, |
380 | ) -> CompletedMarker { | 384 | ) -> (CompletedMarker, BlockLike) { |
381 | loop { | 385 | loop { |
382 | lhs = match p.current() { | 386 | lhs = match p.current() { |
383 | // test stmt_postfix_expr_ambiguity | 387 | // test stmt_postfix_expr_ambiguity |
@@ -417,9 +421,10 @@ fn postfix_expr( | |||
417 | T![as] => cast_expr(p, lhs), | 421 | T![as] => cast_expr(p, lhs), |
418 | _ => break, | 422 | _ => break, |
419 | }; | 423 | }; |
420 | allow_calls = true | 424 | allow_calls = true; |
425 | block_like = BlockLike::NotBlock; | ||
421 | } | 426 | } |
422 | lhs | 427 | (lhs, block_like) |
423 | } | 428 | } |
424 | 429 | ||
425 | // test call_expr | 430 | // test call_expr |
@@ -549,7 +554,7 @@ fn arg_list(p: &mut Parser) { | |||
549 | // let _ = format!(); | 554 | // let _ = format!(); |
550 | // } | 555 | // } |
551 | fn path_expr(p: &mut Parser, r: Restrictions) -> (CompletedMarker, BlockLike) { | 556 | fn path_expr(p: &mut Parser, r: Restrictions) -> (CompletedMarker, BlockLike) { |
552 | assert!(paths::is_path_start(p) || p.at(T![<])); | 557 | assert!(paths::is_path_start(p)); |
553 | let m = p.start(); | 558 | let m = p.start(); |
554 | paths::expr_path(p); | 559 | paths::expr_path(p); |
555 | match p.current() { | 560 | match p.current() { |
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs index d98953a7e..bc942ae01 100644 --- a/crates/ra_parser/src/grammar/expressions/atom.rs +++ b/crates/ra_parser/src/grammar/expressions/atom.rs | |||
@@ -62,7 +62,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar | |||
62 | if let Some(m) = literal(p) { | 62 | if let Some(m) = literal(p) { |
63 | return Some((m, BlockLike::NotBlock)); | 63 | return Some((m, BlockLike::NotBlock)); |
64 | } | 64 | } |
65 | if paths::is_path_start(p) || p.at(T![<]) { | 65 | if paths::is_path_start(p) { |
66 | return Some(path_expr(p, r)); | 66 | return Some(path_expr(p, r)); |
67 | } | 67 | } |
68 | let la = p.nth(1); | 68 | let la = p.nth(1); |
@@ -110,7 +110,19 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar | |||
110 | p.bump(); | 110 | p.bump(); |
111 | block_expr(p, Some(m)) | 111 | block_expr(p, Some(m)) |
112 | } | 112 | } |
113 | T!['{'] => block_expr(p, None), | 113 | T!['{'] => { |
114 | // test for_range_from | ||
115 | // fn foo() { | ||
116 | // for x in 0 .. { | ||
117 | // break; | ||
118 | // } | ||
119 | // } | ||
120 | if r.forbid_structs { | ||
121 | return None; | ||
122 | } else { | ||
123 | block_expr(p, None) | ||
124 | } | ||
125 | } | ||
114 | T![return] => return_expr(p), | 126 | T![return] => return_expr(p), |
115 | T![continue] => continue_expr(p), | 127 | T![continue] => continue_expr(p), |
116 | T![break] => break_expr(p, r), | 128 | T![break] => break_expr(p, r), |
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs index 543af7c4b..b7da44758 100644 --- a/crates/ra_parser/src/grammar/items.rs +++ b/crates/ra_parser/src/grammar/items.rs | |||
@@ -49,7 +49,7 @@ pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemF | |||
49 | } | 49 | } |
50 | Err(m) => m, | 50 | Err(m) => m, |
51 | }; | 51 | }; |
52 | if paths::is_path_start(p) { | 52 | if paths::is_use_path_start(p) { |
53 | match macro_call(p) { | 53 | match macro_call(p) { |
54 | BlockLike::Block => (), | 54 | BlockLike::Block => (), |
55 | BlockLike::NotBlock => { | 55 | BlockLike::NotBlock => { |
@@ -378,7 +378,7 @@ pub(crate) fn mod_item_list(p: &mut Parser) { | |||
378 | } | 378 | } |
379 | 379 | ||
380 | fn macro_call(p: &mut Parser) -> BlockLike { | 380 | fn macro_call(p: &mut Parser) -> BlockLike { |
381 | assert!(paths::is_path_start(p)); | 381 | assert!(paths::is_use_path_start(p)); |
382 | paths::use_path(p); | 382 | paths::use_path(p); |
383 | macro_call_after_excl(p) | 383 | macro_call_after_excl(p) |
384 | } | 384 | } |
diff --git a/crates/ra_parser/src/grammar/items/use_item.rs b/crates/ra_parser/src/grammar/items/use_item.rs index c3a0b4410..c0c7d0ec6 100644 --- a/crates/ra_parser/src/grammar/items/use_item.rs +++ b/crates/ra_parser/src/grammar/items/use_item.rs | |||
@@ -65,7 +65,7 @@ fn use_tree(p: &mut Parser) { | |||
65 | // use crate::Item; | 65 | // use crate::Item; |
66 | // use self::some::Struct; | 66 | // use self::some::Struct; |
67 | // use crate_name::some_item; | 67 | // use crate_name::some_item; |
68 | _ if paths::is_path_start(p) => { | 68 | _ if paths::is_use_path_start(p) => { |
69 | paths::use_path(p); | 69 | paths::use_path(p); |
70 | match p.current() { | 70 | match p.current() { |
71 | T![as] => { | 71 | T![as] => { |
diff --git a/crates/ra_parser/src/grammar/paths.rs b/crates/ra_parser/src/grammar/paths.rs index 3537b0da1..07eb53b0c 100644 --- a/crates/ra_parser/src/grammar/paths.rs +++ b/crates/ra_parser/src/grammar/paths.rs | |||
@@ -4,6 +4,10 @@ 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, COLONCOLON, 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![<]) | ||
8 | } | ||
9 | |||
10 | pub(super) fn is_use_path_start(p: &Parser) -> bool { | ||
7 | match p.current() { | 11 | match p.current() { |
8 | IDENT | T![self] | T![super] | T![crate] | T![::] => true, | 12 | IDENT | T![self] | T![super] | T![crate] | T![::] => true, |
9 | _ => false, | 13 | _ => false, |
@@ -58,7 +62,7 @@ fn path_segment(p: &mut Parser, mode: Mode, first: bool) { | |||
58 | if first && p.eat(T![<]) { | 62 | if first && p.eat(T![<]) { |
59 | types::type_(p); | 63 | types::type_(p); |
60 | if p.eat(T![as]) { | 64 | if p.eat(T![as]) { |
61 | if is_path_start(p) { | 65 | if is_use_path_start(p) { |
62 | types::path_type(p); | 66 | types::path_type(p); |
63 | } else { | 67 | } else { |
64 | p.error("expected a trait"); | 68 | p.error("expected a trait"); |
diff --git a/crates/ra_parser/src/grammar/patterns.rs b/crates/ra_parser/src/grammar/patterns.rs index 46034942a..df6000707 100644 --- a/crates/ra_parser/src/grammar/patterns.rs +++ b/crates/ra_parser/src/grammar/patterns.rs | |||
@@ -65,7 +65,7 @@ fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> { | |||
65 | { | 65 | { |
66 | return Some(bind_pat(p, true)); | 66 | return Some(bind_pat(p, true)); |
67 | } | 67 | } |
68 | if paths::is_path_start(p) { | 68 | if paths::is_use_path_start(p) { |
69 | return Some(path_pat(p)); | 69 | return Some(path_pat(p)); |
70 | } | 70 | } |
71 | 71 | ||
@@ -118,7 +118,7 @@ fn literal_pat(p: &mut Parser) -> CompletedMarker { | |||
118 | // let Bar(..) = (); | 118 | // let Bar(..) = (); |
119 | // } | 119 | // } |
120 | fn path_pat(p: &mut Parser) -> CompletedMarker { | 120 | fn path_pat(p: &mut Parser) -> CompletedMarker { |
121 | assert!(paths::is_path_start(p)); | 121 | assert!(paths::is_use_path_start(p)); |
122 | let m = p.start(); | 122 | let m = p.start(); |
123 | paths::expr_path(p); | 123 | paths::expr_path(p); |
124 | let kind = match p.current() { | 124 | let kind = match p.current() { |
diff --git a/crates/ra_parser/src/grammar/type_params.rs b/crates/ra_parser/src/grammar/type_params.rs index ef59b59d3..d739df727 100644 --- a/crates/ra_parser/src/grammar/type_params.rs +++ b/crates/ra_parser/src/grammar/type_params.rs | |||
@@ -101,7 +101,7 @@ fn type_bound(p: &mut Parser) -> bool { | |||
101 | match p.current() { | 101 | match p.current() { |
102 | LIFETIME => p.bump(), | 102 | LIFETIME => p.bump(), |
103 | T![for] => types::for_type(p), | 103 | T![for] => types::for_type(p), |
104 | _ if paths::is_path_start(p) => types::path_type_(p, false), | 104 | _ if paths::is_use_path_start(p) => types::path_type_(p, false), |
105 | _ => { | 105 | _ => { |
106 | m.abandon(p); | 106 | m.abandon(p); |
107 | return false; | 107 | return false; |
diff --git a/crates/ra_parser/src/grammar/types.rs b/crates/ra_parser/src/grammar/types.rs index c0b722569..29d173305 100644 --- a/crates/ra_parser/src/grammar/types.rs +++ b/crates/ra_parser/src/grammar/types.rs | |||
@@ -29,7 +29,7 @@ fn type_with_bounds_cond(p: &mut Parser, allow_bounds: bool) { | |||
29 | T![dyn ] => dyn_trait_type(p), | 29 | T![dyn ] => dyn_trait_type(p), |
30 | // Some path types are not allowed to have bounds (no plus) | 30 | // Some path types are not allowed to have bounds (no plus) |
31 | T![<] => path_type_(p, allow_bounds), | 31 | T![<] => path_type_(p, allow_bounds), |
32 | _ if paths::is_path_start(p) => path_or_macro_type_(p, allow_bounds), | 32 | _ if paths::is_use_path_start(p) => path_or_macro_type_(p, allow_bounds), |
33 | _ => { | 33 | _ => { |
34 | p.err_recover("expected type", TYPE_RECOVERY_SET); | 34 | p.err_recover("expected type", TYPE_RECOVERY_SET); |
35 | } | 35 | } |
@@ -205,6 +205,7 @@ pub(super) fn for_binder(p: &mut Parser) { | |||
205 | // type A = for<'a> fn() -> (); | 205 | // type A = for<'a> fn() -> (); |
206 | // fn foo<T>(_t: &T) where for<'a> &'a T: Iterator {} | 206 | // fn foo<T>(_t: &T) where for<'a> &'a T: Iterator {} |
207 | // fn bar<T>(_t: &T) where for<'a> &'a mut T: Iterator {} | 207 | // fn bar<T>(_t: &T) where for<'a> &'a mut T: Iterator {} |
208 | // fn baz<T>(_t: &T) where for<'a> <&'a T as Baz>::Foo: Iterator {} | ||
208 | pub(super) fn for_type(p: &mut Parser) { | 209 | pub(super) fn for_type(p: &mut Parser) { |
209 | assert!(p.at(T![for])); | 210 | assert!(p.at(T![for])); |
210 | let m = p.start(); | 211 | let m = p.start(); |
@@ -251,7 +252,7 @@ pub(super) fn path_type(p: &mut Parser) { | |||
251 | // type A = foo!(); | 252 | // type A = foo!(); |
252 | // type B = crate::foo!(); | 253 | // type B = crate::foo!(); |
253 | fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) { | 254 | fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) { |
254 | assert!(paths::is_path_start(p) || p.at(T![<])); | 255 | assert!(paths::is_path_start(p)); |
255 | let m = p.start(); | 256 | let m = p.start(); |
256 | paths::type_path(p); | 257 | paths::type_path(p); |
257 | 258 | ||
@@ -270,7 +271,7 @@ fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) { | |||
270 | } | 271 | } |
271 | 272 | ||
272 | pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) { | 273 | pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) { |
273 | assert!(paths::is_path_start(p) || p.at(T![<])); | 274 | assert!(paths::is_path_start(p)); |
274 | let m = p.start(); | 275 | let m = p.start(); |
275 | paths::type_path(p); | 276 | paths::type_path(p); |
276 | 277 | ||