From b63f260bbcf89a2b40358f534b97f672468294fb Mon Sep 17 00:00:00 2001 From: Geoffry Song Date: Thu, 3 Oct 2019 00:10:58 -0700 Subject: 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. --- crates/ra_parser/src/grammar/expressions.rs | 14 ++- .../test_data/parser/inline/ok/0019_unary_expr.rs | 6 +- .../test_data/parser/inline/ok/0019_unary_expr.txt | 136 +++++++++++++++------ .../test_data/parser/inline/ok/0082_ref_expr.rs | 1 + .../test_data/parser/inline/ok/0082_ref_expr.txt | 41 +++++-- 5 files changed, 153 insertions(+), 45 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) { T![!] if p.at(T![!=]) => (5, T![!=]), T![-] if p.at(T![-=]) => (1, T![-=]), T![-] => (10, T![-]), + T![as] => (12, T![as]), _ => NOT_AN_OP } @@ -278,6 +279,10 @@ fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> (Option, if op_bp < bp { break; } + if p.at(T![as]) { + lhs = cast_expr(p, lhs); + continue; + } let m = lhs.precede(p); p.bump(op); @@ -296,6 +301,7 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> // fn foo() { // let _ = &1; // let _ = &mut &f(); + // let _ = &1 as *const i32; // } T![&] => { m = p.start(); @@ -305,9 +311,13 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> } // test unary_expr // fn foo() { - // **&1; + // **&1 + 1; // !!true; // --1; + // *&1 as u64; + // *x(1); + // &x[1]; + // -1..2; // } T![*] | T![!] | T![-] => { m = p.start(); @@ -338,6 +348,7 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> return Some(postfix_expr(p, lhs, blocklike, !(r.prefer_stmt && blocklike.is_block()))); } }; + // parse the interior of the unary expression expr_bp(p, r, 255); Some((m.complete(p, kind), BlockLike::NotBlock)) } @@ -371,7 +382,6 @@ fn postfix_expr( } }, T![?] => try_expr(p, lhs), - T![as] => cast_expr(p, lhs), _ => break, }; allow_calls = true; diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0019_unary_expr.rs b/crates/ra_syntax/test_data/parser/inline/ok/0019_unary_expr.rs index f1c3f7118..1080b48a1 100644 --- a/crates/ra_syntax/test_data/parser/inline/ok/0019_unary_expr.rs +++ b/crates/ra_syntax/test_data/parser/inline/ok/0019_unary_expr.rs @@ -1,5 +1,9 @@ fn foo() { - **&1; + **&1 + 1; !!true; --1; + *&1 as u64; + *x(1); + &x[1]; + -1..2; } diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0019_unary_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0019_unary_expr.txt index 2d71efd86..e2b60d99f 100644 --- a/crates/ra_syntax/test_data/parser/inline/ok/0019_unary_expr.txt +++ b/crates/ra_syntax/test_data/parser/inline/ok/0019_unary_expr.txt @@ -1,5 +1,5 @@ -SOURCE_FILE@[0; 44) - FN_DEF@[0; 43) +SOURCE_FILE@[0; 97) + FN_DEF@[0; 96) FN_KW@[0; 2) "fn" WHITESPACE@[2; 3) " " NAME@[3; 6) @@ -8,38 +8,104 @@ SOURCE_FILE@[0; 44) L_PAREN@[6; 7) "(" R_PAREN@[7; 8) ")" WHITESPACE@[8; 9) " " - BLOCK_EXPR@[9; 43) - BLOCK@[9; 43) + BLOCK_EXPR@[9; 96) + BLOCK@[9; 96) L_CURLY@[9; 10) "{" WHITESPACE@[10; 15) "\n " - EXPR_STMT@[15; 20) - PREFIX_EXPR@[15; 19) - STAR@[15; 16) "*" - PREFIX_EXPR@[16; 19) - STAR@[16; 17) "*" - REF_EXPR@[17; 19) - AMP@[17; 18) "&" - LITERAL@[18; 19) - INT_NUMBER@[18; 19) "1" - SEMI@[19; 20) ";" - WHITESPACE@[20; 25) "\n " - EXPR_STMT@[25; 32) - PREFIX_EXPR@[25; 31) - EXCL@[25; 26) "!" - PREFIX_EXPR@[26; 31) - EXCL@[26; 27) "!" - LITERAL@[27; 31) - TRUE_KW@[27; 31) "true" - SEMI@[31; 32) ";" - WHITESPACE@[32; 37) "\n " - EXPR_STMT@[37; 41) - PREFIX_EXPR@[37; 40) - MINUS@[37; 38) "-" - PREFIX_EXPR@[38; 40) - MINUS@[38; 39) "-" - LITERAL@[39; 40) - INT_NUMBER@[39; 40) "1" - SEMI@[40; 41) ";" - WHITESPACE@[41; 42) "\n" - R_CURLY@[42; 43) "}" - WHITESPACE@[43; 44) "\n" + EXPR_STMT@[15; 24) + BIN_EXPR@[15; 23) + PREFIX_EXPR@[15; 19) + STAR@[15; 16) "*" + PREFIX_EXPR@[16; 19) + STAR@[16; 17) "*" + REF_EXPR@[17; 19) + AMP@[17; 18) "&" + LITERAL@[18; 19) + INT_NUMBER@[18; 19) "1" + WHITESPACE@[19; 20) " " + PLUS@[20; 21) "+" + WHITESPACE@[21; 22) " " + LITERAL@[22; 23) + INT_NUMBER@[22; 23) "1" + SEMI@[23; 24) ";" + WHITESPACE@[24; 29) "\n " + EXPR_STMT@[29; 36) + PREFIX_EXPR@[29; 35) + EXCL@[29; 30) "!" + PREFIX_EXPR@[30; 35) + EXCL@[30; 31) "!" + LITERAL@[31; 35) + TRUE_KW@[31; 35) "true" + SEMI@[35; 36) ";" + WHITESPACE@[36; 41) "\n " + EXPR_STMT@[41; 45) + PREFIX_EXPR@[41; 44) + MINUS@[41; 42) "-" + PREFIX_EXPR@[42; 44) + MINUS@[42; 43) "-" + LITERAL@[43; 44) + INT_NUMBER@[43; 44) "1" + SEMI@[44; 45) ";" + WHITESPACE@[45; 50) "\n " + EXPR_STMT@[50; 61) + CAST_EXPR@[50; 60) + PREFIX_EXPR@[50; 53) + STAR@[50; 51) "*" + REF_EXPR@[51; 53) + AMP@[51; 52) "&" + LITERAL@[52; 53) + INT_NUMBER@[52; 53) "1" + WHITESPACE@[53; 54) " " + AS_KW@[54; 56) "as" + WHITESPACE@[56; 57) " " + PATH_TYPE@[57; 60) + PATH@[57; 60) + PATH_SEGMENT@[57; 60) + NAME_REF@[57; 60) + IDENT@[57; 60) "u64" + SEMI@[60; 61) ";" + WHITESPACE@[61; 66) "\n " + EXPR_STMT@[66; 72) + PREFIX_EXPR@[66; 71) + STAR@[66; 67) "*" + CALL_EXPR@[67; 71) + PATH_EXPR@[67; 68) + PATH@[67; 68) + PATH_SEGMENT@[67; 68) + NAME_REF@[67; 68) + IDENT@[67; 68) "x" + ARG_LIST@[68; 71) + L_PAREN@[68; 69) "(" + LITERAL@[69; 70) + INT_NUMBER@[69; 70) "1" + R_PAREN@[70; 71) ")" + SEMI@[71; 72) ";" + WHITESPACE@[72; 77) "\n " + EXPR_STMT@[77; 83) + REF_EXPR@[77; 82) + AMP@[77; 78) "&" + INDEX_EXPR@[78; 82) + PATH_EXPR@[78; 79) + PATH@[78; 79) + PATH_SEGMENT@[78; 79) + NAME_REF@[78; 79) + IDENT@[78; 79) "x" + L_BRACK@[79; 80) "[" + LITERAL@[80; 81) + INT_NUMBER@[80; 81) "1" + R_BRACK@[81; 82) "]" + SEMI@[82; 83) ";" + WHITESPACE@[83; 88) "\n " + EXPR_STMT@[88; 94) + RANGE_EXPR@[88; 93) + PREFIX_EXPR@[88; 90) + MINUS@[88; 89) "-" + LITERAL@[89; 90) + INT_NUMBER@[89; 90) "1" + DOTDOT@[90; 92) ".." + LITERAL@[92; 93) + INT_NUMBER@[92; 93) "2" + SEMI@[93; 94) ";" + WHITESPACE@[94; 95) "\n" + R_CURLY@[95; 96) "}" + WHITESPACE@[96; 97) "\n" diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.rs b/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.rs index 2dac6be95..050638f56 100644 --- a/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.rs +++ b/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.rs @@ -1,4 +1,5 @@ fn foo() { let _ = &1; let _ = &mut &f(); + let _ = &1 as *const i32; } diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.txt index 8f34afe76..d6334e55b 100644 --- a/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.txt +++ b/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.txt @@ -1,5 +1,5 @@ -SOURCE_FILE@[0; 52) - FN_DEF@[0; 51) +SOURCE_FILE@[0; 82) + FN_DEF@[0; 81) FN_KW@[0; 2) "fn" WHITESPACE@[2; 3) " " NAME@[3; 6) @@ -8,8 +8,8 @@ SOURCE_FILE@[0; 52) L_PAREN@[6; 7) "(" R_PAREN@[7; 8) ")" WHITESPACE@[8; 9) " " - BLOCK_EXPR@[9; 51) - BLOCK@[9; 51) + BLOCK_EXPR@[9; 81) + BLOCK@[9; 81) L_CURLY@[9; 10) "{" WHITESPACE@[10; 15) "\n " LET_STMT@[15; 26) @@ -50,6 +50,33 @@ SOURCE_FILE@[0; 52) L_PAREN@[46; 47) "(" R_PAREN@[47; 48) ")" SEMI@[48; 49) ";" - WHITESPACE@[49; 50) "\n" - R_CURLY@[50; 51) "}" - WHITESPACE@[51; 52) "\n" + WHITESPACE@[49; 54) "\n " + LET_STMT@[54; 79) + LET_KW@[54; 57) "let" + WHITESPACE@[57; 58) " " + PLACEHOLDER_PAT@[58; 59) + UNDERSCORE@[58; 59) "_" + WHITESPACE@[59; 60) " " + EQ@[60; 61) "=" + WHITESPACE@[61; 62) " " + CAST_EXPR@[62; 78) + REF_EXPR@[62; 64) + AMP@[62; 63) "&" + LITERAL@[63; 64) + INT_NUMBER@[63; 64) "1" + WHITESPACE@[64; 65) " " + AS_KW@[65; 67) "as" + WHITESPACE@[67; 68) " " + POINTER_TYPE@[68; 78) + STAR@[68; 69) "*" + CONST_KW@[69; 74) "const" + WHITESPACE@[74; 75) " " + PATH_TYPE@[75; 78) + PATH@[75; 78) + PATH_SEGMENT@[75; 78) + NAME_REF@[75; 78) + IDENT@[75; 78) "i32" + SEMI@[78; 79) ";" + WHITESPACE@[79; 80) "\n" + R_CURLY@[80; 81) "}" + WHITESPACE@[81; 82) "\n" -- cgit v1.2.3