Skip to content

Commit d9338df

Browse files
bors[bot]goffrie
andauthored
Merge #1951
1951: Lower the precedence of the `as` operator. r=matklad a=goffrie 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. Fixes #1851. Co-authored-by: Geoffry Song <[email protected]>
2 parents 523d7d2 + b4fe06b commit d9338df

File tree

5 files changed

+160
-1
lines changed

5 files changed

+160
-1
lines changed

crates/ra_parser/src/grammar/expressions.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ fn current_op(p: &Parser) -> (u8, SyntaxKind) {
250250
T![!] if p.at(T![!=]) => (5, T![!=]),
251251
T![-] if p.at(T![-=]) => (1, T![-=]),
252252
T![-] => (10, T![-]),
253+
T![as] => (12, T![as]),
253254

254255
_ => NOT_AN_OP
255256
}
@@ -278,6 +279,14 @@ fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> (Option<CompletedMarker>,
278279
if op_bp < bp {
279280
break;
280281
}
282+
// test as_precedence
283+
// fn foo() {
284+
// let _ = &1 as *const i32;
285+
// }
286+
if p.at(T![as]) {
287+
lhs = cast_expr(p, lhs);
288+
continue;
289+
}
281290
let m = lhs.precede(p);
282291
p.bump(op);
283292

@@ -344,6 +353,7 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)>
344353
));
345354
}
346355
};
356+
// parse the interior of the unary expression
347357
expr_bp(p, r, 255);
348358
Some((m.complete(p, kind), BlockLike::NotBlock))
349359
}
@@ -378,7 +388,6 @@ fn postfix_expr(
378388
}
379389
},
380390
T![?] => try_expr(p, lhs),
381-
T![as] => cast_expr(p, lhs),
382391
_ => break,
383392
};
384393
allow_calls = true;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn foo() {
2+
let _ = &1 as *const i32;
3+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
SOURCE_FILE@[0; 43)
2+
FN_DEF@[0; 42)
3+
FN_KW@[0; 2) "fn"
4+
WHITESPACE@[2; 3) " "
5+
NAME@[3; 6)
6+
IDENT@[3; 6) "foo"
7+
PARAM_LIST@[6; 8)
8+
L_PAREN@[6; 7) "("
9+
R_PAREN@[7; 8) ")"
10+
WHITESPACE@[8; 9) " "
11+
BLOCK_EXPR@[9; 42)
12+
BLOCK@[9; 42)
13+
L_CURLY@[9; 10) "{"
14+
WHITESPACE@[10; 15) "\n "
15+
LET_STMT@[15; 40)
16+
LET_KW@[15; 18) "let"
17+
WHITESPACE@[18; 19) " "
18+
PLACEHOLDER_PAT@[19; 20)
19+
UNDERSCORE@[19; 20) "_"
20+
WHITESPACE@[20; 21) " "
21+
EQ@[21; 22) "="
22+
WHITESPACE@[22; 23) " "
23+
CAST_EXPR@[23; 39)
24+
REF_EXPR@[23; 25)
25+
AMP@[23; 24) "&"
26+
LITERAL@[24; 25)
27+
INT_NUMBER@[24; 25) "1"
28+
WHITESPACE@[25; 26) " "
29+
AS_KW@[26; 28) "as"
30+
WHITESPACE@[28; 29) " "
31+
POINTER_TYPE@[29; 39)
32+
STAR@[29; 30) "*"
33+
CONST_KW@[30; 35) "const"
34+
WHITESPACE@[35; 36) " "
35+
PATH_TYPE@[36; 39)
36+
PATH@[36; 39)
37+
PATH_SEGMENT@[36; 39)
38+
NAME_REF@[36; 39)
39+
IDENT@[36; 39) "i32"
40+
SEMI@[39; 40) ";"
41+
WHITESPACE@[40; 41) "\n"
42+
R_CURLY@[41; 42) "}"
43+
WHITESPACE@[42; 43) "\n"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn foo() {
2+
1 + *&2 + 3;
3+
*&1 as u64;
4+
*x(1);
5+
&x[1];
6+
-1..2;
7+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
SOURCE_FILE@[0; 79)
2+
FN_DEF@[0; 78)
3+
FN_KW@[0; 2) "fn"
4+
WHITESPACE@[2; 3) " "
5+
NAME@[3; 6)
6+
IDENT@[3; 6) "foo"
7+
PARAM_LIST@[6; 8)
8+
L_PAREN@[6; 7) "("
9+
R_PAREN@[7; 8) ")"
10+
WHITESPACE@[8; 9) " "
11+
BLOCK_EXPR@[9; 78)
12+
BLOCK@[9; 78)
13+
L_CURLY@[9; 10) "{"
14+
WHITESPACE@[10; 15) "\n "
15+
EXPR_STMT@[15; 27)
16+
BIN_EXPR@[15; 26)
17+
BIN_EXPR@[15; 22)
18+
LITERAL@[15; 16)
19+
INT_NUMBER@[15; 16) "1"
20+
WHITESPACE@[16; 17) " "
21+
PLUS@[17; 18) "+"
22+
WHITESPACE@[18; 19) " "
23+
PREFIX_EXPR@[19; 22)
24+
STAR@[19; 20) "*"
25+
REF_EXPR@[20; 22)
26+
AMP@[20; 21) "&"
27+
LITERAL@[21; 22)
28+
INT_NUMBER@[21; 22) "2"
29+
WHITESPACE@[22; 23) " "
30+
PLUS@[23; 24) "+"
31+
WHITESPACE@[24; 25) " "
32+
LITERAL@[25; 26)
33+
INT_NUMBER@[25; 26) "3"
34+
SEMI@[26; 27) ";"
35+
WHITESPACE@[27; 32) "\n "
36+
EXPR_STMT@[32; 43)
37+
CAST_EXPR@[32; 42)
38+
PREFIX_EXPR@[32; 35)
39+
STAR@[32; 33) "*"
40+
REF_EXPR@[33; 35)
41+
AMP@[33; 34) "&"
42+
LITERAL@[34; 35)
43+
INT_NUMBER@[34; 35) "1"
44+
WHITESPACE@[35; 36) " "
45+
AS_KW@[36; 38) "as"
46+
WHITESPACE@[38; 39) " "
47+
PATH_TYPE@[39; 42)
48+
PATH@[39; 42)
49+
PATH_SEGMENT@[39; 42)
50+
NAME_REF@[39; 42)
51+
IDENT@[39; 42) "u64"
52+
SEMI@[42; 43) ";"
53+
WHITESPACE@[43; 48) "\n "
54+
EXPR_STMT@[48; 54)
55+
PREFIX_EXPR@[48; 53)
56+
STAR@[48; 49) "*"
57+
CALL_EXPR@[49; 53)
58+
PATH_EXPR@[49; 50)
59+
PATH@[49; 50)
60+
PATH_SEGMENT@[49; 50)
61+
NAME_REF@[49; 50)
62+
IDENT@[49; 50) "x"
63+
ARG_LIST@[50; 53)
64+
L_PAREN@[50; 51) "("
65+
LITERAL@[51; 52)
66+
INT_NUMBER@[51; 52) "1"
67+
R_PAREN@[52; 53) ")"
68+
SEMI@[53; 54) ";"
69+
WHITESPACE@[54; 59) "\n "
70+
EXPR_STMT@[59; 65)
71+
REF_EXPR@[59; 64)
72+
AMP@[59; 60) "&"
73+
INDEX_EXPR@[60; 64)
74+
PATH_EXPR@[60; 61)
75+
PATH@[60; 61)
76+
PATH_SEGMENT@[60; 61)
77+
NAME_REF@[60; 61)
78+
IDENT@[60; 61) "x"
79+
L_BRACK@[61; 62) "["
80+
LITERAL@[62; 63)
81+
INT_NUMBER@[62; 63) "1"
82+
R_BRACK@[63; 64) "]"
83+
SEMI@[64; 65) ";"
84+
WHITESPACE@[65; 70) "\n "
85+
EXPR_STMT@[70; 76)
86+
RANGE_EXPR@[70; 75)
87+
PREFIX_EXPR@[70; 72)
88+
MINUS@[70; 71) "-"
89+
LITERAL@[71; 72)
90+
INT_NUMBER@[71; 72) "1"
91+
DOTDOT@[72; 74) ".."
92+
LITERAL@[74; 75)
93+
INT_NUMBER@[74; 75) "2"
94+
SEMI@[75; 76) ";"
95+
WHITESPACE@[76; 77) "\n"
96+
R_CURLY@[77; 78) "}"
97+
WHITESPACE@[78; 79) "\n"

0 commit comments

Comments
 (0)