33//! `DefCollector::collect` contains the fixed-point iteration loop which
44//! resolves imports and expands macros.
55
6- use std:: { cmp :: Ordering , iter, mem, ops :: Not } ;
6+ use std:: { iter, mem} ;
77
8+ use crate :: attr:: Attrs ;
9+ use crate :: item_tree:: Fields ;
10+ use crate :: item_tree:: FileItemTreeId ;
11+ use crate :: item_tree:: MacroCall ;
12+ use crate :: item_tree:: MacroRules ;
13+ use crate :: item_tree:: Mod ;
14+ use crate :: item_tree:: ModKind ;
15+ use crate :: macro_call_as_call_id_with_eager;
16+
17+ use crate :: nameres:: mod_resolution:: ModDir ;
18+
19+ use crate :: item_tree:: ItemTree ;
820use base_db:: { CrateId , Dependency , FileId } ;
921use cfg:: { CfgExpr , CfgOptions } ;
22+
23+ use crate :: item_tree:: TreeId ;
24+
25+ use crate :: LocalModuleId ;
26+ use crate :: {
27+ item_tree:: { ExternCrate , ItemTreeId , Macro2 , ModItem } ,
28+ nameres:: {
29+ diagnostics:: DefDiagnostic , proc_macro:: parse_macro_name_and_helper_attrs,
30+ sub_namespace_match, BuiltinShadowMode , DefMap , MacroSubNs , ModuleData , ModuleOrigin ,
31+ ResolveMode ,
32+ } ,
33+ path:: ModPath ,
34+ per_ns:: PerNs ,
35+ tt,
36+ visibility:: Visibility ,
37+ AstId , AstIdWithPath , ConstLoc , EnumLoc , EnumVariantLoc , ExternBlockLoc , ExternCrateId ,
38+ ExternCrateLoc , FunctionLoc , ImplLoc , Intern , ItemContainerId , Macro2Loc , MacroExpander ,
39+ MacroRulesLoc , MacroRulesLocFlags , ModuleDefId , ModuleId , StaticLoc , StructLoc , TraitAliasLoc ,
40+ TraitLoc , TypeAliasLoc , UnionLoc , UseLoc ,
41+ } ;
42+
43+ use std:: { cmp:: Ordering , ops:: Not } ;
44+
1045use either:: Either ;
1146use hir_expand:: {
12- attrs:: { Attr , AttrId } ,
13- builtin_attr_macro:: { find_builtin_attr, BuiltinAttrExpander } ,
47+ builtin_attr_macro:: find_builtin_attr,
1448 builtin_derive_macro:: find_builtin_derive,
1549 builtin_fn_macro:: find_builtin_macro,
16- name:: { name, AsName , Name } ,
50+ name:: { AsName , Name } ,
51+ HirFileId , InFile ,
52+ } ;
53+
54+ use itertools:: Itertools ;
55+ use span:: { ErasedFileAstId , FileAstId , Span , SyntaxContextId } ;
56+
57+ use hir_expand:: {
58+ attrs:: { Attr , AttrId } ,
59+ builtin_attr_macro:: BuiltinAttrExpander ,
60+ name:: name,
1761 proc_macro:: CustomProcMacroExpander ,
18- ExpandResult , ExpandTo , HirFileId , InFile , MacroCallId , MacroCallKind , MacroCallLoc ,
19- MacroDefId , MacroDefKind ,
62+ ExpandResult , ExpandTo , MacroCallId , MacroCallKind , MacroCallLoc , MacroDefId , MacroDefKind ,
2063} ;
21- use itertools:: { izip, Itertools } ;
64+ use itertools:: izip;
2265use la_arena:: Idx ;
2366use limit:: Limit ;
2467use rustc_hash:: { FxHashMap , FxHashSet } ;
25- use span:: { Edition , ErasedFileAstId , FileAstId , Span , SyntaxContextId } ;
2668use stdx:: always;
2769use syntax:: { ast, SmolStr } ;
2870use triomphe:: Arc ;
2971
3072use crate :: {
31- attr:: Attrs ,
3273 db:: DefDatabase ,
3374 item_scope:: { ImportId , ImportOrExternCrate , ImportType , PerNsGlobImports } ,
34- item_tree:: {
35- self , ExternCrate , Fields , FileItemTreeId , ImportKind , ItemTree , ItemTreeId , ItemTreeNode ,
36- Macro2 , MacroCall , MacroRules , Mod , ModItem , ModKind , TreeId ,
37- } ,
38- macro_call_as_call_id, macro_call_as_call_id_with_eager,
75+ item_tree:: { self , ImportKind , ItemTreeNode } ,
76+ macro_call_as_call_id,
3977 nameres:: {
4078 attr_resolution:: { attr_macro_as_call_id, derive_macro_as_call_id} ,
41- diagnostics:: DefDiagnostic ,
42- mod_resolution:: ModDir ,
4379 path_resolution:: ReachedFixedPoint ,
44- proc_macro:: { parse_macro_name_and_helper_attrs, ProcMacroDef , ProcMacroKind } ,
45- sub_namespace_match, BuiltinShadowMode , DefMap , MacroSubNs , ModuleData , ModuleOrigin ,
46- ResolveMode ,
80+ proc_macro:: { ProcMacroDef , ProcMacroKind } ,
4781 } ,
48- path:: { ImportAlias , ModPath , PathKind } ,
49- per_ns:: PerNs ,
50- tt,
51- visibility:: { RawVisibility , Visibility } ,
52- AdtId , AstId , AstIdWithPath , ConstLoc , CrateRootModuleId , EnumLoc , EnumVariantLoc ,
53- ExternBlockLoc , ExternCrateId , ExternCrateLoc , FunctionId , FunctionLoc , ImplLoc , Intern ,
54- ItemContainerId , LocalModuleId , Lookup , Macro2Id , Macro2Loc , MacroExpander , MacroId ,
55- MacroRulesId , MacroRulesLoc , MacroRulesLocFlags , ModuleDefId , ModuleId , ProcMacroId ,
56- ProcMacroLoc , StaticLoc , StructLoc , TraitAliasLoc , TraitLoc , TypeAliasLoc , UnionLoc ,
57- UnresolvedMacro , UseId , UseLoc ,
82+ path:: { ImportAlias , PathKind } ,
83+ visibility:: RawVisibility ,
84+ AdtId , CrateRootModuleId , FunctionId , Lookup , Macro2Id , MacroId , MacroRulesId , ProcMacroId ,
85+ ProcMacroLoc , UnresolvedMacro , UseId ,
5886} ;
5987
6088static GLOB_RECURSION_LIMIT : Limit = Limit :: new ( 100 ) ;
@@ -237,6 +265,8 @@ enum MacroDirectiveKind {
237265 derive_attr : AttrId ,
238266 derive_pos : usize ,
239267 ctxt : SyntaxContextId ,
268+ /// The "parent" macro it is resolved to.
269+ derive_macro_id : MacroCallId ,
240270 } ,
241271 Attr {
242272 ast_id : AstIdWithPath < ast:: Item > ,
@@ -1146,7 +1176,13 @@ impl DefCollector<'_> {
11461176 return Resolved :: Yes ;
11471177 }
11481178 }
1149- MacroDirectiveKind :: Derive { ast_id, derive_attr, derive_pos, ctxt : call_site } => {
1179+ MacroDirectiveKind :: Derive {
1180+ ast_id,
1181+ derive_attr,
1182+ derive_pos,
1183+ ctxt : call_site,
1184+ derive_macro_id,
1185+ } => {
11501186 let id = derive_macro_as_call_id (
11511187 self . db ,
11521188 ast_id,
@@ -1155,6 +1191,7 @@ impl DefCollector<'_> {
11551191 * call_site,
11561192 self . def_map . krate ,
11571193 resolver,
1194+ * derive_macro_id,
11581195 ) ;
11591196
11601197 if let Ok ( ( macro_id, def_id, call_id) ) = id {
@@ -1223,7 +1260,9 @@ impl DefCollector<'_> {
12231260 Some ( def) if def. is_attribute ( ) => def,
12241261 _ => return Resolved :: No ,
12251262 } ;
1226-
1263+ // We will treat derive macros as an attribute as a reference for the input to derives
1264+ let call_id =
1265+ attr_macro_as_call_id ( self . db , file_ast_id, attr, self . def_map . krate , def) ;
12271266 if let MacroDefId {
12281267 kind :
12291268 MacroDefKind :: BuiltInAttr (
@@ -1267,6 +1306,7 @@ impl DefCollector<'_> {
12671306 derive_attr : attr. id ,
12681307 derive_pos : idx,
12691308 ctxt : call_site. ctx ,
1309+ derive_macro_id : call_id,
12701310 } ,
12711311 container : directive. container ,
12721312 } ) ;
@@ -1301,10 +1341,6 @@ impl DefCollector<'_> {
13011341 return recollect_without ( self ) ;
13021342 }
13031343
1304- // Not resolved to a derive helper or the derive attribute, so try to treat as a normal attribute.
1305- let call_id =
1306- attr_macro_as_call_id ( self . db , file_ast_id, attr, self . def_map . krate , def) ;
1307-
13081344 // Skip #[test]/#[bench] expansion, which would merely result in more memory usage
13091345 // due to duplicating functions into macro expansions
13101346 if matches ! (
@@ -1460,13 +1496,20 @@ impl DefCollector<'_> {
14601496 ) ) ;
14611497 }
14621498 }
1463- MacroDirectiveKind :: Derive { ast_id, derive_attr, derive_pos, ctxt : _ } => {
1499+ MacroDirectiveKind :: Derive {
1500+ ast_id,
1501+ derive_attr,
1502+ derive_pos,
1503+ derive_macro_id,
1504+ ..
1505+ } => {
14641506 self . def_map . diagnostics . push ( DefDiagnostic :: unresolved_macro_call (
14651507 directive. module_id ,
14661508 MacroCallKind :: Derive {
14671509 ast_id : ast_id. ast_id ,
14681510 derive_attr_index : * derive_attr,
14691511 derive_index : * derive_pos as u32 ,
1512+ derive_macro_id : * derive_macro_id,
14701513 } ,
14711514 ast_id. path . clone ( ) ,
14721515 ) ) ;
@@ -2289,7 +2332,7 @@ impl ModCollector<'_, '_> {
22892332
22902333 fn collect_macro_call (
22912334 & mut self ,
2292- & MacroCall { ref path, ast_id, expand_to, ctxt } : & MacroCall ,
2335+ & MacroCall { ref path, ast_id, expand_to, ctxt, .. } : & MacroCall ,
22932336 container : ItemContainerId ,
22942337 ) {
22952338 let ast_id = AstIdWithPath :: new ( self . file_id ( ) , ast_id, ModPath :: clone ( path) ) ;
@@ -2428,7 +2471,10 @@ mod tests {
24282471 use base_db:: SourceDatabase ;
24292472 use test_fixture:: WithFixture ;
24302473
2431- use crate :: { nameres:: DefMapCrateData , test_db:: TestDB } ;
2474+ use crate :: {
2475+ nameres:: { DefMapCrateData , ModuleData , ModuleOrigin } ,
2476+ test_db:: TestDB ,
2477+ } ;
24322478
24332479 use super :: * ;
24342480
0 commit comments