From f6188caaa0d226bef88418c9ff3f13a63ae95358 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 25 Mar 2020 16:41:50 +0100 Subject: Fix parsing lambdas with return type We should eat only a single block, and not whatever larger expression may start with a block. closes #3721 --- crates/ra_parser/src/grammar/expressions/atom.rs | 20 ++++++---- .../parser/err/0010_unsafe_lambda_block.txt | 30 ++++++++------- .../parser/inline/ok/0158_lambda_ret_block.rs | 1 + .../parser/inline/ok/0158_lambda_ret_block.txt | 45 ++++++++++++++++++++++ 4 files changed, 75 insertions(+), 21 deletions(-) create mode 100644 crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.rs create mode 100644 crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.txt (limited to 'crates') diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs index 2335d99b3..0d277a586 100644 --- a/crates/ra_parser/src/grammar/expressions/atom.rs +++ b/crates/ra_parser/src/grammar/expressions/atom.rs @@ -230,14 +230,20 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker { p.eat(T![async]); p.eat(T![move]); params::param_list_closure(p); - if opt_fn_ret_type(p) && !p.at(T!['{']) { - p.error("expected `{`"); - } - - if p.at_ts(EXPR_FIRST) { - expr(p); + if opt_fn_ret_type(p) { + if p.at(T!['{']) { + // test lambda_ret_block + // fn main() { || -> i32 { 92 }(); } + block_expr(p, None); + } else { + p.error("expected `{`"); + } } else { - p.error("expected expression"); + if p.at_ts(EXPR_FIRST) { + expr(p); + } else { + p.error("expected expression"); + } } m.complete(p, LAMBDA_EXPR) } diff --git a/crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.txt b/crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.txt index e0edf6a2d..0ffbd25aa 100644 --- a/crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.txt +++ b/crates/ra_syntax/test_data/parser/err/0010_unsafe_lambda_block.txt @@ -12,8 +12,8 @@ SOURCE_FILE@[0; 42) BLOCK@[10; 41) L_CURLY@[10; 11) "{" WHITESPACE@[11; 16) "\n " - EXPR_STMT@[16; 39) - LAMBDA_EXPR@[16; 38) + EXPR_STMT@[16; 24) + LAMBDA_EXPR@[16; 24) PARAM_LIST@[16; 18) PIPE@[16; 17) "|" PIPE@[17; 18) "|" @@ -24,20 +24,22 @@ SOURCE_FILE@[0; 42) TUPLE_TYPE@[22; 24) L_PAREN@[22; 23) "(" R_PAREN@[23; 24) ")" - WHITESPACE@[24; 25) " " - BLOCK_EXPR@[25; 38) - UNSAFE_KW@[25; 31) "unsafe" - WHITESPACE@[31; 32) " " - BLOCK@[32; 38) - L_CURLY@[32; 33) "{" - WHITESPACE@[33; 34) " " - TUPLE_EXPR@[34; 36) - L_PAREN@[34; 35) "(" - R_PAREN@[35; 36) ")" - WHITESPACE@[36; 37) " " - R_CURLY@[37; 38) "}" + WHITESPACE@[24; 25) " " + EXPR_STMT@[25; 39) + BLOCK_EXPR@[25; 38) + UNSAFE_KW@[25; 31) "unsafe" + WHITESPACE@[31; 32) " " + BLOCK@[32; 38) + L_CURLY@[32; 33) "{" + WHITESPACE@[33; 34) " " + TUPLE_EXPR@[34; 36) + L_PAREN@[34; 35) "(" + R_PAREN@[35; 36) ")" + WHITESPACE@[36; 37) " " + R_CURLY@[37; 38) "}" SEMI@[38; 39) ";" WHITESPACE@[39; 40) "\n" R_CURLY@[40; 41) "}" WHITESPACE@[41; 42) "\n" error [24; 24): expected `{` +error [24; 24): expected SEMI diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.rs b/crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.rs new file mode 100644 index 000000000..061118d3a --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.rs @@ -0,0 +1 @@ +fn main() { || -> i32 { 92 }(); } diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.txt b/crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.txt new file mode 100644 index 000000000..ba8779094 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0158_lambda_ret_block.txt @@ -0,0 +1,45 @@ +SOURCE_FILE@[0; 34) + FN_DEF@[0; 33) + FN_KW@[0; 2) "fn" + WHITESPACE@[2; 3) " " + NAME@[3; 7) + IDENT@[3; 7) "main" + PARAM_LIST@[7; 9) + L_PAREN@[7; 8) "(" + R_PAREN@[8; 9) ")" + WHITESPACE@[9; 10) " " + BLOCK_EXPR@[10; 33) + BLOCK@[10; 33) + L_CURLY@[10; 11) "{" + WHITESPACE@[11; 12) " " + EXPR_STMT@[12; 31) + CALL_EXPR@[12; 30) + LAMBDA_EXPR@[12; 28) + PARAM_LIST@[12; 14) + PIPE@[12; 13) "|" + PIPE@[13; 14) "|" + WHITESPACE@[14; 15) " " + RET_TYPE@[15; 21) + THIN_ARROW@[15; 17) "->" + WHITESPACE@[17; 18) " " + PATH_TYPE@[18; 21) + PATH@[18; 21) + PATH_SEGMENT@[18; 21) + NAME_REF@[18; 21) + IDENT@[18; 21) "i32" + WHITESPACE@[21; 22) " " + BLOCK_EXPR@[22; 28) + BLOCK@[22; 28) + L_CURLY@[22; 23) "{" + WHITESPACE@[23; 24) " " + LITERAL@[24; 26) + INT_NUMBER@[24; 26) "92" + WHITESPACE@[26; 27) " " + R_CURLY@[27; 28) "}" + ARG_LIST@[28; 30) + L_PAREN@[28; 29) "(" + R_PAREN@[29; 30) ")" + SEMI@[30; 31) ";" + WHITESPACE@[31; 32) " " + R_CURLY@[32; 33) "}" + WHITESPACE@[33; 34) "\n" -- cgit v1.2.3