about summary refs log tree commit diff
path: root/src/tools
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-12-05 14:42:00 +0000
committerGitHub <noreply@github.com>2024-12-05 14:42:00 +0000
commit4883a12a979eb871bd022b190f473f083af32ef4 (patch)
tree9f2d5e064a2e7596db57e7fd244a2d8a1a13a56e /src/tools
parentb8db0c5a85608bf5e226577d85d811b92a68a24f (diff)
parenta19e1dffe5ca8574e58826488351af8c714c9620 (diff)
downloadrust-4883a12a979eb871bd022b190f473f083af32ef4.tar.gz
rust-4883a12a979eb871bd022b190f473f083af32ef4.zip
Merge pull request #18618 from Veykril/push-ysklqzomkyvp
fix: Fix parsing of integer/keyword name refs in various places
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs2
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar.rs44
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs64
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs12
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/generic_args.rs4
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs11
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/items.rs12
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs49
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs8
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/err/0004_use_path_bad_segment.rast2
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/err/0048_double_fish.rast4
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/arg_list_recovery.rast2
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/crate_visibility_empty_recover.rast2
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/empty_segment.rast2
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/meta_recovery.rast10
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/precise_capturing_invalid.rast28
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/precise_capturing_invalid.rs1
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rast37
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rs1
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rast29
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rs1
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rast78
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rs3
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate.rast9
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate.rs1
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rast15
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rs1
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_self.rast10
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_self.rs1
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/field_expr.rast24
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/field_expr.rs2
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/method_call_expr.rast14
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/method_call_expr.rs1
33 files changed, 351 insertions, 133 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs
index 5c03fad6131..511626b5ed9 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs
@@ -1733,7 +1733,7 @@ m!(C("0"));
 macro_rules! m {
     ($k:expr) => { fn f() { K::$k; } }
 }
-/* parse error: expected identifier */
+/* parse error: expected identifier, `self`, `super`, `crate`, or `Self` */
 /* parse error: expected SEMICOLON */
 /* parse error: expected SEMICOLON */
 /* parse error: expected expression, item or let statement */
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar.rs b/src/tools/rust-analyzer/crates/parser/src/grammar.rs
index c402c498553..fe6b904bd88 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar.rs
@@ -307,13 +307,49 @@ fn name(p: &mut Parser<'_>) {
     name_r(p, TokenSet::EMPTY);
 }
 
