mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-12 05:08:52 +00:00
Fix another issue with fixup reversing
We need to *remove* the whole subtree, but we don't advance `i` by this, because it hasn't gotten there yet (and never will).
This commit is contained in:
parent
cc016df54b
commit
bbcb71a403
4 changed files with 85 additions and 5 deletions
|
@ -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 * ) => {$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)+ ) => {{
|
($span:ident $builder:ident $first:tt $($tail:tt)+ ) => {{
|
||||||
$crate::builtin::quote::__quote!($span $builder $first);
|
$crate::builtin::quote::__quote!($span $builder $first);
|
||||||
|
|
|
@ -441,8 +441,8 @@ fn transform_tt<'a, 'b>(
|
||||||
};
|
};
|
||||||
let len_diff = replacement.len() as i64 - old_len as i64;
|
let len_diff = replacement.len() as i64 - old_len as i64;
|
||||||
tt.splice(i..i + old_len, replacement.flat_tokens().iter().cloned());
|
tt.splice(i..i + old_len, replacement.flat_tokens().iter().cloned());
|
||||||
// `+1` for the loop.
|
// Skip the newly inserted replacement, we don't want to visit it.
|
||||||
i = i.checked_add_signed(len_diff as isize + 1).unwrap();
|
i += replacement.len();
|
||||||
|
|
||||||
for &subtree_idx in &subtrees_stack {
|
for &subtree_idx in &subtrees_stack {
|
||||||
let tt::TokenTree::Subtree(subtree) = &mut tt[subtree_idx] else {
|
let tt::TokenTree::Subtree(subtree) = &mut tt[subtree_idx] else {
|
||||||
|
|
|
@ -867,6 +867,19 @@ fn foo() {
|
||||||
let
|
let
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn regression_18898() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
//- proc_macros: issue_18898
|
||||||
|
#[proc_macros::issue_18898]
|
||||||
|
fn foo() {
|
||||||
|
let
|
||||||
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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#"
|
r#"
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
|
@ -498,7 +498,22 @@ pub fn issue_17479(input: TokenStream) -> TokenStream {
|
||||||
disabled: false,
|
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(
|
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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue