Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #18618 from Veykril/push-ysklqzomkyvp
fix: Fix parsing of integer/keyword name refs in various places
Lukas Wirth 2024-12-05
parent e7c8b2f · parent df7ab62 · commit 4df6dc8
-rw-r--r--crates/hir-def/src/macro_expansion_tests/mbe.rs2
-rw-r--r--crates/parser/src/grammar.rs44
-rw-r--r--crates/parser/src/grammar/expressions.rs64
-rw-r--r--crates/parser/src/grammar/expressions/atom.rs12
-rw-r--r--crates/parser/src/grammar/generic_args.rs4
-rw-r--r--crates/parser/src/grammar/generic_params.rs11
-rw-r--r--crates/parser/src/grammar/items.rs12
-rw-r--r--crates/parser/src/grammar/paths.rs49
-rw-r--r--crates/parser/test_data/generated/runner.rs8
-rw-r--r--crates/parser/test_data/parser/err/0004_use_path_bad_segment.rast2
-rw-r--r--crates/parser/test_data/parser/err/0048_double_fish.rast4
-rw-r--r--crates/parser/test_data/parser/inline/err/arg_list_recovery.rast2
-rw-r--r--crates/parser/test_data/parser/inline/err/crate_visibility_empty_recover.rast2
-rw-r--r--crates/parser/test_data/parser/inline/err/empty_segment.rast2
-rw-r--r--crates/parser/test_data/parser/inline/err/meta_recovery.rast10
-rw-r--r--crates/parser/test_data/parser/inline/err/precise_capturing_invalid.rast28
-rw-r--r--crates/parser/test_data/parser/inline/err/precise_capturing_invalid.rs1
-rw-r--r--crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rast37
-rw-r--r--crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rs1
-rw-r--r--crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rast29
-rw-r--r--crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rs1
-rw-r--r--crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rast78
-rw-r--r--crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rs3
-rw-r--r--crates/parser/test_data/parser/inline/ok/extern_crate.rast9
-rw-r--r--crates/parser/test_data/parser/inline/ok/extern_crate.rs1
-rw-r--r--crates/parser/test_data/parser/inline/ok/extern_crate_rename.rast15
-rw-r--r--crates/parser/test_data/parser/inline/ok/extern_crate_rename.rs1
-rw-r--r--crates/parser/test_data/parser/inline/ok/extern_crate_self.rast10
-rw-r--r--crates/parser/test_data/parser/inline/ok/extern_crate_self.rs1
-rw-r--r--crates/parser/test_data/parser/inline/ok/field_expr.rast24
-rw-r--r--crates/parser/test_data/parser/inline/ok/field_expr.rs2
-rw-r--r--crates/parser/test_data/parser/inline/ok/method_call_expr.rast14
-rw-r--r--crates/parser/test_data/parser/inline/ok/method_call_expr.rs1
33 files changed, 351 insertions, 133 deletions
diff --git a/crates/hir-def/src/macro_expansion_tests/mbe.rs b/crates/hir-def/src/macro_expansion_tests/mbe.rs
index 5c03fad613..511626b5ed 100644
--- a/crates/hir-def/src/macro_expansion_tests/mbe.rs
+++ b/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/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs
index c402c49855..fe6b904bd8 100644
--- a/crates/parser/src/grammar.rs
+++ b/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/crates/parser/src/grammar/expressions.rs b/crates/parser/src/grammar/expressions.rs
index 349bce0939..3b3f11be13 100644
--- a/crates/parser/src/grammar/expressions.rs
+++ b/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/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs
index 97e0392ce1..cd2ce59f62 100644
--- a/crates/parser/src/grammar/expressions/atom.rs
+++ b/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/crates/parser/src/grammar/generic_args.rs b/crates/parser/src/grammar/generic_args.rs
index 737010985b..c7d8040b24 100644
--- a/crates/parser/src/grammar/generic_args.rs
+++ b/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/crates/parser/src/grammar/generic_params.rs b/crates/parser/src/grammar/generic_params.rs
index 92311238c2..08b23cd92a 100644
--- a/crates/parser/src/grammar/generic_params.rs
+++ b/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/crates/parser/src/grammar/items.rs b/crates/parser/src/grammar/items.rs
index 7d98499008..8ece5af527 100644
--- a/crates/parser/src/grammar/items.rs
+++ b/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/crates/parser/src/grammar/paths.rs b/crates/parser/src/grammar/paths.rs
index b3652f7cd3..3410505cd4 100644
--- a/crates/parser/src/grammar/paths.rs
+++ b/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/crates/parser/test_data/generated/runner.rs b/crates/parser/test_data/generated/runner.rs
index 6d114037bf..f9486f53c2 100644
--- a/crates/parser/test_data/generated/runner.rs
+++ b/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/crates/parser/test_data/parser/err/0004_use_path_bad_segment.rast b/crates/parser/test_data/parser/err/0004_use_path_bad_segment.rast
index cf455934e9..7273c98456 100644
--- a/crates/parser/test_data/parser/err/0004_use_path_bad_segment.rast
+++ b/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/crates/parser/test_data/parser/err/0048_double_fish.rast b/crates/parser/test_data/parser/err/0048_double_fish.rast
index 7ef1eb98fc..47daaf7b3b 100644
--- a/crates/parser/test_data/parser/err/0048_double_fish.rast
+++ b/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/crates/parser/test_data/parser/inline/err/arg_list_recovery.rast b/crates/parser/test_data/parser/inline/err/arg_list_recovery.rast
index cd5aa680c6..755b20bb27 100644
--- a/crates/parser/test_data/parser/inline/err/arg_list_recovery.rast
+++ b/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/crates/parser/test_data/parser/inline/err/crate_visibility_empty_recover.rast b/crates/parser/test_data/parser/inline/err/crate_visibility_empty_recover.rast
index 681ca6b6e0..172bc099b5 100644
--- a/crates/parser/test_data/parser/inline/err/crate_visibility_empty_recover.rast
+++ b/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/crates/parser/test_data/parser/inline/err/empty_segment.rast b/crates/parser/test_data/parser/inline/err/empty_segment.rast
index b03f5ad9f7..7f256218ef 100644
--- a/crates/parser/test_data/parser/inline/err/empty_segment.rast
+++ b/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/crates/parser/test_data/parser/inline/err/meta_recovery.rast b/crates/parser/test_data/parser/inline/err/meta_recovery.rast
index 926dd50fc8..b5c16e0798 100644
--- a/crates/parser/test_data/parser/inline/err/meta_recovery.rast
+++ b/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/crates/parser/test_data/parser/inline/err/precise_capturing_invalid.rast b/crates/parser/test_data/parser/inline/err/precise_capturing_invalid.rast
new file mode 100644
index 0000000000..5ae184c5fe
--- /dev/null
+++ b/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/crates/parser/test_data/parser/inline/err/precise_capturing_invalid.rs b/crates/parser/test_data/parser/inline/err/precise_capturing_invalid.rs
new file mode 100644
index 0000000000..3180338d33
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/err/precise_capturing_invalid.rs
@@ -0,0 +1 @@
+type T = impl use<self, 1>;
diff --git a/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rast b/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rast
index 741b7845e7..08ae906421 100644
--- a/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rast
+++ b/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/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rs b/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rs
index a4e5b2f693..65398ccb88 100644
--- a/crates/parser/test_data/parser/inline/err/record_literal_before_ellipsis_recovery.rs
+++ b/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/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rast b/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rast
index ad4deeb0b6..ad3b6f208e 100644
--- a/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rast
+++ b/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/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rs b/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rs
index 1eb1aa9b92..9ddc46e0da 100644
--- a/crates/parser/test_data/parser/inline/err/record_literal_field_eq_recovery.rs
+++ b/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/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rast b/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rast
index 0c5b618e6f..9cd07d2ea3 100644
--- a/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rast
+++ b/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/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rs b/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rs
index 1b594e8ab9..a63c3c9e7c 100644
--- a/crates/parser/test_data/parser/inline/err/record_literal_missing_ellipsis_recovery.rs
+++ b/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/crates/parser/test_data/parser/inline/ok/extern_crate.rast b/crates/parser/test_data/parser/inline/ok/extern_crate.rast
index 0a660957d1..aa555ed229 100644
--- a/crates/parser/test_data/parser/inline/ok/extern_crate.rast
+++ b/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/crates/parser/test_data/parser/inline/ok/extern_crate.rs b/crates/parser/test_data/parser/inline/ok/extern_crate.rs
index 49af74e1b7..3c498c8738 100644
--- a/crates/parser/test_data/parser/inline/ok/extern_crate.rs
+++ b/crates/parser/test_data/parser/inline/ok/extern_crate.rs
@@ -1 +1,2 @@
extern crate foo;
+extern crate self;
diff --git a/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rast b/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rast
index 5a5aca96f9..5f0a5b5bb0 100644
--- a/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rast
+++ b/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/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rs b/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rs
index fc76e17dda..6d1873d659 100644
--- a/crates/parser/test_data/parser/inline/ok/extern_crate_rename.rs
+++ b/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/crates/parser/test_data/parser/inline/ok/extern_crate_self.rast b/crates/parser/test_data/parser/inline/ok/extern_crate_self.rast
deleted file mode 100644
index edea4245f2..0000000000
--- a/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/crates/parser/test_data/parser/inline/ok/extern_crate_self.rs b/crates/parser/test_data/parser/inline/ok/extern_crate_self.rs
deleted file mode 100644
index c969ed1093..0000000000
--- a/crates/parser/test_data/parser/inline/ok/extern_crate_self.rs
+++ /dev/null
@@ -1 +0,0 @@
-extern crate self;
diff --git a/crates/parser/test_data/parser/inline/ok/field_expr.rast b/crates/parser/test_data/parser/inline/ok/field_expr.rast
index dd27dc4896..3bac226d34 100644
--- a/crates/parser/test_data/parser/inline/ok/field_expr.rast
+++ b/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/crates/parser/test_data/parser/inline/ok/field_expr.rs b/crates/parser/test_data/parser/inline/ok/field_expr.rs
index 98dbe45a7e..b156d6f7d8 100644
--- a/crates/parser/test_data/parser/inline/ok/field_expr.rs
+++ b/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/crates/parser/test_data/parser/inline/ok/method_call_expr.rast b/crates/parser/test_data/parser/inline/ok/method_call_expr.rast
index b28b8eb673..3245042cf2 100644
--- a/crates/parser/test_data/parser/inline/ok/method_call_expr.rast
+++ b/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/crates/parser/test_data/parser/inline/ok/method_call_expr.rs b/crates/parser/test_data/parser/inline/ok/method_call_expr.rs
index 48bb6381e8..bb54d75c19 100644
--- a/crates/parser/test_data/parser/inline/ok/method_call_expr.rs
+++ b/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()
}