aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/grammar
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/grammar')
-rw-r--r--crates/ra_syntax/src/grammar/expressions.rs6
-rw-r--r--crates/ra_syntax/src/grammar/types.rs21
2 files changed, 18 insertions, 9 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