about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-01-09 09:49:25 +0000
committerbors <bors@rust-lang.org>2024-01-09 09:49:25 +0000
commitc246ecfd5540dcf99deab569a5e62158aa3bbe1f (patch)
treeab2a4e47766dbda87f7034d339d1d1effe9d0bef
parent25f71469f1739d5a8fbd8ec28d7e6c282d76f8a9 (diff)
parent72200641c1702fe143ba11218c3ecc6604c3d9db (diff)
downloadrust-c246ecfd5540dcf99deab569a5e62158aa3bbe1f.tar.gz
rust-c246ecfd5540dcf99deab569a5e62158aa3bbe1f.zip
Auto merge of #16310 - Veykril:range-access-parse, r=Veykril
fix: Fix incorrect parsing error on method call on range

Fixes https://github.com/rust-lang/rust-analyzer/issues/16289
-rw-r--r--crates/parser/src/grammar/expressions.rs10
-rw-r--r--crates/parser/test_data/parser/inline/ok/0208_closure_range_method_call.rast49
-rw-r--r--crates/parser/test_data/parser/inline/ok/0208_closure_range_method_call.rs4
3 files changed, 62 insertions, 1 deletions
diff --git a/crates/parser/src/grammar/expressions.rs b/crates/parser/src/grammar/expressions.rs
index e346ece2f94..c8626111145 100644
--- a/crates/parser/src/grammar/expressions.rs
+++ b/crates/parser/src/grammar/expressions.rs
@@ -371,7 +371,15 @@ fn lhs(p: &mut Parser<'_>, r: Restrictions) -> Option<(CompletedMarker, BlockLik
                 if p.at(op) {
                     m = p.start();
                     p.bump(op);
-                    if p.at_ts(EXPR_FIRST) && !(r.forbid_structs && p.at(T!['{'])) {
+
+                    // test closure_range_method_call
+                    // fn foo() {
+                    //     || .. .method();
+                    //     || .. .field;
+                    // }
+                    let has_access_after = p.at(T![.]) && p.nth_at(1, SyntaxKind::IDENT);
+                    let struct_forbidden = r.forbid_structs && p.at(T!['{']);
+                    if p.at_ts(EXPR_FIRST) && !has_access_after && !struct_forbidden {
                         expr_bp(p, None, r, 2);
                     }
                     let cm = m.complete(p, RANGE_EXPR);
diff --git a/crates/parser/test_data/parser/inline/ok/0208_closure_range_method_call.rast b/crates/parser/test_data/parser/inline/ok/0208_closure_range_method_call.rast
new file mode 100644
index 00000000000..542711339d1
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/0208_closure_range_method_call.rast
@@ -0,0 +1,49 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          METHOD_CALL_EXPR
+            CLOSURE_EXPR
+              PARAM_LIST
+                PIPE "|"
+                PIPE "|"
+              WHITESPACE " "
+              RANGE_EXPR
+                DOT2 ".."
+            WHITESPACE " "
+            DOT "."
+            NAME_REF
+              IDENT "method"
+            ARG_LIST
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          FIELD_EXPR
+            CLOSURE_EXPR
+              PARAM_LIST
+                PIPE "|"
+                PIPE "|"
+              WHITESPACE " "
+              RANGE_EXPR
+                DOT2 ".."
+            WHITESPACE " "
+            DOT "."
+            NAME_REF
+              IDENT "field"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/parser/test_data/parser/inline/ok/0208_closure_range_method_call.rs b/crates/parser/test_data/parser/inline/ok/0208_closure_range_method_call.rs
new file mode 100644
index 00000000000..a81d3c37133
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/0208_closure_range_method_call.rs
@@ -0,0 +1,4 @@
+fn foo() {
+    || .. .method();
+    || .. .field;
+}