aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2018-12-17 19:43:51 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2018-12-17 19:43:51 +0000
commit1875aa024f885f1d6119bff8aa828634b4941248 (patch)
tree273bdffe892f2eeef1850e2d3f7b1ca9ed228285
parent8d42deeac354d1f8297d6c4d52b2707fb8d7a771 (diff)
parentd0f1334226fc25a8c00ecccd64c0021e4aef9ca5 (diff)
Merge #280
280: Fixed cast expression parsing in ra_syntax. r=matklad a=ruabmbua Fixes #279 Related to https://github.com/rust-analyzer/rust-analyzer/pull/273 The cast expression expected any type via types::type_() function, but the language spec does only allow TypeNoBounds (types without direct extra bounds via `+`). **Example:** ```rust fn test() { 6i8 as i32 + 5; } ``` This fails, because the types::type_() function which should parse the type after the as keyword is greedy, and takes the plus sign after path types as extra type bounds. My proposed fix is to replace the not implemented `type_no_plus()` just calls (`type_()`) function, which is used at several places. The replacement is `type_with_bounds_cond(p: &mut Parser, allow_bounds: bool)`, which passes the condition to relevant sub-parsers. This function is then called by `type_()` and the new public `type_no_bounds()`. Co-authored-by: Roland Ruckerbauer <[email protected]>
-rw-r--r--crates/ra_syntax/src/grammar/expressions.rs6
-rw-r--r--crates/ra_syntax/src/grammar/types.rs21
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.rs2
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.txt52
4 files changed, 66 insertions, 15 deletions
diff --git a/crates/ra_syntax/src/grammar/expressions.rs b/crates/ra_syntax/src/grammar/expressions.rs
index 60c8602f9..a9449c7bf 100644
--- a/crates/ra_syntax/src/grammar/expressions.rs
+++ b/crates/ra_syntax/src/grammar/expressions.rs
@@ -368,12 +368,16 @@ fn try_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
368// test cast_expr 368// test cast_expr
369// fn foo() { 369// fn foo() {
370// 82 as i32; 370// 82 as i32;
371// 81 as i8 + 1;
372// 79 as i16 - 1;
371// } 373// }
372fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { 374fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
373 assert!(p.at(AS_KW)); 375 assert!(p.at(AS_KW));
374 let m = lhs.precede(p); 376 let m = lhs.precede(p);
375 p.bump(); 377 p.bump();
376 types::type_(p); 378 // Use type_no_bounds(), because cast expressions are not
379 // allowed to have bounds.
380 types::type_no_bounds(p);
377 m.complete(p, CAST_EXPR) 381 m.complete(p, CAST_EXPR)
378} 382}
379 383
diff --git a/crates/ra_syntax/src/grammar/types.rs b/crates/ra_syntax/src/grammar/types.rs
index ed2718e73..811d399d4 100644
--- a/crates/ra_syntax/src/grammar/types.rs
+++ b/crates/ra_syntax/src/grammar/types.rs
@@ -11,6 +11,14 @@ pub(super) const TYPE_FIRST: TokenSet = token_set_union![
11const TYPE_RECOVERY_SET: TokenSet = token_set![R_PAREN, COMMA]; 11const TYPE_RECOVERY_SET: TokenSet = token_set![R_PAREN, COMMA];
12 12
13pub(super) fn type_(p: &mut Parser) { 13pub(super) fn type_(p: &mut Parser) {
14 type_with_bounds_cond(p, true);
15}
16
17pub(super) fn type_no_bounds(p: &mut Parser) {
18 type_with_bounds_cond(p, false);
19}
20
21fn type_with_bounds_cond(p: &mut Parser, allow_bounds: bool) {
14 match p.current() { 22 match p.current() {
15 L_PAREN => paren_or_tuple_type(p), 23 L_PAREN => paren_or_tuple_type(p),
16 EXCL => never_type(p), 24 EXCL => never_type(p),
@@ -22,8 +30,9 @@ pub(super) fn type_(p: &mut Parser) {
22 FOR_KW => for_type(p), 30 FOR_KW => for_type(p),
23 IMPL_KW => impl_trait_type(p), 31 IMPL_KW => impl_trait_type(p),
24 DYN_KW => dyn_trait_type(p), 32 DYN_KW => dyn_trait_type(p),
25 L_ANGLE => path_type(p), 33 // Some path types are not allowed to have bounds (no plus)
26 _ if paths::is_path_start(p) => path_type(p), 34 L_ANGLE => path_type_(p, allow_bounds),
35 _ if paths::is_path_start(p) => path_type_(p, allow_bounds),
27 _ => { 36 _ => {
28 p.err_recover("expected type", TYPE_RECOVERY_SET); 37 p.err_recover("expected type", TYPE_RECOVERY_SET);
29 } 38 }
@@ -35,10 +44,6 @@ pub(super) fn ascription(p: &mut Parser) {
35 type_(p) 44 type_(p)
36} 45}
37 46
38fn type_no_plus(p: &mut Parser) {
39 type_(p);
40}
41
42fn paren_or_tuple_type(p: &mut Parser) { 47fn paren_or_tuple_type(p: &mut Parser) {
43 assert!(p.at(L_PAREN)); 48 assert!(p.at(L_PAREN));
44 let m = p.start(); 49 let m = p.start();
@@ -101,7 +106,7 @@ fn pointer_type(p: &mut Parser) {
101 } 106 }
102 }; 107 };
103 108
104 type_no_plus(p); 109 type_no_bounds(p);
105 m.complete(p, POINTER_TYPE); 110 m.complete(p, POINTER_TYPE);
106} 111}
107 112
@@ -147,7 +152,7 @@ fn reference_type(p: &mut Parser) {
147 p.bump(); 152 p.bump();
148 p.eat(LIFETIME); 153 p.eat(LIFETIME);
149 p.eat(MUT_KW); 154 p.eat(MUT_KW);
150 type_no_plus(p); 155 type_no_bounds(p);
151 m.complete(p, REFERENCE_TYPE); 156 m.complete(p, REFERENCE_TYPE);
152} 157}
153 158
diff --git a/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.rs
index 3e53d56d6..b571a5860 100644
--- a/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.rs
+++ b/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.rs
@@ -1,3 +1,5 @@
1fn foo() { 1fn foo() {
2 82 as i32; 2 82 as i32;
3 81 as i8 + 1;
4 79 as i16 - 1;
3} 5}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.txt
index a80439913..cb56aef0b 100644
--- a/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 28) 1SOURCE_FILE@[0; 65)
2 FN_DEF@[0; 27) 2 FN_DEF@[0; 64)
3 FN_KW@[0; 2) 3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3) 4 WHITESPACE@[2; 3)
5 NAME@[3; 6) 5 NAME@[3; 6)
@@ -8,7 +8,7 @@ SOURCE_FILE@[0; 28)
8 L_PAREN@[6; 7) 8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8) 9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9) 10 WHITESPACE@[8; 9)
11 BLOCK@[9; 27) 11 BLOCK@[9; 64)
12 L_CURLY@[9; 10) 12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15) 13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 25) 14 EXPR_STMT@[15; 25)
@@ -24,6 +24,46 @@ SOURCE_FILE@[0; 28)
24 NAME_REF@[21; 24) 24 NAME_REF@[21; 24)
25 IDENT@[21; 24) "i32" 25 IDENT@[21; 24) "i32"
26 SEMI@[24; 25) 26 SEMI@[24; 25)
27 WHITESPACE@[25; 26) 27 WHITESPACE@[25; 30)
28 R_CURLY@[26; 27) 28 EXPR_STMT@[30; 43)
29 WHITESPACE@[27; 28) 29 BIN_EXPR@[30; 42)
30 CAST_EXPR@[30; 38)
31 LITERAL@[30; 32)
32 INT_NUMBER@[30; 32) "81"
33 WHITESPACE@[32; 33)
34 AS_KW@[33; 35)
35 WHITESPACE@[35; 36)
36 PATH_TYPE@[36; 38)
37 PATH@[36; 38)
38 PATH_SEGMENT@[36; 38)
39 NAME_REF@[36; 38)
40 IDENT@[36; 38) "i8"
41 WHITESPACE@[38; 39)
42 PLUS@[39; 40)
43 WHITESPACE@[40; 41)
44 LITERAL@[41; 42)
45 INT_NUMBER@[41; 42) "1"
46 SEMI@[42; 43)
47 WHITESPACE@[43; 48)
48 EXPR_STMT@[48; 62)
49 BIN_EXPR@[48; 61)
50 CAST_EXPR@[48; 57)
51 LITERAL@[48; 50)
52 INT_NUMBER@[48; 50) "79"
53 WHITESPACE@[50; 51)
54 AS_KW@[51; 53)
55 WHITESPACE@[53; 54)
56 PATH_TYPE@[54; 57)
57 PATH@[54; 57)
58 PATH_SEGMENT@[54; 57)
59 NAME_REF@[54; 57)
60 IDENT@[54; 57) "i16"
61 WHITESPACE@[57; 58)
62 MINUS@[58; 59)
63 WHITESPACE@[59; 60)
64 LITERAL@[60; 61)
65 INT_NUMBER@[60; 61) "1"
66 SEMI@[61; 62)
67 WHITESPACE@[62; 63)
68 R_CURLY@[63; 64)
69 WHITESPACE@[64; 65)