diff --git a/crates/ra_syntax/src/grammar/expressions.rs b/crates/ra_syntax/src/grammar/expressions.rs index 60c8602f9f..a9449c7bf8 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 { // test cast_expr // fn foo() { // 82 as i32; +// 81 as i8 + 1; +// 79 as i16 - 1; // } fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { assert!(p.at(AS_KW)); let m = lhs.precede(p); p.bump(); - types::type_(p); + // Use type_no_bounds(), because cast expressions are not + // allowed to have bounds. + types::type_no_bounds(p); m.complete(p, CAST_EXPR) } diff --git a/crates/ra_syntax/src/grammar/types.rs b/crates/ra_syntax/src/grammar/types.rs index ed2718e739..811d399d4e 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![ const TYPE_RECOVERY_SET: TokenSet = token_set![R_PAREN, COMMA]; pub(super) fn type_(p: &mut Parser) { + type_with_bounds_cond(p, true); +} + +pub(super) fn type_no_bounds(p: &mut Parser) { + type_with_bounds_cond(p, false); +} + +fn type_with_bounds_cond(p: &mut Parser, allow_bounds: bool) { match p.current() { L_PAREN => paren_or_tuple_type(p), EXCL => never_type(p), @@ -22,8 +30,9 @@ pub(super) fn type_(p: &mut Parser) { FOR_KW => for_type(p), IMPL_KW => impl_trait_type(p), DYN_KW => dyn_trait_type(p), - L_ANGLE => path_type(p), - _ if paths::is_path_start(p) => path_type(p), + // Some path types are not allowed to have bounds (no plus) + L_ANGLE => path_type_(p, allow_bounds), + _ if paths::is_path_start(p) => path_type_(p, allow_bounds), _ => { p.err_recover("expected type", TYPE_RECOVERY_SET); } @@ -35,10 +44,6 @@ pub(super) fn ascription(p: &mut Parser) { type_(p) } -fn type_no_plus(p: &mut Parser) { - type_(p); -} - fn paren_or_tuple_type(p: &mut Parser) { assert!(p.at(L_PAREN)); let m = p.start(); @@ -101,7 +106,7 @@ fn pointer_type(p: &mut Parser) { } }; - type_no_plus(p); + type_no_bounds(p); m.complete(p, POINTER_TYPE); } @@ -147,7 +152,7 @@ fn reference_type(p: &mut Parser) { p.bump(); p.eat(LIFETIME); p.eat(MUT_KW); - type_no_plus(p); + type_no_bounds(p); m.complete(p, REFERENCE_TYPE); } 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 3e53d56d64..b571a58608 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 @@ fn foo() { 82 as i32; + 81 as i8 + 1; + 79 as i16 - 1; } 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 a804399134..cb56aef0ba 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 @@ -SOURCE_FILE@[0; 28) - FN_DEF@[0; 27) +SOURCE_FILE@[0; 65) + FN_DEF@[0; 64) FN_KW@[0; 2) WHITESPACE@[2; 3) NAME@[3; 6) @@ -8,7 +8,7 @@ SOURCE_FILE@[0; 28) L_PAREN@[6; 7) R_PAREN@[7; 8) WHITESPACE@[8; 9) - BLOCK@[9; 27) + BLOCK@[9; 64) L_CURLY@[9; 10) WHITESPACE@[10; 15) EXPR_STMT@[15; 25) @@ -24,6 +24,46 @@ SOURCE_FILE@[0; 28) NAME_REF@[21; 24) IDENT@[21; 24) "i32" SEMI@[24; 25) - WHITESPACE@[25; 26) - R_CURLY@[26; 27) - WHITESPACE@[27; 28) + WHITESPACE@[25; 30) + EXPR_STMT@[30; 43) + BIN_EXPR@[30; 42) + CAST_EXPR@[30; 38) + LITERAL@[30; 32) + INT_NUMBER@[30; 32) "81" + WHITESPACE@[32; 33) + AS_KW@[33; 35) + WHITESPACE@[35; 36) + PATH_TYPE@[36; 38) + PATH@[36; 38) + PATH_SEGMENT@[36; 38) + NAME_REF@[36; 38) + IDENT@[36; 38) "i8" + WHITESPACE@[38; 39) + PLUS@[39; 40) + WHITESPACE@[40; 41) + LITERAL@[41; 42) + INT_NUMBER@[41; 42) "1" + SEMI@[42; 43) + WHITESPACE@[43; 48) + EXPR_STMT@[48; 62) + BIN_EXPR@[48; 61) + CAST_EXPR@[48; 57) + LITERAL@[48; 50) + INT_NUMBER@[48; 50) "79" + WHITESPACE@[50; 51) + AS_KW@[51; 53) + WHITESPACE@[53; 54) + PATH_TYPE@[54; 57) + PATH@[54; 57) + PATH_SEGMENT@[54; 57) + NAME_REF@[54; 57) + IDENT@[54; 57) "i16" + WHITESPACE@[57; 58) + MINUS@[58; 59) + WHITESPACE@[59; 60) + LITERAL@[60; 61) + INT_NUMBER@[60; 61) "1" + SEMI@[61; 62) + WHITESPACE@[62; 63) + R_CURLY@[63; 64) + WHITESPACE@[64; 65)