Skip to content

Commit 769ebaf

Browse files
authored
Merge pull request #20934 from Veykril/veykril/push-qtzmsqkzntpo
fix: Improve error recovery when parsing malformed function return types
2 parents d08d54f + 47c5af2 commit 769ebaf

File tree

7 files changed

+189
-0
lines changed

7 files changed

+189
-0
lines changed

crates/parser/src/grammar/expressions/atom.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,12 @@ fn closure_expr(p: &mut Parser<'_>) -> CompletedMarker {
588588
}
589589
params::param_list_closure(p);
590590
if opt_ret_type(p) {
591+
// test_err closure_ret_recovery
592+
// fn foo() { || -> A> { let x = 1; } }
593+
while p.at(T![>]) {
594+
// recover from unbalanced return type brackets
595+
p.err_and_bump("expected a curly brace");
596+
}
591597
// test lambda_ret_block
592598
// fn main() { || -> i32 { 92 }(); }
593599
block_expr(p);

crates/parser/src/grammar/items.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,14 @@ fn fn_(p: &mut Parser<'_>, m: Marker) {
424424
// fn bar() -> () {}
425425
opt_ret_type(p);
426426

427+
// test_err fn_ret_recovery
428+
// fn foo() -> A>]) { let x = 1; }
429+
// fn foo() -> A>]) where T: Copy { let x = 1; }
430+
while p.at(T![')']) | p.at(T![']']) | p.at(T![>]) {
431+
// recover from unbalanced return type brackets
432+
p.err_and_bump("expected a curly brace");
433+
}
434+
427435
// test function_where_clause
428436
// fn foo<T>() where T: Copy {}
429437
generic_params::opt_where_clause(p);

crates/parser/test_data/generated/runner.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,10 @@ mod err {
749749
#[test]
750750
fn bad_asm_expr() { run_and_expect_errors("test_data/parser/inline/err/bad_asm_expr.rs"); }
751751
#[test]
752+
fn closure_ret_recovery() {
753+
run_and_expect_errors("test_data/parser/inline/err/closure_ret_recovery.rs");
754+
}
755+
#[test]
752756
fn comma_after_default_values_syntax() {
753757
run_and_expect_errors("test_data/parser/inline/err/comma_after_default_values_syntax.rs");
754758
}
@@ -773,6 +777,10 @@ mod err {
773777
run_and_expect_errors("test_data/parser/inline/err/fn_pointer_type_missing_fn.rs");
774778
}
775779
#[test]
780+
fn fn_ret_recovery() {
781+
run_and_expect_errors("test_data/parser/inline/err/fn_ret_recovery.rs");
782+
}
783+
#[test]
776784
fn gen_fn() {
777785
run_and_expect_errors_with_edition(
778786
"test_data/parser/inline/err/gen_fn.rs",
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
SOURCE_FILE
2+
FN
3+
FN_KW "fn"
4+
WHITESPACE " "
5+
NAME
6+
IDENT "foo"
7+
PARAM_LIST
8+
L_PAREN "("
9+
R_PAREN ")"
10+
WHITESPACE " "
11+
BLOCK_EXPR
12+
STMT_LIST
13+
L_CURLY "{"
14+
WHITESPACE " "
15+
CLOSURE_EXPR
16+
PARAM_LIST
17+
PIPE "|"
18+
PIPE "|"
19+
WHITESPACE " "
20+
RET_TYPE
21+
THIN_ARROW "->"
22+
WHITESPACE " "
23+
PATH_TYPE
24+
PATH
25+
PATH_SEGMENT
26+
NAME_REF
27+
IDENT "A"
28+
ERROR
29+
R_ANGLE ">"
30+
WHITESPACE " "
31+
BLOCK_EXPR
32+
STMT_LIST
33+
L_CURLY "{"
34+
WHITESPACE " "
35+
LET_STMT
36+
LET_KW "let"
37+
WHITESPACE " "
38+
IDENT_PAT
39+
NAME
40+
IDENT "x"
41+
WHITESPACE " "
42+
EQ "="
43+
WHITESPACE " "
44+
LITERAL
45+
INT_NUMBER "1"
46+
SEMICOLON ";"
47+
WHITESPACE " "
48+
R_CURLY "}"
49+
WHITESPACE " "
50+
R_CURLY "}"
51+
WHITESPACE "\n"
52+
error 18: expected a curly brace
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn foo() { || -> A> { let x = 1; } }
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
SOURCE_FILE
2+
FN
3+
FN_KW "fn"
4+
WHITESPACE " "
5+
NAME
6+
IDENT "foo"
7+
PARAM_LIST
8+
L_PAREN "("
9+
R_PAREN ")"
10+
WHITESPACE " "
11+
RET_TYPE
12+
THIN_ARROW "->"
13+
WHITESPACE " "
14+
PATH_TYPE
15+
PATH
16+
PATH_SEGMENT
17+
NAME_REF
18+
IDENT "A"
19+
ERROR
20+
R_ANGLE ">"
21+
ERROR
22+
R_BRACK "]"
23+
ERROR
24+
R_PAREN ")"
25+
WHITESPACE " "
26+
BLOCK_EXPR
27+
STMT_LIST
28+
L_CURLY "{"
29+
WHITESPACE " "
30+
LET_STMT
31+
LET_KW "let"
32+
WHITESPACE " "
33+
IDENT_PAT
34+
NAME
35+
IDENT "x"
36+
WHITESPACE " "
37+
EQ "="
38+
WHITESPACE " "
39+
LITERAL
40+
INT_NUMBER "1"
41+
SEMICOLON ";"
42+
WHITESPACE " "
43+
R_CURLY "}"
44+
WHITESPACE "\n"
45+
FN
46+
FN_KW "fn"
47+
WHITESPACE " "
48+
NAME
49+
IDENT "foo"
50+
PARAM_LIST
51+
L_PAREN "("
52+
R_PAREN ")"
53+
WHITESPACE " "
54+
RET_TYPE
55+
THIN_ARROW "->"
56+
WHITESPACE " "
57+
PATH_TYPE
58+
PATH
59+
PATH_SEGMENT
60+
NAME_REF
61+
IDENT "A"
62+
ERROR
63+
R_ANGLE ">"
64+
ERROR
65+
R_BRACK "]"
66+
ERROR
67+
R_PAREN ")"
68+
WHITESPACE " "
69+
WHERE_CLAUSE
70+
WHERE_KW "where"
71+
WHITESPACE " "
72+
WHERE_PRED
73+
PATH_TYPE
74+
PATH
75+
PATH_SEGMENT
76+
NAME_REF
77+
IDENT "T"
78+
COLON ":"
79+
WHITESPACE " "
80+
TYPE_BOUND_LIST
81+
TYPE_BOUND
82+
PATH_TYPE
83+
PATH
84+
PATH_SEGMENT
85+
NAME_REF
86+
IDENT "Copy"
87+
WHITESPACE " "
88+
BLOCK_EXPR
89+
STMT_LIST
90+
L_CURLY "{"
91+
WHITESPACE " "
92+
LET_STMT
93+
LET_KW "let"
94+
WHITESPACE " "
95+
IDENT_PAT
96+
NAME
97+
IDENT "x"
98+
WHITESPACE " "
99+
EQ "="
100+
WHITESPACE " "
101+
LITERAL
102+
INT_NUMBER "1"
103+
SEMICOLON ";"
104+
WHITESPACE " "
105+
R_CURLY "}"
106+
WHITESPACE "\n"
107+
error 13: expected a curly brace
108+
error 14: expected a curly brace
109+
error 15: expected a curly brace
110+
error 45: expected a curly brace
111+
error 46: expected a curly brace
112+
error 47: expected a curly brace
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
fn foo() -> A>]) { let x = 1; }
2+
fn foo() -> A>]) where T: Copy { let x = 1; }

0 commit comments

Comments
 (0)