diff options
author | Geoffry Song <[email protected]> | 2019-10-03 08:10:58 +0100 |
---|---|---|
committer | Geoffry Song <[email protected]> | 2019-10-03 08:27:09 +0100 |
commit | b63f260bbcf89a2b40358f534b97f672468294fb (patch) | |
tree | 9a21ac5bc76e828025c9dd66b01ea1e27bd38d50 /crates/ra_parser/src/grammar | |
parent | e1c367595139f109fb6f53811bed7d67a384793e (diff) |
Lower the precedence of the `as` operator.
Previously, the `as` operator was being parsed like a postfix expression, and
therefore being given the highest possible precedence. That caused it to bind
more tightly than prefix operators, which it should not. Instead, parse it
somewhat like a normal binary expression with some special-casing.
Diffstat (limited to 'crates/ra_parser/src/grammar')
-rw-r--r-- | crates/ra_parser/src/grammar/expressions.rs | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index 413ecb278..448b87505 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs | |||
@@ -250,6 +250,7 @@ fn current_op(p: &Parser) -> (u8, SyntaxKind) { | |||
250 | T![!] if p.at(T![!=]) => (5, T![!=]), | 250 | T![!] if p.at(T![!=]) => (5, T![!=]), |
251 | T![-] if p.at(T![-=]) => (1, T![-=]), | 251 | T![-] if p.at(T![-=]) => (1, T![-=]), |
252 | T![-] => (10, T![-]), | 252 | T![-] => (10, T![-]), |
253 | T![as] => (12, T![as]), | ||
253 | 254 | ||
254 | _ => NOT_AN_OP | 255 | _ => NOT_AN_OP |
255 | } | 256 | } |
@@ -278,6 +279,10 @@ fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> (Option<CompletedMarker>, | |||
278 | if op_bp < bp { | 279 | if op_bp < bp { |
279 | break; | 280 | break; |
280 | } | 281 | } |
282 | if p.at(T![as]) { | ||
283 | lhs = cast_expr(p, lhs); | ||
284 | continue; | ||
285 | } | ||
281 | let m = lhs.precede(p); | 286 | let m = lhs.precede(p); |
282 | p.bump(op); | 287 | p.bump(op); |
283 | 288 | ||
@@ -296,6 +301,7 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> | |||
296 | // fn foo() { | 301 | // fn foo() { |
297 | // let _ = &1; | 302 | // let _ = &1; |
298 | // let _ = &mut &f(); | 303 | // let _ = &mut &f(); |
304 | // let _ = &1 as *const i32; | ||
299 | // } | 305 | // } |
300 | T![&] => { | 306 | T![&] => { |
301 | m = p.start(); | 307 | m = p.start(); |
@@ -305,9 +311,13 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> | |||
305 | } | 311 | } |
306 | // test unary_expr | 312 | // test unary_expr |
307 | // fn foo() { | 313 | // fn foo() { |
308 | // **&1; | 314 | // **&1 + 1; |
309 | // !!true; | 315 | // !!true; |
310 | // --1; | 316 | // --1; |
317 | // *&1 as u64; | ||
318 | // *x(1); | ||
319 | // &x[1]; | ||
320 | // -1..2; | ||
311 | // } | 321 | // } |
312 | T![*] | T![!] | T![-] => { | 322 | T![*] | T![!] | T![-] => { |
313 | m = p.start(); | 323 | m = p.start(); |
@@ -338,6 +348,7 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> | |||
338 | return Some(postfix_expr(p, lhs, blocklike, !(r.prefer_stmt && blocklike.is_block()))); | 348 | return Some(postfix_expr(p, lhs, blocklike, !(r.prefer_stmt && blocklike.is_block()))); |
339 | } | 349 | } |
340 | }; | 350 | }; |
351 | // parse the interior of the unary expression | ||
341 | expr_bp(p, r, 255); | 352 | expr_bp(p, r, 255); |
342 | Some((m.complete(p, kind), BlockLike::NotBlock)) | 353 | Some((m.complete(p, kind), BlockLike::NotBlock)) |
343 | } | 354 | } |
@@ -371,7 +382,6 @@ fn postfix_expr( | |||
371 | } | 382 | } |
372 | }, | 383 | }, |
373 | T![?] => try_expr(p, lhs), | 384 | T![?] => try_expr(p, lhs), |
374 | T![as] => cast_expr(p, lhs), | ||
375 | _ => break, | 385 | _ => break, |
376 | }; | 386 | }; |
377 | allow_calls = true; | 387 | allow_calls = true; |