-fn name_ref(p: &mut Parser<'_>) {
-    if p.at(IDENT) {
+fn name_ref_or_self(p: &mut Parser<'_>) {
+    if matches!(p.current(), T![ident] | T![self]) {
         let m = p.start();
-        p.bump(IDENT);
+        p.bump_any();
+        m.complete(p, NAME_REF);
+    } else {
+        p.err_and_bump("expected identifier or `self`");
+    }
+}
+
+fn name_ref_or_upper_self(p: &mut Parser<'_>) {
+    if matches!(p.current(), T![ident] | T![Self]) {
+        let m = p.start();
+        p.bump_any();
+        m.complete(p, NAME_REF);
+    } else {
+        p.err_and_bump("expected identifier or `Self`");
+    }
+}
+
+const PATH_NAME_REF_KINDS: TokenSet =
+    TokenSet::new(&[IDENT, T![self], T![super], T![crate], T![Self]]);
+
+fn name_ref_mod_path(p: &mut Parser<'_>) {
+    if p.at_ts(PATH_NAME_REF_KINDS) {
+        let m = p.start();
+        p.bump_any();
+        m.complete(p, NAME_REF);
+    } else {
+        p.err_and_bump("expected identifier, `self`, `super`, `crate`, or `Self`");
+    }
+}
+
+const PATH_NAME_REF_OR_INDEX_KINDS: TokenSet =
+    PATH_NAME_REF_KINDS.union(TokenSet::new(&[INT_NUMBER]));
+
+fn name_ref_mod_path_or_index(p: &mut Parser<'_>) {
+    if p.at_ts(PATH_NAME_REF_OR_INDEX_KINDS) {
+        let m = p.start();
+        p.bump_any();
         m.complete(p, NAME_REF);
     } else {
-        p.err_and_bump("expected identifier");
+        p.err_and_bump("expected integer, identifier, `self`, `super`, `crate`, or `Self`");
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs
index 349bce09390..3b3f11be130 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs
@@ -449,7 +449,9 @@ fn postfix_dot_expr<const FLOAT_RECOVERY: bool>(
     let nth1 = if FLOAT_RECOVERY { 0 } else { 1 };
     let nth2 = if FLOAT_RECOVERY { 1 } else { 2 };
 
-    if p.nth(nth1) == IDENT && (p.nth(nth2) == T!['('] || p.nth_at(nth2, T![::])) {
+    if PATH_NAME_REF_KINDS.contains(p.nth(nth1))
+        && (p.nth(nth2) == T!['('] || p.nth_at(nth2, T![::]))
+    {
         return Ok(method_call_expr::<FLOAT_RECOVERY>(p, lhs));
     }
 
@@ -510,21 +512,26 @@ fn index_expr(p: &mut Parser<'_>, lhs: CompletedMarker) -> CompletedMarker {
 //     y.bar::<T>(1, 2,);
 //     x.0.0.call();
 //     x.0. call();
+//     x.0()
 // }
 fn method_call_expr<const FLOAT_RECOVERY: bool>(
     p: &mut Parser<'_>,
     lhs: CompletedMarker,
 ) -> CompletedMarker {
     if FLOAT_RECOVERY {
-        assert!(p.nth(0) == IDENT && (p.nth(1) == T!['('] || p.nth_at(1, T![::])));
+        assert!(p.at_ts(PATH_NAME_REF_KINDS) && (p.nth(1) == T!['('] || p.nth_at(1, T![::])));
     } else {
-        assert!(p.at(T![.]) && p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth_at(2, T![::])));
+        assert!(
+            p.at(T![.])
+                && PATH_NAME_REF_KINDS.contains(p.nth(1))
+                && (p.nth(2) == T!['('] || p.nth_at(2, T![::]))
+        );
     }
     let m = lhs.precede(p);
     if !FLOAT_RECOVERY {
         p.bump(T![.]);
     }
-    name_ref(p);
+    name_ref_mod_path(p);
     generic_args::opt_generic_arg_list_expr(p);
     if p.at(T!['(']) {
         arg_list(p);
@@ -543,6 +550,8 @@ fn method_call_expr<const FLOAT_RECOVERY: bool>(
 
 // test field_expr
 // fn foo() {
+//     x.self;
+//     x.Self;
 //     x.foo;
 //     x.0.bar;
 //     x.0.1;
@@ -560,8 +569,8 @@ fn field_expr<const FLOAT_RECOVERY: bool>(
     if !FLOAT_RECOVERY {
         p.bump(T![.]);
     }
-    if p.at(IDENT) || p.at(INT_NUMBER) {
-        name_ref_or_index(p);
+    if p.at_ts(PATH_NAME_REF_OR_INDEX_KINDS) {
+        name_ref_mod_path_or_index(p);
     } else if p.at(FLOAT_NUMBER) {
         return match p.split_float(m) {
             (true, m) => {
@@ -679,34 +688,37 @@ pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
             IDENT | INT_NUMBER if p.nth_at(1, T![::]) => {
                 // test_err record_literal_missing_ellipsis_recovery
                 // fn main() {
-                //     S { S::default() }
+                //     S { S::default() };
+                //     S { 0::default() };
                 // }
                 m.abandon(p);
                 p.expect(T![..]);
                 expr(p);
             }
+            IDENT | INT_NUMBER if p.nth_at(1, T![..]) => {
+                // test_err record_literal_before_ellipsis_recovery
+                // fn main() {
+                //     S { field ..S::default() }
+                //     S { 0 ..S::default() }
+                // }
+                name_ref_or_index(p);
+                p.error("expected `:`");
+                m.complete(p, RECORD_EXPR_FIELD);
+            }
             IDENT | INT_NUMBER => {
-                if p.nth_at(1, T![..]) {
-                    // test_err record_literal_before_ellipsis_recovery
-                    // fn main() {
-                    //     S { field ..S::default() }
-                    // }
+                // test_err record_literal_field_eq_recovery
+                // fn main() {
+                //     S { field = foo }
+                //     S { 0 = foo }
+                // }
+                if p.nth_at(1, T![:]) {
                     name_ref_or_index(p);
-                    p.error("expected `:`");
-                } else {
-                    // test_err record_literal_field_eq_recovery
-                    // fn main() {
-                    //     S { field = foo }
-                    // }
-                    if p.nth_at(1, T![:]) {
-                        name_ref_or_index(p);
-                        p.bump(T![:]);
-                    } else if p.nth_at(1, T![=]) {
-                        name_ref_or_index(p);
-                        p.err_and_bump("expected `:`");
-                    }
-                    expr(p);
+                    p.bump(T![:]);
+                } else if p.nth_at(1, T![=]) {
+                    name_ref_or_index(p);
+                    p.err_and_bump("expected `:`");
                 }
+                expr(p);
                 m.complete(p, RECORD_EXPR_FIELD);
             }
             T![.] if p.at(T![..]) => {
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs
index 97e0392ce15..cd2ce59f627 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs
@@ -259,13 +259,7 @@ fn builtin_expr(p: &mut Parser<'_>) -> Option<CompletedMarker> {
         type_(p);
         p.expect(T![,]);
         while !p.at(EOF) && !p.at(T![')']) {
-            if p.at(IDENT) || p.at(INT_NUMBER) {
-                name_ref_or_index(p);
-            // } else if p.at(FLOAT_NUMBER) {
-            // FIXME: needs float hack
-            } else {
-                p.err_and_bump("expected field name or number");
-            }
+            name_ref_mod_path_or_index(p);
             if !p.at(T![')']) {
                 p.expect(T![.]);
             }
@@ -465,9 +459,9 @@ fn parse_clobber_abi(p: &mut Parser<'_>) {
 
 fn parse_reg(p: &mut Parser<'_>) {
     p.expect(T!['(']);
-    if p.at(T![ident]) {
+    if p.at_ts(PATH_NAME_REF_KINDS) {
         let m = p.start();
-        name_ref(p);
+        name_ref_mod_path(p);
         m.complete(p, ASM_REG_SPEC);
     } else if p.at(T![string]) {
         let m = p.start();
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/generic_args.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/generic_args.rs
index 737010985b2..c7d8040b24e 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/generic_args.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/generic_args.rs
@@ -59,9 +59,9 @@ pub(crate) fn generic_arg(p: &mut Parser<'_>) -> bool {
 
         // test macro_inside_generic_arg
         // type A = Foo<syn::Token![_]>;
-        IDENT => {
+        k if PATH_NAME_REF_KINDS.contains(k) => {
             let m = p.start();
-            name_ref(p);
+            name_ref_mod_path(p);
             paths::opt_path_type_args(p);
             match p.current() {
                 T![=] => {
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs
index 92311238c23..08b23cd92a6 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs
@@ -145,6 +145,9 @@ fn type_bound(p: &mut Parser<'_>) -> bool {
         T![for] => types::for_type(p, false),
         // test precise_capturing
         // fn captures<'a: 'a, 'b: 'b, T>() -> impl Sized + use<'b, T, Self> {}
+
+        // test_err precise_capturing_invalid
+        // type T = impl use<self, 1>;
         T![use] if p.nth_at(1, T![<]) => {
             p.bump_any();
             let m = p.start();
@@ -156,14 +159,10 @@ fn type_bound(p: &mut Parser<'_>) -> bool {
                 || "expected identifier or lifetime".into(),
                 TokenSet::new(&[T![Self], IDENT, LIFETIME_IDENT]),
                 |p| {
-                    if p.at(T![Self]) {
-                        let m = p.start();
-                        p.bump(T![Self]);
-                        m.complete(p, NAME_REF);
-                    } else if p.at(LIFETIME_IDENT) {
+                    if p.at(LIFETIME_IDENT) {
                         lifetime(p);
                     } else {
-                        name_ref(p);
+                        name_ref_or_upper_self(p);
                     }
                     true
                 },
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs
index 7d98499008d..8ece5af527d 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/items.rs
@@ -254,22 +254,16 @@ fn opt_item_without_modifiers(p: &mut Parser<'_>, m: Marker) -> Result<(), Marke
 
 // test extern_crate
 // extern crate foo;
+// extern crate self;
 fn extern_crate(p: &mut Parser<'_>, m: Marker) {
     p.bump(T![extern]);
     p.bump(T![crate]);
 
-    if p.at(T![self]) {
-        // test extern_crate_self
-        // extern crate self;
-        let m = p.start();
-        p.bump(T![self]);
-        m.complete(p, NAME_REF);
-    } else {
-        name_ref(p);
-    }
+    name_ref_or_self(p);
 
     // test extern_crate_rename
     // extern crate foo as bar;
+    // extern crate self as bar;
     opt_rename(p);
     p.expect(T![;]);
     m.complete(p, EXTERN_CRATE);
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs
index b3652f7cd3f..3410505cd46 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs
@@ -107,37 +107,32 @@ fn path_segment(p: &mut Parser<'_>, mode: Mode, first: bool) -> Option<Completed
         }
     } else {
         let mut empty = if first { !p.eat(T![::]) } else { true };
-        match p.current() {
-            IDENT => {
-                name_ref(p);
-                opt_path_args(p, mode);
-            }
+        if p.at_ts(PATH_NAME_REF_KINDS) {
             // test crate_path
             // use crate::foo;
-            T![self] | T![super] | T![crate] | T![Self] => {
-                let m = p.start();
-                p.bump_any();
-                m.complete(p, NAME_REF);
-            }
-            _ => {
-                let recover_set = match mode {
-                    Mode::Use => items::ITEM_RECOVERY_SET,
-                    Mode::Attr => {
-                        items::ITEM_RECOVERY_SET.union(TokenSet::new(&[T![']'], T![=], T![#]]))
-                    }
-                    Mode::Vis => items::ITEM_RECOVERY_SET.union(TokenSet::new(&[T![')']])),
-                    Mode::Type => TYPE_PATH_SEGMENT_RECOVERY_SET,
-                    Mode::Expr => EXPR_PATH_SEGMENT_RECOVERY_SET,
-                };
-                empty &= p.err_recover("expected identifier", recover_set);
-                if empty {
-                    // test_err empty_segment
-                    // use crate::;
-                    m.abandon(p);
-                    return None;
+            name_ref_mod_path(p);
+            opt_path_args(p, mode);
+        } else {
+            let recover_set = match mode {
+                Mode::Use => items::ITEM_RECOVERY_SET,
+                Mode::Attr => {
+                    items::ITEM_RECOVERY_SET.union(TokenSet::new(&[T![']'], T![=], T![#]]))
                 }
+                Mode::Vis => items::ITEM_RECOVERY_SET.union(TokenSet::new(&[T![')']])),
+                Mode::Type => TYPE_PATH_SEGMENT_RECOVERY_SET,
+                Mode::Expr => EXPR_PATH_SEGMENT_RECOVERY_SET,
+            };
+            empty &= p.err_recover(
+                "expected identifier, `self`, `super`, `crate`, or `Self`",
+                recover_set,
+            );
+            if empty {
+                // test_err empty_segment
+                // use crate::;
+                m.abandon(p);
+                return None;
             }
-        };
+        }
     }
     Some(m.complete(p, PATH_SEGMENT))
 }
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs
index 6d114037bf9..f9486f53c25 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs
@@ -210,10 +210,6 @@ mod ok {
         run_and_expect_no_errors("test_data/parser/inline/ok/extern_crate_rename.rs");
     }
     #[test]
-    fn extern_crate_self() {
-        run_and_expect_no_errors("test_data/parser/inline/ok/extern_crate_self.rs");
-    }
-    #[test]
     fn field_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/field_expr.rs"); }
     #[test]
     fn fn_() { run_and_expect_no_errors("test_data/parser/inline/ok/fn_.rs"); }
@@ -774,6 +770,10 @@ mod err {
         run_and_expect_errors("test_data/parser/inline/err/pointer_type_no_mutability.rs");
     }
     #[test]
+    fn precise_capturing_invalid() {
+        run_and_expect_errors("test_data/parser/inline/err/precise_capturing_invalid.rs");
+    }
+    #[test]
     fn pub_expr() { run_and_expect_errors("test_data/parser/inline/err/pub_expr.rs"); }
     #[test]
     fn record_literal_before_ellipsis_recovery() {
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0004_use_path_bad_segment.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0004_use_path_bad_segment.rast
index cf455934e91..7273c98456e 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0004_use_path_bad_segment.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0004_use_path_bad_segment.rast
@@ -13,4 +13,4 @@ SOURCE_FILE
           ERROR
             INT_NUMBER "92"
     SEMICOLON ";"
-error 9: expected identifier
+error 9: expected identifier, `self`, `super`, `crate`, or `Self`
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0048_double_fish.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0048_double_fish.rast
index 7ef1eb98fcd..47daaf7b3b3 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0048_double_fish.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0048_double_fish.rast
@@ -115,10 +115,10 @@ SOURCE_FILE
         WHITESPACE "\n"
         R_CURLY "}"
   WHITESPACE "\n"
-error 30: expected identifier
+error 30: expected identifier, `self`, `super`, `crate`, or `Self`
 error 31: expected COMMA
 error 37: expected expression
-error 75: expected identifier
+error 75: expected identifier, `self`, `super`, `crate`, or `Self`
 error 76: expected SEMICOLON
 error 82: expected expression
 error 83: expected SEMICOLON
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/arg_list_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/arg_list_recovery.rast
index cd5aa680c65..755b20bb271 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/arg_list_recovery.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/arg_list_recovery.rast
@@ -98,7 +98,7 @@ SOURCE_FILE
         WHITESPACE "\n"
         R_CURLY "}"
   WHITESPACE "\n"
-error 25: expected identifier
+error 25: expected identifier, `self`, `super`, `crate`, or `Self`
 error 39: expected COMMA
 error 39: expected expression
 error 55: expected expression
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/crate_visibility_empty_recover.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/crate_visibility_empty_recover.rast
index 681ca6b6e05..172bc099b58 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/crate_visibility_empty_recover.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/crate_visibility_empty_recover.rast
@@ -11,4 +11,4 @@ SOURCE_FILE
       IDENT "S"
     SEMICOLON ";"
   WHITESPACE "\n"
-error 4: expected identifier
+error 4: expected identifier, `self`, `super`, `crate`, or `Self`
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/empty_segment.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/empty_segment.rast
index b03f5ad9f7e..7f256218eff 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/empty_segment.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/empty_segment.rast
@@ -11,4 +11,4 @@ SOURCE_FILE
         COLON2 "::"
     SEMICOLON ";"
   WHITESPACE "\n"
-error 11: expected identifier
+error 11: expected identifier, `self`, `super`, `crate`, or `Self`
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/meta_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/meta_recovery.rast
index 926dd50fc85..b5c16e0798c 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/meta_recovery.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/meta_recovery.rast
@@ -66,18 +66,18 @@ SOURCE_FILE
       EQ "="
     R_BRACK "]"
   WHITESPACE "\n"
-error 3: expected identifier
+error 3: expected identifier, `self`, `super`, `crate`, or `Self`
 error 11: expected expression
 error 11: expected expression
-error 20: expected identifier
-error 28: expected identifier
+error 20: expected identifier, `self`, `super`, `crate`, or `Self`
+error 28: expected identifier, `self`, `super`, `crate`, or `Self`
 error 30: expected expression
 error 30: expected expression
 error 41: expected L_PAREN
-error 41: expected identifier
+error 41: expected identifier, `self`, `super`, `crate`, or `Self`
 error 41: expected R_PAREN
 error 52: expected L_PAREN
-error 52: expected identifier
+error 52: expected identifier, `self`, `super`, `crate`, or `Self`
 error 54: expected expression
 error 54: expected expression
 error 54: expected R_PAREN
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/precise_capturing_invalid.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/precise_capturing_invalid.rast
new file mode 100644
index 00000000000..5ae184c5feb
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/precise_capturing_invalid.rast
@@ -0,0 +1,28 @@
+SOURCE_FILE
+  TYPE_ALIAS
+    TYPE_KW "type"
+    WHITESPACE " "
+    NAME
+      IDENT "T"
+    WHITESPACE " "
+    EQ "="
+    WHITESPACE " "
+    IMPL_TRAIT_TYPE
+      IMPL_KW "impl"
+      WHITESPACE " "
+      TYPE_BOUND_LIST
+        TYPE_BOUND
+          USE_KW "use"
+          USE_BOUND_GENERIC_ARGS
+            L_ANGLE "<"
+            ERROR
+              SELF_KW "self"
+            COMMA ","
+            WHITESPACE " "
+            ERROR
+              INT_NUMBER "1"
+            R_ANGLE ">"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+error 18: expected identifier or `Self`
+error 24: expected identifier or `Self`
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/precise_capturing_invalid.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/precise_capturing_invalid.rs
new file mode 100644
index 00000000000..3180338d33f
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/precise_capturing_invalid.rs
@@ -0,0 +1 @@
+type T = impl use<self, 1>;
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rast
index 741b7845e7f..08ae906421c 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rast
@@ -12,6 +12,38 @@ SOURCE_FILE
       STMT_LIST
         L_CURLY "{"
         WHITESPACE "\n    "
+        EXPR_STMT
+          RECORD_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "S"
+            WHITESPACE " "
+            RECORD_EXPR_FIELD_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              RECORD_EXPR_FIELD
+                NAME_REF
+                  IDENT "field"
+              WHITESPACE " "
+              DOT2 ".."
+              CALL_EXPR
+                PATH_EXPR
+                  PATH
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "S"
+                    COLON2 "::"
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "default"
+                ARG_LIST
+                  L_PAREN "("
+                  R_PAREN ")"
+              WHITESPACE " "
+              R_CURLY "}"
+        WHITESPACE "\n    "
         RECORD_EXPR
           PATH
             PATH_SEGMENT
@@ -23,7 +55,7 @@ SOURCE_FILE
             WHITESPACE " "
             RECORD_EXPR_FIELD
               NAME_REF
-                IDENT "field"
+                INT_NUMBER "0"
             WHITESPACE " "
             DOT2 ".."
             CALL_EXPR
@@ -47,3 +79,6 @@ SOURCE_FILE
   WHITESPACE "\n"
 error 25: expected `:`
 error 25: expected COMMA
+error 42: expected SEMICOLON
+error 52: expected `:`
+error 52: expected COMMA
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rs
index a4e5b2f6933..65398ccb88e 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rs
@@ -1,3 +1,4 @@
 fn main() {
     S { field ..S::default() }
+    S { 0 ..S::default() }
 }
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rast
index ad4deeb0b67..ad3b6f208e6 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rast
@@ -12,6 +12,31 @@ SOURCE_FILE
       STMT_LIST
         L_CURLY "{"
         WHITESPACE "\n    "
+        EXPR_STMT
+          RECORD_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "S"
+            WHITESPACE " "
+            RECORD_EXPR_FIELD_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              RECORD_EXPR_FIELD
+                NAME_REF
+                  IDENT "field"
+                WHITESPACE " "
+                ERROR
+                  EQ "="
+                WHITESPACE " "
+                PATH_EXPR
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "foo"
+              WHITESPACE " "
+              R_CURLY "}"
+        WHITESPACE "\n    "
         RECORD_EXPR
           PATH
             PATH_SEGMENT
@@ -23,7 +48,7 @@ SOURCE_FILE
             WHITESPACE " "
             RECORD_EXPR_FIELD
               NAME_REF
-                IDENT "field"
+                INT_NUMBER "0"
               WHITESPACE " "
               ERROR
                 EQ "="
@@ -39,3 +64,5 @@ SOURCE_FILE
         R_CURLY "}"
   WHITESPACE "\n"
 error 26: expected `:`
+error 33: expected SEMICOLON
+error 44: expected `:`
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rs
index 1eb1aa9b926..9ddc46e0daf 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rs
@@ -1,3 +1,4 @@
 fn main() {
     S { field = foo }
+    S { 0 = foo }
 }
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rast
index 0c5b618e6f0..9cd07d2ea38 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rast
@@ -12,32 +12,70 @@ SOURCE_FILE
       STMT_LIST
         L_CURLY "{"
         WHITESPACE "\n    "
-        RECORD_EXPR
-          PATH
-            PATH_SEGMENT
-              NAME_REF
-                IDENT "S"
-          WHITESPACE " "
-          RECORD_EXPR_FIELD_LIST
-            L_CURLY "{"
+        EXPR_STMT
+          RECORD_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "S"
             WHITESPACE " "
-            CALL_EXPR
-              PATH_EXPR
-                PATH
+            RECORD_EXPR_FIELD_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              CALL_EXPR
+                PATH_EXPR
                   PATH
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "S"
+                    COLON2 "::"
                     PATH_SEGMENT
                       NAME_REF
-                        IDENT "S"
-                  COLON2 "::"
-                  PATH_SEGMENT
-                    NAME_REF
-                      IDENT "default"
-              ARG_LIST
-                L_PAREN "("
-                R_PAREN ")"
+                        IDENT "default"
+                ARG_LIST
+                  L_PAREN "("
+                  R_PAREN ")"
+              WHITESPACE " "
+              R_CURLY "}"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          RECORD_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "S"
             WHITESPACE " "
-            R_CURLY "}"
+            RECORD_EXPR_FIELD_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "0"
+              ERROR
+                COLON ":"
+              ERROR
+                COLON ":"
+              RECORD_EXPR_FIELD
+                CALL_EXPR
+                  PATH_EXPR
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "default"
+                  ARG_LIST
+                    L_PAREN "("
+                    R_PAREN ")"
+              WHITESPACE " "
+              R_CURLY "}"
+          SEMICOLON ";"
         WHITESPACE "\n"
         R_CURLY "}"
   WHITESPACE "\n"
 error 19: expected DOT2
+error 43: expected DOT2
+error 45: expected COMMA
+error 45: expected identifier
+error 46: expected COMMA
+error 46: expected identifier
+error 47: expected COMMA
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rs
index 1b594e8ab96..a63c3c9e7c2 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rs
@@ -1,3 +1,4 @@
 fn main() {
-    S { S::default() }
+    S { S::default() };
+    S { 0::default() };
 }
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate.rast
index 0a660957d15..aa555ed2293 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate.rast
@@ -8,3 +8,12 @@ SOURCE_FILE
       IDENT "foo"
     SEMICOLON ";"
   WHITESPACE "\n"
+  EXTERN_CRATE
+    EXTERN_KW "extern"
+    WHITESPACE " "
+    CRATE_KW "crate"
+    WHITESPACE " "
+    NAME_REF
+      SELF_KW "self"
+    SEMICOLON ";"
+  WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate.rs
index 49af74e1b74..3c498c8738f 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate.rs
@@ -1 +1,2 @@
 extern crate foo;
+extern crate self;
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rast
index 5a5aca96f91..5f0a5b5bb05 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rast
@@ -14,3 +14,18 @@ SOURCE_FILE
         IDENT "bar"
     SEMICOLON ";"
   WHITESPACE "\n"
+  EXTERN_CRATE
+    EXTERN_KW "extern"
+    WHITESPACE " "
+    CRATE_KW "crate"
+    WHITESPACE " "
+    NAME_REF
+      SELF_KW "self"
+    WHITESPACE " "
+    RENAME
+      AS_KW "as"
+      WHITESPACE " "
+      NAME
+        IDENT "bar"
+    SEMICOLON ";"
+  WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rs
index fc76e17dda4..6d1873d659e 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rs
@@ -1 +1,2 @@
 extern crate foo as bar;
+extern crate self as bar;
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_self.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_self.rast
deleted file mode 100644
index edea4245f20..00000000000
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_self.rast
+++ /dev/null
@@ -1,10 +0,0 @@
-SOURCE_FILE
-  EXTERN_CRATE
-    EXTERN_KW "extern"
-    WHITESPACE " "
-    CRATE_KW "crate"
-    WHITESPACE " "
-    NAME_REF
-      SELF_KW "self"
-    SEMICOLON ";"
-  WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_self.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_self.rs
deleted file mode 100644
index c969ed10936..00000000000
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_crate_self.rs
+++ /dev/null
@@ -1 +0,0 @@
-extern crate self;
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/field_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/field_expr.rast
index dd27dc48964..3bac226d343 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/field_expr.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/field_expr.rast
@@ -21,6 +21,30 @@ SOURCE_FILE
                     IDENT "x"
             DOT "."
             NAME_REF
+              SELF_KW "self"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          FIELD_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "x"
+            DOT "."
+            NAME_REF
+              SELF_TYPE_KW "Self"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          FIELD_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "x"
+            DOT "."
+            NAME_REF
               IDENT "foo"
           SEMICOLON ";"
         WHITESPACE "\n    "
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/field_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/field_expr.rs
index 98dbe45a7ec..b156d6f7d88 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/field_expr.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/field_expr.rs
@@ -1,4 +1,6 @@
 fn foo() {
+    x.self;
+    x.Self;
     x.foo;
     x.0.bar;
     x.0.1;
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/method_call_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/method_call_expr.rast
index b28b8eb673a..3245042cf24 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/method_call_expr.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/method_call_expr.rast
@@ -101,6 +101,20 @@ SOURCE_FILE
               L_PAREN "("
               R_PAREN ")"
           SEMICOLON ";"
+        WHITESPACE "\n    "
+        CALL_EXPR
+          FIELD_EXPR
+            PATH_EXPR
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "x"
+            DOT "."
+            NAME_REF
+              INT_NUMBER "0"
+          ARG_LIST
+            L_PAREN "("
+            R_PAREN ")"
         WHITESPACE "\n"
         R_CURLY "}"
   WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/method_call_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/method_call_expr.rs
index 48bb6381e80..bb54d75c19b 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/method_call_expr.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/method_call_expr.rs
@@ -3,4 +3,5 @@ fn foo() {
     y.bar::<T>(1, 2,);
     x.0.0.call();
     x.0. call();
+    x.0()
 }