@@ -550,7 +550,9 @@ impl<'db> SemanticsImpl<'db> {
550550 string : & ast:: String ,
551551 ) -> Option < Vec < ( TextRange , Option < PathResolution > ) > > {
552552 let quote = string. open_quote_text_range ( ) ?;
553- self . descend_into_macros_breakable ( string. syntax ( ) . clone ( ) , |token| {
553+
554+ let token = self . wrap_token_infile ( string. syntax ( ) . clone ( ) ) . into_real_file ( ) . ok ( ) ?;
555+ self . descend_into_macros_breakable ( token, |token| {
554556 ( || {
555557 let token = token. value ;
556558 let string = ast:: String :: cast ( token) ?;
@@ -576,8 +578,9 @@ impl<'db> SemanticsImpl<'db> {
576578 offset : TextSize ,
577579 ) -> Option < ( TextRange , Option < PathResolution > ) > {
578580 let original_string = ast:: String :: cast ( original_token. clone ( ) ) ?;
581+ let original_token = self . wrap_token_infile ( original_token) . into_real_file ( ) . ok ( ) ?;
579582 let quote = original_string. open_quote_text_range ( ) ?;
580- self . descend_into_macros_breakable ( original_token. clone ( ) , |token| {
583+ self . descend_into_macros_breakable ( original_token, |token| {
581584 ( || {
582585 let token = token. value ;
583586 self . resolve_offset_in_format_args (
@@ -617,30 +620,37 @@ impl<'db> SemanticsImpl<'db> {
617620 Some ( it) => it,
618621 None => return res,
619622 } ;
623+ let file = self . find_file ( node. syntax ( ) ) ;
624+ let Some ( file_id) = file. file_id . file_id ( ) else {
625+ return res;
626+ } ;
620627
621628 if first == last {
622629 // node is just the token, so descend the token
623- self . descend_into_macros_impl ( first, & mut |InFile { value, .. } | {
624- if let Some ( node) = value
625- . parent_ancestors ( )
626- . take_while ( |it| it. text_range ( ) == value. text_range ( ) )
627- . find_map ( N :: cast)
628- {
629- res. push ( node)
630- }
631- CONTINUE_NO_BREAKS
632- } ) ;
630+ self . descend_into_macros_impl (
631+ InRealFile :: new ( file_id, first) ,
632+ & mut |InFile { value, .. } | {
633+ if let Some ( node) = value
634+ . parent_ancestors ( )
635+ . take_while ( |it| it. text_range ( ) == value. text_range ( ) )
636+ . find_map ( N :: cast)
637+ {
638+ res. push ( node)
639+ }
640+ CONTINUE_NO_BREAKS
641+ } ,
642+ ) ;
633643 } else {
634644 // Descend first and last token, then zip them to look for the node they belong to
635645 let mut scratch: SmallVec < [ _ ; 1 ] > = smallvec ! [ ] ;
636- self . descend_into_macros_impl ( first, & mut |token| {
646+ self . descend_into_macros_impl ( InRealFile :: new ( file_id , first) , & mut |token| {
637647 scratch. push ( token) ;
638648 CONTINUE_NO_BREAKS
639649 } ) ;
640650
641651 let mut scratch = scratch. into_iter ( ) ;
642652 self . descend_into_macros_impl (
643- last,
653+ InRealFile :: new ( file_id , last) ,
644654 & mut |InFile { value : last, file_id : last_fid } | {
645655 if let Some ( InFile { value : first, file_id : first_fid } ) = scratch. next ( ) {
646656 if first_fid == last_fid {
@@ -669,18 +679,22 @@ impl<'db> SemanticsImpl<'db> {
669679 token : SyntaxToken ,
670680 mut cb : impl FnMut ( InFile < SyntaxToken > ) ,
671681 ) {
672- self . descend_into_macros_impl ( token. clone ( ) , & mut |t| {
673- cb ( t) ;
674- CONTINUE_NO_BREAKS
675- } ) ;
682+ if let Ok ( token) = self . wrap_token_infile ( token) . into_real_file ( ) {
683+ self . descend_into_macros_impl ( token, & mut |t| {
684+ cb ( t) ;
685+ CONTINUE_NO_BREAKS
686+ } ) ;
687+ }
676688 }
677689
678690 pub fn descend_into_macros ( & self , token : SyntaxToken ) -> SmallVec < [ SyntaxToken ; 1 ] > {
679691 let mut res = smallvec ! [ ] ;
680- self . descend_into_macros_impl ( token. clone ( ) , & mut |t| {
681- res. push ( t. value ) ;
682- CONTINUE_NO_BREAKS
683- } ) ;
692+ if let Ok ( token) = self . wrap_token_infile ( token. clone ( ) ) . into_real_file ( ) {
693+ self . descend_into_macros_impl ( token, & mut |t| {
694+ res. push ( t. value ) ;
695+ CONTINUE_NO_BREAKS
696+ } ) ;
697+ }
684698 if res. is_empty ( ) {
685699 res. push ( token) ;
686700 }
@@ -689,7 +703,7 @@ impl<'db> SemanticsImpl<'db> {
689703
690704 pub fn descend_into_macros_breakable < T > (
691705 & self ,
692- token : SyntaxToken ,
706+ token : InRealFile < SyntaxToken > ,
693707 mut cb : impl FnMut ( InFile < SyntaxToken > ) -> ControlFlow < T > ,
694708 ) -> Option < T > {
695709 self . descend_into_macros_impl ( token. clone ( ) , & mut cb)
@@ -721,28 +735,36 @@ impl<'db> SemanticsImpl<'db> {
721735 pub fn descend_into_macros_single_exact ( & self , token : SyntaxToken ) -> SyntaxToken {
722736 let text = token. text ( ) ;
723737 let kind = token. kind ( ) ;
724-
725- self . descend_into_macros_breakable ( token. clone ( ) , |InFile { value, file_id : _ } | {
726- let mapped_kind = value. kind ( ) ;
727- let any_ident_match = || kind. is_any_identifier ( ) && value. kind ( ) . is_any_identifier ( ) ;
728- let matches = ( kind == mapped_kind || any_ident_match ( ) ) && text == value. text ( ) ;
729- if matches {
730- ControlFlow :: Break ( value)
731- } else {
732- ControlFlow :: Continue ( ( ) )
733- }
734- } )
738+ if let Ok ( token) = self . wrap_token_infile ( token. clone ( ) ) . into_real_file ( ) {
739+ self . descend_into_macros_breakable ( token. clone ( ) , |InFile { value, file_id : _ } | {
740+ let mapped_kind = value. kind ( ) ;
741+ let any_ident_match =
742+ || kind. is_any_identifier ( ) && value. kind ( ) . is_any_identifier ( ) ;
743+ let matches = ( kind == mapped_kind || any_ident_match ( ) ) && text == value. text ( ) ;
744+ if matches {
745+ ControlFlow :: Break ( value)
746+ } else {
747+ ControlFlow :: Continue ( ( ) )
748+ }
749+ } )
750+ } else {
751+ None
752+ }
735753 . unwrap_or ( token)
736754 }
737755
738756 fn descend_into_macros_impl < T > (
739757 & self ,
740- token : SyntaxToken ,
758+ InRealFile { value : token, file_id } : InRealFile < SyntaxToken > ,
741759 f : & mut dyn FnMut ( InFile < SyntaxToken > ) -> ControlFlow < T > ,
742760 ) -> Option < T > {
743761 let _p = tracing:: info_span!( "descend_into_macros_impl" ) . entered ( ) ;
744- let ( sa, span, file_id) =
745- token. parent ( ) . and_then ( |parent| self . analyze_no_infer ( & parent) ) . and_then ( |sa| {
762+ let ( sa, span, file_id) = token
763+ . parent ( )
764+ . and_then ( |parent| {
765+ self . analyze_impl ( InRealFile :: new ( file_id, & parent) . into ( ) , None , false )
766+ } )
767+ . and_then ( |sa| {
746768 let file_id = sa. file_id . file_id ( ) ?;
747769 Some ( (
748770 sa,
@@ -1400,11 +1422,13 @@ impl<'db> SemanticsImpl<'db> {
14001422
14011423 /// Returns none if the file of the node is not part of a crate.
14021424 fn analyze ( & self , node : & SyntaxNode ) -> Option < SourceAnalyzer > {
1425+ let node = self . find_file ( node) ;
14031426 self . analyze_impl ( node, None , true )
14041427 }
14051428
14061429 /// Returns none if the file of the node is not part of a crate.
14071430 fn analyze_no_infer ( & self , node : & SyntaxNode ) -> Option < SourceAnalyzer > {
1431+ let node = self . find_file ( node) ;
14081432 self . analyze_impl ( node, None , false )
14091433 }
14101434
@@ -1413,17 +1437,17 @@ impl<'db> SemanticsImpl<'db> {
14131437 node : & SyntaxNode ,
14141438 offset : TextSize ,
14151439 ) -> Option < SourceAnalyzer > {
1440+ let node = self . find_file ( node) ;
14161441 self . analyze_impl ( node, Some ( offset) , false )
14171442 }
14181443
14191444 fn analyze_impl (
14201445 & self ,
1421- node : & SyntaxNode ,
1446+ node : InFile < & SyntaxNode > ,
14221447 offset : Option < TextSize > ,
14231448 infer_body : bool ,
14241449 ) -> Option < SourceAnalyzer > {
14251450 let _p = tracing:: info_span!( "SemanticsImpl::analyze_impl" ) . entered ( ) ;
1426- let node = self . find_file ( node) ;
14271451
14281452 let container = self . with_ctx ( |ctx| ctx. find_container ( node) ) ?;
14291453
@@ -1468,6 +1492,11 @@ impl<'db> SemanticsImpl<'db> {
14681492 InFile :: new ( file_id, node)
14691493 }
14701494
1495+ fn wrap_token_infile ( & self , token : SyntaxToken ) -> InFile < SyntaxToken > {
1496+ let InFile { file_id, .. } = self . find_file ( & token. parent ( ) . unwrap ( ) ) ;
1497+ InFile :: new ( file_id, token)
1498+ }
1499+
14711500 /// Wraps the node in a [`InFile`] with the file id it belongs to.
14721501 fn find_file < ' node > ( & self , node : & ' node SyntaxNode ) -> InFile < & ' node SyntaxNode > {
14731502 let root_node = find_root ( node) ;
0 commit comments