mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-28 14:03:35 +00:00
feat: improve parser error recovery for function parameters
This commit is contained in:
parent
a2f83c956e
commit
15f11dce4a
10 changed files with 106 additions and 21 deletions
|
@ -101,6 +101,20 @@ fn baz(file$0) {}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_param_completion_first_param() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
fn foo(file_id: FileId) {}
|
||||||
|
fn bar(file_id: FileId) {}
|
||||||
|
fn baz(file$0 id: u32) {}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
bn file_id: FileId
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_param_completion_nth_param() {
|
fn test_param_completion_nth_param() {
|
||||||
check(
|
check(
|
||||||
|
|
|
@ -21,8 +21,11 @@ fn const_or_static(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) {
|
||||||
|
|
||||||
// test_err static_underscore
|
// test_err static_underscore
|
||||||
// static _: i32 = 5;
|
// static _: i32 = 5;
|
||||||
|
if p.at(T![:]) {
|
||||||
types::ascription(p);
|
types::ascription(p);
|
||||||
|
} else {
|
||||||
|
p.error("missing type for `const` or `static`")
|
||||||
|
}
|
||||||
if p.eat(T![=]) {
|
if p.eat(T![=]) {
|
||||||
expressions::expr(p);
|
expressions::expr(p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,13 @@ fn param(p: &mut Parser, m: Marker, flavor: Flavor) -> Variadic {
|
||||||
if variadic_param(p) {
|
if variadic_param(p) {
|
||||||
res = Variadic(true)
|
res = Variadic(true)
|
||||||
} else {
|
} else {
|
||||||
types::ascription(p);
|
if p.at(T![:]) {
|
||||||
|
types::ascription(p)
|
||||||
|
} else {
|
||||||
|
// test_err missing_fn_param_type
|
||||||
|
// fn f(x y: i32, z, t: i32) {}
|
||||||
|
p.error("missing type for function parameter")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// test value_parameters_no_patterns
|
// test value_parameters_no_patterns
|
||||||
|
@ -126,7 +132,11 @@ fn param(p: &mut Parser, m: Marker, flavor: Flavor) -> Variadic {
|
||||||
if variadic_param(p) {
|
if variadic_param(p) {
|
||||||
res = Variadic(true)
|
res = Variadic(true)
|
||||||
} else {
|
} else {
|
||||||
types::ascription(p);
|
if p.at(T![:]) {
|
||||||
|
types::ascription(p)
|
||||||
|
} else {
|
||||||
|
p.error("missing type for function parameter")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
types::type_(p);
|
types::type_(p);
|
||||||
|
|
|
@ -67,7 +67,11 @@ fn const_param(p: &mut Parser, m: Marker) {
|
||||||
assert!(p.at(T![const]));
|
assert!(p.at(T![const]));
|
||||||
p.bump(T![const]);
|
p.bump(T![const]);
|
||||||
name(p);
|
name(p);
|
||||||
types::ascription(p);
|
if p.at(T![:]) {
|
||||||
|
types::ascription(p);
|
||||||
|
} else {
|
||||||
|
p.error("missing type for const parameter");
|
||||||
|
}
|
||||||
|
|
||||||
// test const_param_defaults
|
// test const_param_defaults
|
||||||
// struct A<const N: i32 = -1>;
|
// struct A<const N: i32 = -1>;
|
||||||
|
|
|
@ -55,7 +55,8 @@ fn type_with_bounds_cond(p: &mut Parser, allow_bounds: bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn ascription(p: &mut Parser) {
|
pub(super) fn ascription(p: &mut Parser) {
|
||||||
p.expect(T![:]);
|
assert!(p.at(T![:]));
|
||||||
|
p.bump(T![:]);
|
||||||
type_(p)
|
type_(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,6 @@ SOURCE_FILE@0..183
|
||||||
R_CURLY@181..182 "}"
|
R_CURLY@181..182 "}"
|
||||||
WHITESPACE@182..183 "\n"
|
WHITESPACE@182..183 "\n"
|
||||||
error 34..34: expected pattern
|
error 34..34: expected pattern
|
||||||
error 34..34: expected COLON
|
error 34..34: missing type for function parameter
|
||||||
error 34..34: expected type
|
|
||||||
error 180..180: expected function arguments
|
error 180..180: expected function arguments
|
||||||
error 180..180: expected a block
|
error 180..180: expected a block
|
||||||
|
|
|
@ -30,5 +30,4 @@ SOURCE_FILE@0..22
|
||||||
WHITESPACE@19..20 "\n"
|
WHITESPACE@19..20 "\n"
|
||||||
R_CURLY@20..21 "}"
|
R_CURLY@20..21 "}"
|
||||||
WHITESPACE@21..22 "\n"
|
WHITESPACE@21..22 "\n"
|
||||||
error 16..16: expected COLON
|
error 16..16: missing type for function parameter
|
||||||
error 16..16: expected type
|
|
||||||
|
|
|
@ -17,22 +17,22 @@ SOURCE_FILE@0..50
|
||||||
L_CURLY@22..23 "{"
|
L_CURLY@22..23 "{"
|
||||||
R_CURLY@23..24 "}"
|
R_CURLY@23..24 "}"
|
||||||
WHITESPACE@24..25 "\n"
|
WHITESPACE@24..25 "\n"
|
||||||
CONST@25..46
|
CONST@25..40
|
||||||
UNSAFE_KW@25..31 "unsafe"
|
UNSAFE_KW@25..31 "unsafe"
|
||||||
WHITESPACE@31..32 " "
|
WHITESPACE@31..32 " "
|
||||||
CONST_KW@32..37 "const"
|
CONST_KW@32..37 "const"
|
||||||
WHITESPACE@37..38 " "
|
WHITESPACE@37..38 " "
|
||||||
ERROR@38..40
|
ERROR@38..40
|
||||||
FN_KW@38..40 "fn"
|
FN_KW@38..40 "fn"
|
||||||
WHITESPACE@40..41 " "
|
WHITESPACE@40..41 " "
|
||||||
PATH_TYPE@41..46
|
MACRO_CALL@41..46
|
||||||
PATH@41..46
|
PATH@41..44
|
||||||
PATH_SEGMENT@41..46
|
PATH_SEGMENT@41..44
|
||||||
NAME_REF@41..44
|
NAME_REF@41..44
|
||||||
IDENT@41..44 "bar"
|
IDENT@41..44 "bar"
|
||||||
PARAM_LIST@44..46
|
TOKEN_TREE@44..46
|
||||||
L_PAREN@44..45 "("
|
L_PAREN@44..45 "("
|
||||||
R_PAREN@45..46 ")"
|
R_PAREN@45..46 ")"
|
||||||
WHITESPACE@46..47 " "
|
WHITESPACE@46..47 " "
|
||||||
ERROR@47..49
|
ERROR@47..49
|
||||||
L_CURLY@47..48 "{"
|
L_CURLY@47..48 "{"
|
||||||
|
@ -40,6 +40,8 @@ SOURCE_FILE@0..50
|
||||||
WHITESPACE@49..50 "\n"
|
WHITESPACE@49..50 "\n"
|
||||||
error 6..6: expected existential, fn, trait or impl
|
error 6..6: expected existential, fn, trait or impl
|
||||||
error 38..38: expected a name
|
error 38..38: expected a name
|
||||||
error 40..40: expected COLON
|
error 40..40: missing type for `const` or `static`
|
||||||
|
error 40..40: expected SEMICOLON
|
||||||
|
error 44..44: expected BANG
|
||||||
error 46..46: expected SEMICOLON
|
error 46..46: expected SEMICOLON
|
||||||
error 47..47: expected an item
|
error 47..47: expected an item
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
SOURCE_FILE@0..29
|
||||||
|
FN@0..28
|
||||||
|
FN_KW@0..2 "fn"
|
||||||
|
WHITESPACE@2..3 " "
|
||||||
|
NAME@3..4
|
||||||
|
IDENT@3..4 "f"
|
||||||
|
PARAM_LIST@4..25
|
||||||
|
L_PAREN@4..5 "("
|
||||||
|
PARAM@5..6
|
||||||
|
IDENT_PAT@5..6
|
||||||
|
NAME@5..6
|
||||||
|
IDENT@5..6 "x"
|
||||||
|
WHITESPACE@6..7 " "
|
||||||
|
PARAM@7..13
|
||||||
|
IDENT_PAT@7..8
|
||||||
|
NAME@7..8
|
||||||
|
IDENT@7..8 "y"
|
||||||
|
COLON@8..9 ":"
|
||||||
|
WHITESPACE@9..10 " "
|
||||||
|
PATH_TYPE@10..13
|
||||||
|
PATH@10..13
|
||||||
|
PATH_SEGMENT@10..13
|
||||||
|
NAME_REF@10..13
|
||||||
|
IDENT@10..13 "i32"
|
||||||
|
COMMA@13..14 ","
|
||||||
|
WHITESPACE@14..15 " "
|
||||||
|
PARAM@15..16
|
||||||
|
IDENT_PAT@15..16
|
||||||
|
NAME@15..16
|
||||||
|
IDENT@15..16 "z"
|
||||||
|
COMMA@16..17 ","
|
||||||
|
WHITESPACE@17..18 " "
|
||||||
|
PARAM@18..24
|
||||||
|
IDENT_PAT@18..19
|
||||||
|
NAME@18..19
|
||||||
|
IDENT@18..19 "t"
|
||||||
|
COLON@19..20 ":"
|
||||||
|
WHITESPACE@20..21 " "
|
||||||
|
PATH_TYPE@21..24
|
||||||
|
PATH@21..24
|
||||||
|
PATH_SEGMENT@21..24
|
||||||
|
NAME_REF@21..24
|
||||||
|
IDENT@21..24 "i32"
|
||||||
|
R_PAREN@24..25 ")"
|
||||||
|
WHITESPACE@25..26 " "
|
||||||
|
BLOCK_EXPR@26..28
|
||||||
|
L_CURLY@26..27 "{"
|
||||||
|
R_CURLY@27..28 "}"
|
||||||
|
WHITESPACE@28..29 "\n"
|
||||||
|
error 6..6: missing type for function parameter
|
||||||
|
error 6..6: expected COMMA
|
||||||
|
error 16..16: missing type for function parameter
|
|
@ -0,0 +1 @@
|
||||||
|
fn f(x y: i32, z, t: i32) {}
|
Loading…
Reference in a new issue