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:
Chayim Refael Friedman 2025-01-09 22:02:44 +02:00
parent cc016df54b
commit bbcb71a403
4 changed files with 85 additions and 5 deletions

View file

@ -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);

View file

@ -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 {

View file

@ -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
}
"#, "#,
); );
} }

View file

@ -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
}
})
}
}