@@ -154,8 +154,9 @@ pub enum MacroDefKind {
154
154
struct EagerCallInfo {
155
155
/// NOTE: This can be *either* the expansion result, *or* the argument to the eager macro!
156
156
arg : Arc < ( tt:: Subtree , TokenMap ) > ,
157
- /// call id of the eager macro's input file. If this is none, macro call containing this call info
158
- /// is an eager macro's input, otherwise it is its output.
157
+ /// Call id of the eager macro's input file (this is the macro file for its fully expanded input).
158
+ /// If this is none, `arg` contains the pre-expanded input, otherwise arg contains the
159
+ /// post-expanded input.
159
160
arg_id : Option < MacroCallId > ,
160
161
error : Option < ExpandError > ,
161
162
}
@@ -276,13 +277,20 @@ impl HirFileId {
276
277
277
278
let macro_def = db. macro_def ( loc. def ) . ok ( ) ?;
278
279
let ( parse, exp_map) = db. parse_macro_expansion ( macro_file) . value ;
279
- let macro_arg = db. macro_arg ( macro_file. macro_call_id ) . unwrap_or_else ( || {
280
- Arc :: new ( (
281
- tt:: Subtree { delimiter : tt:: Delimiter :: UNSPECIFIED , token_trees : Vec :: new ( ) } ,
282
- Default :: default ( ) ,
283
- Default :: default ( ) ,
284
- ) )
285
- } ) ;
280
+ let expanded = InMacroFile { file_id : macro_file, value : parse. syntax_node ( ) } ;
281
+
282
+ let macro_arg = db
283
+ . macro_arg ( match loc. eager . as_deref ( ) {
284
+ Some ( & EagerCallInfo { arg_id : Some ( arg_id) , .. } ) => arg_id,
285
+ _ => macro_file. macro_call_id ,
286
+ } )
287
+ . unwrap_or_else ( || {
288
+ Arc :: new ( (
289
+ tt:: Subtree { delimiter : tt:: Delimiter :: UNSPECIFIED , token_trees : Vec :: new ( ) } ,
290
+ Default :: default ( ) ,
291
+ Default :: default ( ) ,
292
+ ) )
293
+ } ) ;
286
294
287
295
let def = loc. def . ast_id ( ) . left ( ) . and_then ( |id| {
288
296
let def_tt = match id. to_node ( db) {
@@ -309,8 +317,8 @@ impl HirFileId {
309
317
} ) ;
310
318
311
319
Some ( ExpansionInfo {
312
- expanded : InFile :: new ( self , parse . syntax_node ( ) ) ,
313
- arg : InFile :: new ( loc . kind . file_id ( ) , arg_tt) ,
320
+ expanded,
321
+ arg : arg_tt,
314
322
attr_input_or_mac_def,
315
323
macro_arg_shift : mbe:: Shift :: new ( & macro_arg. 0 ) ,
316
324
macro_arg,
@@ -603,13 +611,18 @@ impl MacroCallKind {
603
611
FileRange { range, file_id }
604
612
}
605
613
606
- fn arg ( & self , db : & dyn db:: ExpandDatabase ) -> Option < SyntaxNode > {
614
+ fn arg ( & self , db : & dyn db:: ExpandDatabase ) -> Option < InFile < SyntaxNode > > {
607
615
match self {
608
- MacroCallKind :: FnLike { ast_id, .. } => {
609
- Some ( ast_id. to_node ( db) . token_tree ( ) ?. syntax ( ) . clone ( ) )
616
+ MacroCallKind :: FnLike { ast_id, .. } => ast_id
617
+ . to_in_file_node ( db)
618
+ . map ( |it| Some ( it. token_tree ( ) ?. syntax ( ) . clone ( ) ) )
619
+ . transpose ( ) ,
620
+ MacroCallKind :: Derive { ast_id, .. } => {
621
+ Some ( ast_id. to_in_file_node ( db) . syntax ( ) . cloned ( ) )
622
+ }
623
+ MacroCallKind :: Attr { ast_id, .. } => {
624
+ Some ( ast_id. to_in_file_node ( db) . syntax ( ) . cloned ( ) )
610
625
}
611
- MacroCallKind :: Derive { ast_id, .. } => Some ( ast_id. to_node ( db) . syntax ( ) . clone ( ) ) ,
612
- MacroCallKind :: Attr { ast_id, .. } => Some ( ast_id. to_node ( db) . syntax ( ) . clone ( ) ) ,
613
626
}
614
627
}
615
628
}
@@ -627,7 +640,7 @@ impl MacroCallId {
627
640
/// ExpansionInfo mainly describes how to map text range between src and expanded macro
628
641
#[ derive( Debug , Clone , PartialEq , Eq ) ]
629
642
pub struct ExpansionInfo {
630
- expanded : InFile < SyntaxNode > ,
643
+ expanded : InMacroFile < SyntaxNode > ,
631
644
/// The argument TokenTree or item for attributes
632
645
arg : InFile < SyntaxNode > ,
633
646
/// The `macro_rules!` or attribute input.
@@ -643,7 +656,7 @@ pub struct ExpansionInfo {
643
656
644
657
impl ExpansionInfo {
645
658
pub fn expanded ( & self ) -> InFile < SyntaxNode > {
646
- self . expanded . clone ( )
659
+ self . expanded . clone ( ) . into ( )
647
660
}
648
661
649
662
pub fn call_node ( & self ) -> Option < InFile < SyntaxNode > > {
@@ -674,7 +687,7 @@ impl ExpansionInfo {
674
687
let token_id_in_attr_input = if let Some ( item) = item {
675
688
// check if we are mapping down in an attribute input
676
689
// this is a special case as attributes can have two inputs
677
- let call_id = self . expanded . file_id . macro_file ( ) ? . macro_call_id ;
690
+ let call_id = self . expanded . file_id . macro_call_id ;
678
691
let loc = db. lookup_intern_macro_call ( call_id) ;
679
692
680
693
let token_range = token. value . text_range ( ) ;
@@ -730,7 +743,7 @@ impl ExpansionInfo {
730
743
. ranges_by_token ( token_id, token. value . kind ( ) )
731
744
. flat_map ( move |range| self . expanded . value . covering_element ( range) . into_token ( ) ) ;
732
745
733
- Some ( tokens. map ( move |token| self . expanded . with_value ( token) ) )
746
+ Some ( tokens. map ( move |token| InFile :: new ( self . expanded . file_id . into ( ) , token) ) )
734
747
}
735
748
736
749
/// Map a token up out of the expansion it resides in into the arguments of the macro call of the expansion.
@@ -739,12 +752,14 @@ impl ExpansionInfo {
739
752
db : & dyn db:: ExpandDatabase ,
740
753
token : InFile < & SyntaxToken > ,
741
754
) -> Option < ( InFile < SyntaxToken > , Origin ) > {
755
+ assert_eq ! ( token. file_id, self . expanded. file_id. into( ) ) ;
756
+ dbg ! ( & token) ;
742
757
// Fetch the id through its text range,
743
758
let token_id = self . exp_map . token_by_range ( token. value . text_range ( ) ) ?;
744
759
// conditionally unshifting the id to accommodate for macro-rules def site
745
760
let ( mut token_id, origin) = self . macro_def . map_id_up ( token_id) ;
746
761
747
- let call_id = self . expanded . file_id . macro_file ( ) ? . macro_call_id ;
762
+ let call_id = self . expanded . file_id . macro_call_id ;
748
763
let loc = db. lookup_intern_macro_call ( call_id) ;
749
764
750
765
// Special case: map tokens from `include!` expansions to the included file
@@ -778,7 +793,7 @@ impl ExpansionInfo {
778
793
}
779
794
}
780
795
}
781
- _ => match origin {
796
+ _ => match dbg ! ( origin) {
782
797
mbe:: Origin :: Call => ( & self . macro_arg . 1 , self . arg . clone ( ) ) ,
783
798
mbe:: Origin :: Def => match ( & * self . macro_def , & self . attr_input_or_mac_def ) {
784
799
( TokenExpander :: DeclarativeMacro { def_site_token_map, .. } , Some ( tt) ) => {
@@ -790,6 +805,8 @@ impl ExpansionInfo {
790
805
} ;
791
806
792
807
let range = token_map. first_range_by_token ( token_id, token. value . kind ( ) ) ?;
808
+ dbg ! ( & tt) ;
809
+ dbg ! ( range) ;
793
810
let token =
794
811
tt. value . covering_element ( range + tt. value . text_range ( ) . start ( ) ) . into_token ( ) ?;
795
812
Some ( ( tt. with_value ( token) , origin) )
@@ -805,6 +822,9 @@ impl<N: AstIdNode> AstId<N> {
805
822
pub fn to_node ( & self , db : & dyn db:: ExpandDatabase ) -> N {
806
823
self . to_ptr ( db) . to_node ( & db. parse_or_expand ( self . file_id ) )
807
824
}
825
+ pub fn to_in_file_node ( & self , db : & dyn db:: ExpandDatabase ) -> InFile < N > {
826
+ InFile :: new ( self . file_id , self . to_ptr ( db) . to_node ( & db. parse_or_expand ( self . file_id ) ) )
827
+ }
808
828
pub fn to_ptr ( & self , db : & dyn db:: ExpandDatabase ) -> AstPtr < N > {
809
829
db. ast_id_map ( self . file_id ) . get ( self . value )
810
830
}
@@ -820,6 +840,7 @@ impl ErasedAstId {
820
840
db. ast_id_map ( self . file_id ) . get_raw ( self . value )
821
841
}
822
842
}
843
+
823
844
/// `InFile<T>` stores a value of `T` inside a particular file/syntax tree.
824
845
///
825
846
/// Typical usages are:
@@ -1038,6 +1059,18 @@ impl InFile<SyntaxToken> {
1038
1059
}
1039
1060
}
1040
1061
1062
+ #[ derive( Debug , PartialEq , Eq , Clone , Copy , Hash ) ]
1063
+ pub struct InMacroFile < T > {
1064
+ pub file_id : MacroFile ,
1065
+ pub value : T ,
1066
+ }
1067
+
1068
+ impl < T > From < InMacroFile < T > > for InFile < T > {
1069
+ fn from ( macro_file : InMacroFile < T > ) -> Self {
1070
+ InFile { file_id : macro_file. file_id . into ( ) , value : macro_file. value }
1071
+ }
1072
+ }
1073
+
1041
1074
fn ascend_node_border_tokens (
1042
1075
db : & dyn db:: ExpandDatabase ,
1043
1076
InFile { file_id, value : node } : InFile < & SyntaxNode > ,
0 commit comments