@@ -12,13 +12,13 @@ pub mod legacy_protocol {
1212mod process;
1313
1414use paths:: { AbsPath , AbsPathBuf } ;
15- use span:: Span ;
15+ use span:: { ErasedFileAstId , FIXUP_ERASED_FILE_AST_ID_MARKER , Span } ;
1616use std:: { fmt, io, sync:: Arc , time:: SystemTime } ;
1717
1818use crate :: {
1919 legacy_protocol:: msg:: {
20- ExpandMacro , ExpandMacroData , ExpnGlobals , FlatTree , HAS_GLOBAL_SPANS , PanicMessage ,
21- RUST_ANALYZER_SPAN_SUPPORT , Request , Response , SpanDataIndexMap ,
20+ ExpandMacro , ExpandMacroData , ExpnGlobals , FlatTree , HAS_GLOBAL_SPANS , HASHED_AST_ID ,
21+ PanicMessage , RUST_ANALYZER_SPAN_SUPPORT , Request , Response , SpanDataIndexMap ,
2222 deserialize_span_data_index_map, flat:: serialize_span_data_index_map,
2323 } ,
2424 process:: ProcMacroServerProcess ,
@@ -161,6 +161,38 @@ impl ProcMacro {
161161 self . kind
162162 }
163163
164+ fn needs_fixup_change ( & self ) -> bool {
165+ let version = self . process . version ( ) ;
166+ ( RUST_ANALYZER_SPAN_SUPPORT ..HASHED_AST_ID ) . contains ( & version)
167+ }
168+
169+ /// On some server versions, the fixup ast id is different than ours. So change it to match.
170+ fn change_fixup_to_match_old_server ( & self , tt : & mut tt:: TopSubtree < Span > ) {
171+ const OLD_FIXUP_AST_ID : ErasedFileAstId = ErasedFileAstId :: from_raw ( !0 - 1 ) ;
172+ let change_ast_id = |ast_id : & mut ErasedFileAstId | {
173+ if * ast_id == FIXUP_ERASED_FILE_AST_ID_MARKER {
174+ * ast_id = OLD_FIXUP_AST_ID ;
175+ } else if * ast_id == OLD_FIXUP_AST_ID {
176+ // Swap between them, that means no collision plus the change can be reversed by doing itself.
177+ * ast_id = FIXUP_ERASED_FILE_AST_ID_MARKER ;
178+ }
179+ } ;
180+
181+ for tt in & mut tt. 0 {
182+ match tt {
183+ tt:: TokenTree :: Leaf ( tt:: Leaf :: Ident ( tt:: Ident { span, .. } ) )
184+ | tt:: TokenTree :: Leaf ( tt:: Leaf :: Literal ( tt:: Literal { span, .. } ) )
185+ | tt:: TokenTree :: Leaf ( tt:: Leaf :: Punct ( tt:: Punct { span, .. } ) ) => {
186+ change_ast_id ( & mut span. anchor . ast_id ) ;
187+ }
188+ tt:: TokenTree :: Subtree ( subtree) => {
189+ change_ast_id ( & mut subtree. delimiter . open . anchor . ast_id ) ;
190+ change_ast_id ( & mut subtree. delimiter . close . anchor . ast_id ) ;
191+ }
192+ }
193+ }
194+ }
195+
164196 /// Expands the procedural macro by sending an expansion request to the server.
165197 /// This includes span information and environmental context.
166198 pub fn expand (
@@ -173,6 +205,20 @@ impl ProcMacro {
173205 mixed_site : Span ,
174206 current_dir : String ,
175207 ) -> Result < Result < tt:: TopSubtree < Span > , PanicMessage > , ServerError > {
208+ let ( mut subtree, mut attr) = ( subtree, attr) ;
209+ let ( mut subtree_changed, mut attr_changed) ;
210+ if self . needs_fixup_change ( ) {
211+ subtree_changed = tt:: TopSubtree :: from_subtree ( subtree) ;
212+ self . change_fixup_to_match_old_server ( & mut subtree_changed) ;
213+ subtree = subtree_changed. view ( ) ;
214+
215+ if let Some ( attr) = & mut attr {
216+ attr_changed = tt:: TopSubtree :: from_subtree ( * attr) ;
217+ self . change_fixup_to_match_old_server ( & mut attr_changed) ;
218+ * attr = attr_changed. view ( ) ;
219+ }
220+ }
221+
176222 let version = self . process . version ( ) ;
177223
178224 let mut span_data_table = SpanDataIndexMap :: default ( ) ;
@@ -205,15 +251,23 @@ impl ProcMacro {
205251 let response = self . process . send_task ( Request :: ExpandMacro ( Box :: new ( task) ) ) ?;
206252
207253 match response {
208- Response :: ExpandMacro ( it) => {
209- Ok ( it. map ( |tree| FlatTree :: to_subtree_resolved ( tree, version, & span_data_table) ) )
210- }
254+ Response :: ExpandMacro ( it) => Ok ( it. map ( |tree| {
255+ let mut expanded = FlatTree :: to_subtree_resolved ( tree, version, & span_data_table) ;
256+ if self . needs_fixup_change ( ) {
257+ self . change_fixup_to_match_old_server ( & mut expanded) ;
258+ }
259+ expanded
260+ } ) ) ,
211261 Response :: ExpandMacroExtended ( it) => Ok ( it. map ( |resp| {
212- FlatTree :: to_subtree_resolved (
262+ let mut expanded = FlatTree :: to_subtree_resolved (
213263 resp. tree ,
214264 version,
215265 & deserialize_span_data_index_map ( & resp. span_data_table ) ,
216- )
266+ ) ;
267+ if self . needs_fixup_change ( ) {
268+ self . change_fixup_to_match_old_server ( & mut expanded) ;
269+ }
270+ expanded
217271 } ) ) ,
218272 _ => Err ( ServerError { message : "unexpected response" . to_owned ( ) , io : None } ) ,
219273 }
0 commit comments