Skip to content

Commit e3ece38

Browse files
authored
Merge pull request rust-lang#20886 from A4-Tacks/parse-missing-method-name
Improve parsing of missing name in MethodCallExpr
2 parents 1b94579 + 922aad6 commit e3ece38

File tree

4 files changed

+55
-5
lines changed

4 files changed

+55
-5
lines changed

src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,11 @@ fn postfix_expr(
430430
// }
431431
T!['('] if allow_calls => call_expr(p, lhs),
432432
T!['['] if allow_calls => index_expr(p, lhs),
433+
// test_err postfix_dot_expr_ambiguity
434+
// fn foo() {
435+
// x.
436+
// ()
437+
// }
433438
T![.] => match postfix_dot_expr::<false>(p, lhs) {
434439
Ok(it) => it,
435440
Err(it) => {
@@ -458,6 +463,7 @@ fn postfix_dot_expr<const FLOAT_RECOVERY: bool>(
458463

459464
if PATH_NAME_REF_KINDS.contains(p.nth(nth1))
460465
&& (p.nth(nth2) == T!['('] || p.nth_at(nth2, T![::]))
466+
|| p.nth(nth1) == T!['(']
461467
{
462468
return Ok(method_call_expr::<FLOAT_RECOVERY>(p, lhs));
463469
}
@@ -526,19 +532,26 @@ fn method_call_expr<const FLOAT_RECOVERY: bool>(
526532
lhs: CompletedMarker,
527533
) -> CompletedMarker {
528534
if FLOAT_RECOVERY {
529-
assert!(p.at_ts(PATH_NAME_REF_KINDS) && (p.nth(1) == T!['('] || p.nth_at(1, T![::])));
535+
assert!(
536+
p.at_ts(PATH_NAME_REF_KINDS) && (p.nth(1) == T!['('] || p.nth_at(1, T![::]))
537+
|| p.current() == T!['(']
538+
);
530539
} else {
540+
assert!(p.at(T![.]));
531541
assert!(
532-
p.at(T![.])
533-
&& PATH_NAME_REF_KINDS.contains(p.nth(1))
534-
&& (p.nth(2) == T!['('] || p.nth_at(2, T![::]))
542+
PATH_NAME_REF_KINDS.contains(p.nth(1)) && (p.nth(2) == T!['('] || p.nth_at(2, T![::]))
543+
|| p.nth(1) == T!['(']
535544
);
536545
}
537546
let m = lhs.precede(p);
538547
if !FLOAT_RECOVERY {
539548
p.bump(T![.]);
540549
}
541-
name_ref_mod_path(p);
550+
if p.at_ts(PATH_NAME_REF_KINDS) {
551+
name_ref_mod_path(p);
552+
} else {
553+
p.error("expected method name, field name or number");
554+
}
542555
generic_args::opt_generic_arg_list_expr(p);
543556
if p.at(T!['(']) {
544557
arg_list(p);

src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,10 @@ mod err {
844844
run_and_expect_errors("test_data/parser/inline/err/pointer_type_no_mutability.rs");
845845
}
846846
#[test]
847+
fn postfix_dot_expr_ambiguity() {
848+
run_and_expect_errors("test_data/parser/inline/err/postfix_dot_expr_ambiguity.rs");
849+
}
850+
#[test]
847851
fn precise_capturing_invalid() {
848852
run_and_expect_errors("test_data/parser/inline/err/precise_capturing_invalid.rs");
849853
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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 "\n "
15+
METHOD_CALL_EXPR
16+
PATH_EXPR
17+
PATH
18+
PATH_SEGMENT
19+
NAME_REF
20+
IDENT "x"
21+
DOT "."
22+
WHITESPACE "\n "
23+
ARG_LIST
24+
L_PAREN "("
25+
R_PAREN ")"
26+
WHITESPACE "\n"
27+
R_CURLY "}"
28+
WHITESPACE "\n"
29+
error 17: expected method name, field name or number
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn foo() {
2+
x.
3+
()
4+
}

0 commit comments

Comments
 (0)