Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-expand/src/builtin/quote.rs1
-rw-r--r--crates/hir-expand/src/fixup.rs4
-rw-r--r--crates/ide/src/inlay_hints.rs13
-rw-r--r--crates/test-fixture/src/lib.rs72
4 files changed, 85 insertions, 5 deletions
diff --git a/crates/hir-expand/src/builtin/quote.rs b/crates/hir-expand/src/builtin/quote.rs
index fcd242bb49..9b637fc768 100644
--- a/crates/hir-expand/src/builtin/quote.rs
+++ b/crates/hir-expand/src/builtin/quote.rs
@@ -102,6 +102,7 @@ macro_rules! quote_impl__ {
($span:ident $builder:ident # ) => {$crate::builtin::quote::__quote!(@PUNCT($span $builder) '#')};
($span:ident $builder:ident $ ) => {$crate::builtin::quote::__quote!(@PUNCT($span $builder) '$')};
($span:ident $builder:ident * ) => {$crate::builtin::quote::__quote!(@PUNCT($span $builder) '*')};
+ ($span:ident $builder:ident = ) => {$crate::builtin::quote::__quote!(@PUNCT($span $builder) '=')};
($span:ident $builder:ident $first:tt $($tail:tt)+ ) => {{
$crate::builtin::quote::__quote!($span $builder $first);
diff --git a/crates/hir-expand/src/fixup.rs b/crates/hir-expand/src/fixup.rs
index a2d44ff376..c4113de7a5 100644
--- a/crates/hir-expand/src/fixup.rs
+++ b/crates/hir-expand/src/fixup.rs
@@ -441,8 +441,8 @@ fn transform_tt<'a, 'b>(
};
let len_diff = replacement.len() as i64 - old_len as i64;
tt.splice(i..i + old_len, replacement.flat_tokens().iter().cloned());
- // `+1` for the loop.
- i = i.checked_add_signed(len_diff as isize + 1).unwrap();
+ // Skip the newly inserted replacement, we don't want to visit it.
+ i += replacement.len();
for &subtree_idx in &subtrees_stack {
let tt::TokenTree::Subtree(subtree) = &mut tt[subtree_idx] else {
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index faa65019ee..31b1774bb7 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -870,4 +870,17 @@ fn foo() {
"#,
);
}
+
+ #[test]
+ fn regression_18898() {
+ check(
+ r#"
+//- proc_macros: issue_18898
+#[proc_macros::issue_18898]
+fn foo() {
+ let
+}
+"#,
+ );
+ }
}
diff --git a/crates/test-fixture/src/lib.rs b/crates/test-fixture/src/lib.rs
index 0e72d79687..422aa08e35 100644
--- a/crates/test-fixture/src/lib.rs
+++ b/crates/test-fixture/src/lib.rs
@@ -376,8 +376,8 @@ impl ChangeFixture {
}
}
-fn default_test_proc_macros() -> [(String, ProcMacro); 8] {
- [
+fn default_test_proc_macros() -> Box<[(String, ProcMacro)]> {
+ Box::new([
(
r#"
#[proc_macro_attribute]
@@ -498,7 +498,22 @@ pub fn issue_17479(input: TokenStream) -> TokenStream {
disabled: false,
},
),
- ]
+ (
+ r#"
+#[proc_macro_attribute]
+pub fn issue_18898(_attr: TokenStream, input: TokenStream) -> TokenStream {
+ input
+}
+"#
+ .into(),
+ ProcMacro {
+ name: Symbol::intern("issue_18898"),
+ kind: ProcMacroKind::Bang,
+ expander: sync::Arc::new(Issue18898ProcMacroExpander),
+ disabled: false,
+ },
+ ),
+ ])
}
fn filter_test_proc_macros(
@@ -801,3 +816,54 @@ impl ProcMacroExpander for Issue17479ProcMacroExpander {
})
}
}
+
+// Reads ident type within string quotes, for issue #17479.
+#[derive(Debug)]
+struct Issue18898ProcMacroExpander;
+impl ProcMacroExpander for Issue18898ProcMacroExpander {
+ fn expand(
+ &self,
+ subtree: &TopSubtree,
+ _: Option<&TopSubtree>,
+ _: &Env,
+ def_site: Span,
+ _: Span,
+ _: Span,
+ _: Option<String>,
+ ) -> Result<TopSubtree, ProcMacroExpansionError> {
+ let span = subtree
+ .token_trees()
+ .flat_tokens()
+ .last()
+ .ok_or_else(|| ProcMacroExpansionError::Panic("malformed input".to_owned()))?
+ .first_span();
+ let overly_long_subtree = quote! {span =>
+ {
+ let a = 5;
+ let a = 5;
+ let a = 5;
+ let a = 5;
+ let a = 5;
+ let a = 5;
+ let a = 5;
+ let a = 5;
+ let a = 5;
+ let a = 5;
+ let a = 5;
+ let a = 5;
+ let a = 5;
+ let a = 5;
+ let a = 5;
+ let a = 5;
+ let a = 5;
+ let a = 5;
+ let a = 5;
+ }
+ };
+ Ok(quote! { def_site =>
+ fn foo() {
+ #overly_long_subtree
+ }
+ })
+ }
+}