diff options
Diffstat (limited to 'crates/ra_parser')
-rw-r--r-- | crates/ra_parser/src/event.rs | 6 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/expressions.rs | 1 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/expressions/atom.rs | 17 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/items.rs | 2 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/items/traits.rs | 1 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/type_args.rs | 1 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/type_params.rs | 45 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/types.rs | 40 | ||||
-rw-r--r-- | crates/ra_parser/src/lib.rs | 8 | ||||
-rw-r--r-- | crates/ra_parser/src/syntax_kind/generated.rs | 4 |
10 files changed, 93 insertions, 32 deletions
diff --git a/crates/ra_parser/src/event.rs b/crates/ra_parser/src/event.rs index c1773e8e0..87cf4eca0 100644 --- a/crates/ra_parser/src/event.rs +++ b/crates/ra_parser/src/event.rs | |||
@@ -116,12 +116,12 @@ pub(super) fn process(sink: &mut dyn TreeSink, mut events: Vec<Event>) { | |||
116 | } | 116 | } |
117 | 117 | ||
118 | for kind in forward_parents.drain(..).rev() { | 118 | for kind in forward_parents.drain(..).rev() { |
119 | sink.start_branch(kind); | 119 | sink.start_node(kind); |
120 | } | 120 | } |
121 | } | 121 | } |
122 | Event::Finish => sink.finish_branch(), | 122 | Event::Finish => sink.finish_node(), |
123 | Event::Token { kind, n_raw_tokens } => { | 123 | Event::Token { kind, n_raw_tokens } => { |
124 | sink.leaf(kind, n_raw_tokens); | 124 | sink.token(kind, n_raw_tokens); |
125 | } | 125 | } |
126 | Event::Error { msg } => sink.error(msg), | 126 | Event::Error { msg } => sink.error(msg), |
127 | } | 127 | } |
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index 73e1acd5a..bf5d6544d 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs | |||
@@ -410,6 +410,7 @@ fn try_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | |||
410 | // 82 as i32; | 410 | // 82 as i32; |
411 | // 81 as i8 + 1; | 411 | // 81 as i8 + 1; |
412 | // 79 as i16 - 1; | 412 | // 79 as i16 - 1; |
413 | // 0x36 as u8 <= 0x37; | ||
413 | // } | 414 | // } |
414 | fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | 415 | fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { |
415 | assert!(p.at(AS_KW)); | 416 | assert!(p.at(AS_KW)); |
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs index a23977bfb..8dc7e44a9 100644 --- a/crates/ra_parser/src/grammar/expressions/atom.rs +++ b/crates/ra_parser/src/grammar/expressions/atom.rs | |||
@@ -51,6 +51,7 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet = | |||
51 | BREAK_KW, | 51 | BREAK_KW, |
52 | CONTINUE_KW, | 52 | CONTINUE_KW, |
53 | LIFETIME, | 53 | LIFETIME, |
54 | ASYNC_KW, | ||
54 | ]); | 55 | ]); |
55 | 56 | ||
56 | const EXPR_RECOVERY_SET: TokenSet = token_set![LET_KW]; | 57 | const EXPR_RECOVERY_SET: TokenSet = token_set![LET_KW]; |
@@ -68,6 +69,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar | |||
68 | L_BRACK => array_expr(p), | 69 | L_BRACK => array_expr(p), |
69 | PIPE => lambda_expr(p), | 70 | PIPE => lambda_expr(p), |
70 | MOVE_KW if la == PIPE => lambda_expr(p), | 71 | MOVE_KW if la == PIPE => lambda_expr(p), |
72 | ASYNC_KW if la == PIPE || (la == MOVE_KW && p.nth(2) == PIPE) => lambda_expr(p), | ||
71 | IF_KW => if_expr(p), | 73 | IF_KW => if_expr(p), |
72 | 74 | ||
73 | LOOP_KW => loop_expr(p, None), | 75 | LOOP_KW => loop_expr(p, None), |
@@ -92,10 +94,10 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar | |||
92 | } | 94 | } |
93 | } | 95 | } |
94 | } | 96 | } |
95 | 97 | ASYNC_KW if la == L_CURLY || (la == MOVE_KW && p.nth(2) == L_CURLY) => { | |
96 | ASYNC_KW if la == L_CURLY => { | ||
97 | let m = p.start(); | 98 | let m = p.start(); |
98 | p.bump(); | 99 | p.bump(); |
100 | p.eat(MOVE_KW); | ||
99 | block_expr(p, Some(m)) | 101 | block_expr(p, Some(m)) |
100 | } | 102 | } |
101 | MATCH_KW => match_expr(p), | 103 | MATCH_KW => match_expr(p), |
@@ -190,10 +192,19 @@ fn array_expr(p: &mut Parser) -> CompletedMarker { | |||
190 | // || -> i32 { 92 }; | 192 | // || -> i32 { 92 }; |
191 | // |x| x; | 193 | // |x| x; |
192 | // move |x: i32,| x; | 194 | // move |x: i32,| x; |
195 | // async || {}; | ||
196 | // move || {}; | ||
197 | // async move || {}; | ||
193 | // } | 198 | // } |
194 | fn lambda_expr(p: &mut Parser) -> CompletedMarker { | 199 | fn lambda_expr(p: &mut Parser) -> CompletedMarker { |
195 | assert!(p.at(PIPE) || (p.at(MOVE_KW) && p.nth(1) == PIPE)); | 200 | assert!( |
201 | p.at(PIPE) | ||
202 | || (p.at(MOVE_KW) && p.nth(1) == PIPE) | ||
203 | || (p.at(ASYNC_KW) && p.nth(1) == PIPE) | ||
204 | || (p.at(ASYNC_KW) && p.nth(1) == MOVE_KW && p.nth(2) == PIPE) | ||
205 | ); | ||
196 | let m = p.start(); | 206 | let m = p.start(); |
207 | p.eat(ASYNC_KW); | ||
197 | p.eat(MOVE_KW); | 208 | p.eat(MOVE_KW); |
198 | params::param_list_opt_types(p); | 209 | params::param_list_opt_types(p); |
199 | if opt_fn_ret_type(p) { | 210 | if opt_fn_ret_type(p) { |
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs index c24e6d1e0..c4b8ef3c7 100644 --- a/crates/ra_parser/src/grammar/items.rs +++ b/crates/ra_parser/src/grammar/items.rs | |||
@@ -82,7 +82,7 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul | |||
82 | // test_err async_without_semicolon | 82 | // test_err async_without_semicolon |
83 | // fn foo() { let _ = async {} } | 83 | // fn foo() { let _ = async {} } |
84 | has_mods |= p.eat(CONST_KW); | 84 | has_mods |= p.eat(CONST_KW); |
85 | if p.at(ASYNC_KW) && p.nth(1) != L_CURLY { | 85 | if p.at(ASYNC_KW) && p.nth(1) != L_CURLY && p.nth(1) != MOVE_KW && p.nth(1) != PIPE { |
86 | p.eat(ASYNC_KW); | 86 | p.eat(ASYNC_KW); |
87 | has_mods = true; | 87 | has_mods = true; |
88 | } | 88 | } |
diff --git a/crates/ra_parser/src/grammar/items/traits.rs b/crates/ra_parser/src/grammar/items/traits.rs index f49615f6b..d03a6be0d 100644 --- a/crates/ra_parser/src/grammar/items/traits.rs +++ b/crates/ra_parser/src/grammar/items/traits.rs | |||
@@ -2,6 +2,7 @@ use super::*; | |||
2 | 2 | ||
3 | // test trait_item | 3 | // test trait_item |
4 | // trait T<U>: Hash + Clone where U: Copy {} | 4 | // trait T<U>: Hash + Clone where U: Copy {} |
5 | // trait X<U: Debug + Display>: Hash + Clone where U: Copy {} | ||
5 | pub(super) fn trait_def(p: &mut Parser) { | 6 | pub(super) fn trait_def(p: &mut Parser) { |
6 | assert!(p.at(TRAIT_KW)); | 7 | assert!(p.at(TRAIT_KW)); |
7 | p.bump(); | 8 | p.bump(); |
diff --git a/crates/ra_parser/src/grammar/type_args.rs b/crates/ra_parser/src/grammar/type_args.rs index f889419c5..684976b99 100644 --- a/crates/ra_parser/src/grammar/type_args.rs +++ b/crates/ra_parser/src/grammar/type_args.rs | |||
@@ -8,6 +8,7 @@ pub(super) fn opt_type_arg_list(p: &mut Parser, colon_colon_required: bool) { | |||
8 | p.bump(); | 8 | p.bump(); |
9 | p.bump(); | 9 | p.bump(); |
10 | } | 10 | } |
11 | (false, L_ANGLE, EQ) => return, | ||
11 | (false, L_ANGLE, _) => { | 12 | (false, L_ANGLE, _) => { |
12 | m = p.start(); | 13 | m = p.start(); |
13 | p.bump(); | 14 | p.bump(); |
diff --git a/crates/ra_parser/src/grammar/type_params.rs b/crates/ra_parser/src/grammar/type_params.rs index 40f998682..07d9b0792 100644 --- a/crates/ra_parser/src/grammar/type_params.rs +++ b/crates/ra_parser/src/grammar/type_params.rs | |||
@@ -79,23 +79,40 @@ fn lifetime_bounds(p: &mut Parser) { | |||
79 | } | 79 | } |
80 | } | 80 | } |
81 | 81 | ||
82 | pub(super) fn bounds_without_colon(p: &mut Parser) { | 82 | pub(super) fn bounds_without_colon_m(p: &mut Parser, marker: Marker) -> CompletedMarker { |
83 | loop { | 83 | while type_bound(p) { |
84 | let has_paren = p.eat(L_PAREN); | ||
85 | p.eat(QUESTION); | ||
86 | match p.current() { | ||
87 | LIFETIME => p.bump(), | ||
88 | FOR_KW => types::for_type(p), | ||
89 | _ if paths::is_path_start(p) => types::path_type(p), | ||
90 | _ => break, | ||
91 | } | ||
92 | if has_paren { | ||
93 | p.expect(R_PAREN); | ||
94 | } | ||
95 | if !p.eat(PLUS) { | 84 | if !p.eat(PLUS) { |
96 | break; | 85 | break; |
97 | } | 86 | } |
98 | } | 87 | } |
88 | |||
89 | marker.complete(p, TYPE_BOUND_LIST) | ||
90 | } | ||
91 | |||
92 | pub(super) fn bounds_without_colon(p: &mut Parser) { | ||
93 | let m = p.start(); | ||
94 | bounds_without_colon_m(p, m); | ||
95 | } | ||
96 | |||
97 | fn type_bound(p: &mut Parser) -> bool { | ||
98 | let m = p.start(); | ||
99 | let has_paren = p.eat(L_PAREN); | ||
100 | p.eat(QUESTION); | ||
101 | match p.current() { | ||
102 | LIFETIME => p.bump(), | ||
103 | FOR_KW => types::for_type(p), | ||
104 | _ if paths::is_path_start(p) => types::path_type_(p, false), | ||
105 | _ => { | ||
106 | m.abandon(p); | ||
107 | return false; | ||
108 | } | ||
109 | } | ||
110 | if has_paren { | ||
111 | p.expect(R_PAREN); | ||
112 | } | ||
113 | m.complete(p, TYPE_BOUND); | ||
114 | |||
115 | true | ||
99 | } | 116 | } |
100 | 117 | ||
101 | // test where_clause | 118 | // test where_clause |
@@ -148,7 +165,7 @@ fn where_predicate(p: &mut Parser) { | |||
148 | LIFETIME => { | 165 | LIFETIME => { |
149 | p.bump(); | 166 | p.bump(); |
150 | if p.at(COLON) { | 167 | if p.at(COLON) { |
151 | lifetime_bounds(p); | 168 | bounds(p); |
152 | } else { | 169 | } else { |
153 | p.error("expected colon"); | 170 | p.error("expected colon"); |
154 | } | 171 | } |
diff --git a/crates/ra_parser/src/grammar/types.rs b/crates/ra_parser/src/grammar/types.rs index fdd4f2c52..a46da9b44 100644 --- a/crates/ra_parser/src/grammar/types.rs +++ b/crates/ra_parser/src/grammar/types.rs | |||
@@ -261,21 +261,47 @@ fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) { | |||
261 | PATH_TYPE | 261 | PATH_TYPE |
262 | }; | 262 | }; |
263 | 263 | ||
264 | if allow_bounds && p.eat(PLUS) { | 264 | let path = m.complete(p, kind); |
265 | type_params::bounds_without_colon(p); | ||
266 | } | ||
267 | 265 | ||
268 | m.complete(p, kind); | 266 | if allow_bounds { |
267 | opt_path_type_bounds_as_dyn_trait_type(p, path); | ||
268 | } | ||
269 | } | 269 | } |
270 | 270 | ||
271 | pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) { | 271 | pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) { |
272 | assert!(paths::is_path_start(p) || p.at(L_ANGLE)); | 272 | assert!(paths::is_path_start(p) || p.at(L_ANGLE)); |
273 | let m = p.start(); | 273 | let m = p.start(); |
274 | paths::type_path(p); | 274 | paths::type_path(p); |
275 | |||
275 | // test path_type_with_bounds | 276 | // test path_type_with_bounds |
276 | // fn foo() -> Box<T + 'f> {} | 277 | // fn foo() -> Box<T + 'f> {} |
277 | if allow_bounds && p.eat(PLUS) { | 278 | // fn foo() -> Box<dyn T + 'f> {} |
278 | type_params::bounds_without_colon(p); | 279 | let path = m.complete(p, PATH_TYPE); |
280 | if allow_bounds { | ||
281 | opt_path_type_bounds_as_dyn_trait_type(p, path); | ||
279 | } | 282 | } |
280 | m.complete(p, PATH_TYPE); | 283 | } |
284 | |||
285 | /// This turns a parsed PATH_TYPE optionally into a DYN_TRAIT_TYPE | ||
286 | /// with a TYPE_BOUND_LIST | ||
287 | fn opt_path_type_bounds_as_dyn_trait_type(p: &mut Parser, path_type_marker: CompletedMarker) { | ||
288 | if !p.at(PLUS) { | ||
289 | return; | ||
290 | } | ||
291 | |||
292 | // First create a TYPE_BOUND from the completed PATH_TYPE | ||
293 | let m = path_type_marker.precede(p).complete(p, TYPE_BOUND); | ||
294 | |||
295 | // Next setup a marker for the TYPE_BOUND_LIST | ||
296 | let m = m.precede(p); | ||
297 | |||
298 | // This gets consumed here so it gets properly set | ||
299 | // in the TYPE_BOUND_LIST | ||
300 | p.eat(PLUS); | ||
301 | |||
302 | // Parse rest of the bounds into the TYPE_BOUND_LIST | ||
303 | let m = type_params::bounds_without_colon_m(p, m); | ||
304 | |||
305 | // Finally precede everything with DYN_TRAIT_TYPE | ||
306 | m.precede(p).complete(p, DYN_TRAIT_TYPE); | ||
281 | } | 307 | } |
diff --git a/crates/ra_parser/src/lib.rs b/crates/ra_parser/src/lib.rs index ddc08e462..30ba06aac 100644 --- a/crates/ra_parser/src/lib.rs +++ b/crates/ra_parser/src/lib.rs | |||
@@ -40,15 +40,15 @@ pub trait TokenSource { | |||
40 | 40 | ||
41 | /// `TreeSink` abstracts details of a particular syntax tree implementation. | 41 | /// `TreeSink` abstracts details of a particular syntax tree implementation. |
42 | pub trait TreeSink { | 42 | pub trait TreeSink { |
43 | /// Adds new leaf to the current branch. | 43 | /// Adds new token to the current branch. |
44 | fn leaf(&mut self, kind: SyntaxKind, n_tokens: u8); | 44 | fn token(&mut self, kind: SyntaxKind, n_tokens: u8); |
45 | 45 | ||
46 | /// Start new branch and make it current. | 46 | /// Start new branch and make it current. |
47 | fn start_branch(&mut self, kind: SyntaxKind); | 47 | fn start_node(&mut self, kind: SyntaxKind); |
48 | 48 | ||
49 | /// Finish current branch and restore previous | 49 | /// Finish current branch and restore previous |
50 | /// branch as current. | 50 | /// branch as current. |
51 | fn finish_branch(&mut self); | 51 | fn finish_node(&mut self); |
52 | 52 | ||
53 | fn error(&mut self, error: ParseError); | 53 | fn error(&mut self, error: ParseError); |
54 | } | 54 | } |
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs index 03247ae38..547af1b27 100644 --- a/crates/ra_parser/src/syntax_kind/generated.rs +++ b/crates/ra_parser/src/syntax_kind/generated.rs | |||
@@ -228,6 +228,8 @@ pub enum SyntaxKind { | |||
228 | PARAM, | 228 | PARAM, |
229 | SELF_PARAM, | 229 | SELF_PARAM, |
230 | ARG_LIST, | 230 | ARG_LIST, |
231 | TYPE_BOUND, | ||
232 | TYPE_BOUND_LIST, | ||
231 | } | 233 | } |
232 | use self::SyntaxKind::*; | 234 | use self::SyntaxKind::*; |
233 | 235 | ||
@@ -567,6 +569,8 @@ impl SyntaxKind { | |||
567 | PARAM => &SyntaxInfo { name: "PARAM" }, | 569 | PARAM => &SyntaxInfo { name: "PARAM" }, |
568 | SELF_PARAM => &SyntaxInfo { name: "SELF_PARAM" }, | 570 | SELF_PARAM => &SyntaxInfo { name: "SELF_PARAM" }, |
569 | ARG_LIST => &SyntaxInfo { name: "ARG_LIST" }, | 571 | ARG_LIST => &SyntaxInfo { name: "ARG_LIST" }, |
572 | TYPE_BOUND => &SyntaxInfo { name: "TYPE_BOUND" }, | ||
573 | TYPE_BOUND_LIST => &SyntaxInfo { name: "TYPE_BOUND_LIST" }, | ||
570 | TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" }, | 574 | TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" }, |
571 | EOF => &SyntaxInfo { name: "EOF" }, | 575 | EOF => &SyntaxInfo { name: "EOF" }, |
572 | } | 576 | } |