diff options
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 | // } |
372 | fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | 374 | fn 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![ | |||
11 | const TYPE_RECOVERY_SET: TokenSet = token_set![R_PAREN, COMMA]; | 11 | const TYPE_RECOVERY_SET: TokenSet = token_set![R_PAREN, COMMA]; |
12 | 12 | ||
13 | pub(super) fn type_(p: &mut Parser) { | 13 | pub(super) fn type_(p: &mut Parser) { |
14 | type_with_bounds_cond(p, true); | ||
15 | } | ||
16 | |||
17 | pub(super) fn type_no_bounds(p: &mut Parser) { | ||
18 | type_with_bounds_cond(p, false); | ||
19 | } | ||
20 | |||
21 | fn 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 | ||
38 | fn type_no_plus(p: &mut Parser) { | ||
39 | type_(p); | ||
40 | } | ||
41 | |||
42 | fn paren_or_tuple_type(p: &mut Parser) { | 47 | fn 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 @@ | |||
1 | fn foo() { | 1 | fn 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 @@ | |||
1 | SOURCE_FILE@[0; 28) | 1 | SOURCE_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) | ||