Unnamed repository; edit this file 'description' to name the repository.
Don't remap float tokens to `INT_NUMBER`
Jonas Schievink 2022-05-13
parent f8c0062 · commit cb5e8da
-rw-r--r--crates/hir-def/src/macro_expansion_tests/proc_macros.rs37
-rw-r--r--crates/mbe/src/syntax_bridge.rs2
-rw-r--r--crates/parser/src/grammar.rs4
-rw-r--r--crates/parser/test_data/parser/inline/ok/0011_field_expr.rast6
4 files changed, 45 insertions, 4 deletions
diff --git a/crates/hir-def/src/macro_expansion_tests/proc_macros.rs b/crates/hir-def/src/macro_expansion_tests/proc_macros.rs
index 0ca30fb799..e4b065d020 100644
--- a/crates/hir-def/src/macro_expansion_tests/proc_macros.rs
+++ b/crates/hir-def/src/macro_expansion_tests/proc_macros.rs
@@ -92,3 +92,40 @@ fn foo() {
}"##]],
);
}
+
+#[test]
+fn float_parsing_panic() {
+ // Regression test for https://github.com/rust-lang/rust-analyzer/issues/12211
+ check(
+ r#"
+//- proc_macros: identity
+macro_rules! id {
+ ($($t:tt)*) => {
+ $($t)*
+ };
+}
+
+id! {
+ #[proc_macros::identity]
+ impl Foo for WrapBj {
+ async fn foo(&self) {
+ self.0. id().await;
+ }
+ }
+}
+"#,
+ expect![[r##"
+macro_rules! id {
+ ($($t:tt)*) => {
+ $($t)*
+ };
+}
+
+#[proc_macros::identity] impl Foo for WrapBj {
+ async fn foo(&self ) {
+ self .0.id().await ;
+ }
+}
+"##]],
+ );
+}
diff --git a/crates/mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs
index fb6f8d66c6..361633e39d 100644
--- a/crates/mbe/src/syntax_bridge.rs
+++ b/crates/mbe/src/syntax_bridge.rs
@@ -243,6 +243,8 @@ fn convert_tokens<C: TokenConvertor>(conv: &mut C) -> tt::Subtree {
let char = match token.to_char(conv) {
Some(c) => c,
None => {
+ // FIXME: this isn't really correct, `to_char` yields the *first* char of the token,
+ // and this is relevant when eg. creating 2 `tt::Punct` from a single `::` token
panic!("Token from lexer must be single char: token = {:#?}", token);
}
};
diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs
index f68d7196c8..4ebf2157c6 100644
--- a/crates/parser/src/grammar.rs
+++ b/crates/parser/src/grammar.rs
@@ -324,7 +324,9 @@ fn name_ref_or_index(p: &mut Parser) {
);
let m = p.start();
if p.at(FLOAT_NUMBER_PART) || p.at_ts(FLOAT_LITERAL_FIRST) {
- p.bump_remap(INT_NUMBER);
+ // Ideally we'd remap this to `INT_NUMBER` instead, but that causes the MBE conversion to
+ // lose track of what's a float and what isn't, causing panics.
+ p.bump_remap(FLOAT_NUMBER_PART);
} else {
p.bump_any();
}
diff --git a/crates/parser/test_data/parser/inline/ok/0011_field_expr.rast b/crates/parser/test_data/parser/inline/ok/0011_field_expr.rast
index 19fab593fa..a1efb3a9fb 100644
--- a/crates/parser/test_data/parser/inline/ok/0011_field_expr.rast
+++ b/crates/parser/test_data/parser/inline/ok/0011_field_expr.rast
@@ -50,7 +50,7 @@ SOURCE_FILE
IDENT "x"
DOT "."
NAME_REF
- INT_NUMBER "0"
+ FLOAT_NUMBER_PART "0"
DOT "."
WHITESPACE " "
NAME_REF
@@ -67,10 +67,10 @@ SOURCE_FILE
IDENT "x"
DOT "."
NAME_REF
- INT_NUMBER "0"
+ FLOAT_NUMBER_PART "0"
DOT "."
NAME_REF
- INT_NUMBER "1"
+ FLOAT_NUMBER_PART "1"
SEMICOLON ";"
WHITESPACE "\n "
EXPR_STMT