@@ -550,7 +550,9 @@ impl<'db> SemanticsImpl<'db> {
550
550
string : & ast:: String ,
551
551
) -> Option < Vec < ( TextRange , Option < PathResolution > ) > > {
552
552
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| {
554
556
( || {
555
557
let token = token. value ;
556
558
let string = ast:: String :: cast ( token) ?;
@@ -576,8 +578,9 @@ impl<'db> SemanticsImpl<'db> {
576
578
offset : TextSize ,
577
579
) -> Option < ( TextRange , Option < PathResolution > ) > {
578
580
let original_string = ast:: String :: cast ( original_token. clone ( ) ) ?;
581
+ let original_token = self . wrap_token_infile ( original_token) . into_real_file ( ) . ok ( ) ?;
579
582
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| {
581
584
( || {
582
585
let token = token. value ;
583
586
self . resolve_offset_in_format_args (
@@ -617,30 +620,37 @@ impl<'db> SemanticsImpl<'db> {
617
620
Some ( it) => it,
618
621
None => return res,
619
622
} ;
623
+ let file = self . find_file ( node. syntax ( ) ) ;
624
+ let Some ( file_id) = file. file_id . file_id ( ) else {
625
+ return res;
626
+ } ;
620
627
621
628
if first == last {
622
629
// 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
+ ) ;
633
643
} else {
634
644
// Descend first and last token, then zip them to look for the node they belong to
635
645
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| {
637
647
scratch. push ( token) ;
638
648
CONTINUE_NO_BREAKS
639
649
} ) ;
640
650
641
651
let mut scratch = scratch. into_iter ( ) ;
642
652
self . descend_into_macros_impl (
643
- last,
653
+ InRealFile :: new ( file_id , last) ,
644
654
& mut |InFile { value : last, file_id : last_fid } | {
645
655
if let Some ( InFile { value : first, file_id : first_fid } ) = scratch. next ( ) {
646
656
if first_fid == last_fid {
@@ -669,18 +679,22 @@ impl<'db> SemanticsImpl<'db> {
669
679
token : SyntaxToken ,
670
680
mut cb : impl FnMut ( InFile < SyntaxToken > ) ,
671
681
) {
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
+ }
676
688
}
677
689
678
690
pub fn descend_into_macros ( & self , token : SyntaxToken ) -> SmallVec < [ SyntaxToken ; 1 ] > {
679
691
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
+ }
684
698
if res. is_empty ( ) {
685
699
res. push ( token) ;
686
700
}
@@ -689,7 +703,7 @@ impl<'db> SemanticsImpl<'db> {
689
703
690
704
pub fn descend_into_macros_breakable < T > (
691
705
& self ,
692
- token : SyntaxToken ,
706
+ token : InRealFile < SyntaxToken > ,
693
707
mut cb : impl FnMut ( InFile < SyntaxToken > ) -> ControlFlow < T > ,
694
708
) -> Option < T > {
695
709
self . descend_into_macros_impl ( token. clone ( ) , & mut cb)
@@ -721,28 +735,36 @@ impl<'db> SemanticsImpl<'db> {
721
735
pub fn descend_into_macros_single_exact ( & self , token : SyntaxToken ) -> SyntaxToken {
722
736
let text = token. text ( ) ;
723
737
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
+ }
735
753
. unwrap_or ( token)
736
754
}
737
755
738
756
fn descend_into_macros_impl < T > (
739
757
& self ,
740
- token : SyntaxToken ,
758
+ InRealFile { value : token, file_id } : InRealFile < SyntaxToken > ,
741
759
f : & mut dyn FnMut ( InFile < SyntaxToken > ) -> ControlFlow < T > ,
742
760
) -> Option < T > {
743
761
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| {
746
768
let file_id = sa. file_id . file_id ( ) ?;
747
769
Some ( (
748
770
sa,
@@ -1400,11 +1422,13 @@ impl<'db> SemanticsImpl<'db> {
1400
1422
1401
1423
/// Returns none if the file of the node is not part of a crate.
1402
1424
fn analyze ( & self , node : & SyntaxNode ) -> Option < SourceAnalyzer > {
1425
+ let node = self . find_file ( node) ;
1403
1426
self . analyze_impl ( node, None , true )
1404
1427
}
1405
1428
1406
1429
/// Returns none if the file of the node is not part of a crate.
1407
1430
fn analyze_no_infer ( & self , node : & SyntaxNode ) -> Option < SourceAnalyzer > {
1431
+ let node = self . find_file ( node) ;
1408
1432
self . analyze_impl ( node, None , false )
1409
1433
}
1410
1434
@@ -1413,17 +1437,17 @@ impl<'db> SemanticsImpl<'db> {
1413
1437
node : & SyntaxNode ,
1414
1438
offset : TextSize ,
1415
1439
) -> Option < SourceAnalyzer > {
1440
+ let node = self . find_file ( node) ;
1416
1441
self . analyze_impl ( node, Some ( offset) , false )
1417
1442
}
1418
1443
1419
1444
fn analyze_impl (
1420
1445
& self ,
1421
- node : & SyntaxNode ,
1446
+ node : InFile < & SyntaxNode > ,
1422
1447
offset : Option < TextSize > ,
1423
1448
infer_body : bool ,
1424
1449
) -> Option < SourceAnalyzer > {
1425
1450
let _p = tracing:: info_span!( "SemanticsImpl::analyze_impl" ) . entered ( ) ;
1426
- let node = self . find_file ( node) ;
1427
1451
1428
1452
let container = self . with_ctx ( |ctx| ctx. find_container ( node) ) ?;
1429
1453
@@ -1468,6 +1492,11 @@ impl<'db> SemanticsImpl<'db> {
1468
1492
InFile :: new ( file_id, node)
1469
1493
}
1470
1494
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
+
1471
1500
/// Wraps the node in a [`InFile`] with the file id it belongs to.
1472
1501
fn find_file < ' node > ( & self , node : & ' node SyntaxNode ) -> InFile < & ' node SyntaxNode > {
1473
1502
let root_node = find_root ( node) ;
0 commit comments