aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar
diff options
context:
space:
mode:
authorGeoffry Song <[email protected]>2019-10-03 08:10:58 +0100
committerGeoffry Song <[email protected]>2019-10-03 08:27:09 +0100
commitb63f260bbcf89a2b40358f534b97f672468294fb (patch)
tree9a21ac5bc76e828025c9dd66b01ea1e27bd38d50 /crates/ra_parser/src/grammar
parente1c367595139f109fb6f53811bed7d67a384793e (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.rs14
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;