mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-10-30 19:49:36 +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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Chayim Refael Friedman
						Chayim Refael Friedman