Merge pull request #20934 from Veykril/veykril/push-qtzmsqkzntpo

fix: Improve error recovery when parsing malformed function return types
This commit is contained in:
Lukas Wirth 2025-10-29 12:10:01 +00:00 committed by GitHub
commit 769ebafdc6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 189 additions and 0 deletions

View File

@ -588,6 +588,12 @@ fn closure_expr(p: &mut Parser<'_>) -> CompletedMarker {
}
params::param_list_closure(p);
if opt_ret_type(p) {
// test_err closure_ret_recovery
// fn foo() { || -> A> { let x = 1; } }
while p.at(T![>]) {
// recover from unbalanced return type brackets
p.err_and_bump("expected a curly brace");
}
// test lambda_ret_block
// fn main() { || -> i32 { 92 }(); }
block_expr(p);

View File

@ -424,6 +424,14 @@ fn fn_(p: &mut Parser<'_>, m: Marker) {
// fn bar() -> () {}
opt_ret_type(p);
// test_err fn_ret_recovery
// fn foo() -> A>]) { let x = 1; }
// fn foo() -> A>]) where T: Copy { let x = 1; }
while p.at(T![')']) | p.at(T![']']) | p.at(T![>]) {
// recover from unbalanced return type brackets
p.err_and_bump("expected a curly brace");
}
// test function_where_clause
// fn foo<T>() where T: Copy {}
generic_params::opt_where_clause(p);

View File

@ -749,6 +749,10 @@ mod err {
#[test]
fn bad_asm_expr() { run_and_expect_errors("test_data/parser/inline/err/bad_asm_expr.rs"); }
#[test]
fn closure_ret_recovery() {
run_and_expect_errors("test_data/parser/inline/err/closure_ret_recovery.rs");
}
#[test]
fn comma_after_default_values_syntax() {
run_and_expect_errors("test_data/parser/inline/err/comma_after_default_values_syntax.rs");
}
@ -773,6 +777,10 @@ mod err {
run_and_expect_errors("test_data/parser/inline/err/fn_pointer_type_missing_fn.rs");
}
#[test]
fn fn_ret_recovery() {
run_and_expect_errors("test_data/parser/inline/err/fn_ret_recovery.rs");
}
#[test]
fn gen_fn() {
run_and_expect_errors_with_edition(
"test_data/parser/inline/err/gen_fn.rs",

View File

@ -0,0 +1,52 @@
SOURCE_FILE
FN
FN_KW "fn"
WHITESPACE " "
NAME
IDENT "foo"
PARAM_LIST
L_PAREN "("
R_PAREN ")"
WHITESPACE " "
BLOCK_EXPR
STMT_LIST
L_CURLY "{"
WHITESPACE " "
CLOSURE_EXPR
PARAM_LIST
PIPE "|"
PIPE "|"
WHITESPACE " "
RET_TYPE
THIN_ARROW "->"
WHITESPACE " "
PATH_TYPE
PATH
PATH_SEGMENT
NAME_REF
IDENT "A"
ERROR
R_ANGLE ">"
WHITESPACE " "
BLOCK_EXPR
STMT_LIST
L_CURLY "{"
WHITESPACE " "
LET_STMT
LET_KW "let"
WHITESPACE " "
IDENT_PAT
NAME
IDENT "x"
WHITESPACE " "
EQ "="
WHITESPACE " "
LITERAL
INT_NUMBER "1"
SEMICOLON ";"
WHITESPACE " "
R_CURLY "}"
WHITESPACE " "
R_CURLY "}"
WHITESPACE "\n"
error 18: expected a curly brace

View File

@ -0,0 +1 @@
fn foo() { || -> A> { let x = 1; } }

View File

@ -0,0 +1,112 @@
SOURCE_FILE
FN
FN_KW "fn"
WHITESPACE " "
NAME
IDENT "foo"
PARAM_LIST
L_PAREN "("
R_PAREN ")"
WHITESPACE " "
RET_TYPE
THIN_ARROW "->"
WHITESPACE " "
PATH_TYPE
PATH
PATH_SEGMENT
NAME_REF
IDENT "A"
ERROR
R_ANGLE ">"
ERROR
R_BRACK "]"
ERROR
R_PAREN ")"
WHITESPACE " "
BLOCK_EXPR
STMT_LIST
L_CURLY "{"
WHITESPACE " "
LET_STMT
LET_KW "let"
WHITESPACE " "
IDENT_PAT
NAME
IDENT "x"
WHITESPACE " "
EQ "="
WHITESPACE " "
LITERAL
INT_NUMBER "1"
SEMICOLON ";"
WHITESPACE " "
R_CURLY "}"
WHITESPACE "\n"
FN
FN_KW "fn"
WHITESPACE " "
NAME
IDENT "foo"
PARAM_LIST
L_PAREN "("
R_PAREN ")"
WHITESPACE " "
RET_TYPE
THIN_ARROW "->"
WHITESPACE " "
PATH_TYPE
PATH
PATH_SEGMENT
NAME_REF
IDENT "A"
ERROR
R_ANGLE ">"
ERROR
R_BRACK "]"
ERROR
R_PAREN ")"
WHITESPACE " "
WHERE_CLAUSE
WHERE_KW "where"
WHITESPACE " "
WHERE_PRED
PATH_TYPE
PATH
PATH_SEGMENT
NAME_REF
IDENT "T"
COLON ":"
WHITESPACE " "
TYPE_BOUND_LIST
TYPE_BOUND
PATH_TYPE
PATH
PATH_SEGMENT
NAME_REF
IDENT "Copy"
WHITESPACE " "
BLOCK_EXPR
STMT_LIST
L_CURLY "{"
WHITESPACE " "
LET_STMT
LET_KW "let"
WHITESPACE " "
IDENT_PAT
NAME
IDENT "x"
WHITESPACE " "
EQ "="
WHITESPACE " "
LITERAL
INT_NUMBER "1"
SEMICOLON ";"
WHITESPACE " "
R_CURLY "}"
WHITESPACE "\n"
error 13: expected a curly brace
error 14: expected a curly brace
error 15: expected a curly brace
error 45: expected a curly brace
error 46: expected a curly brace
error 47: expected a curly brace

View File

@ -0,0 +1,2 @@
fn foo() -> A>]) { let x = 1; }
fn foo() -> A>]) where T: Copy { let x = 1; }