@@ -18,7 +18,7 @@ use hir_expand::{
1818 ExpandTo , HirFileId , InFile , MacroCallId , MacroCallKind , MacroCallLoc , MacroDefId ,
1919 MacroDefKind ,
2020} ;
21- use itertools:: Itertools ;
21+ use itertools:: { izip , Itertools } ;
2222use la_arena:: Idx ;
2323use limit:: Limit ;
2424use rustc_hash:: { FxHashMap , FxHashSet } ;
@@ -110,7 +110,6 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T
110110 proc_macros,
111111 from_glob_import : Default :: default ( ) ,
112112 skip_attrs : Default :: default ( ) ,
113- derive_helpers_in_scope : Default :: default ( ) ,
114113 is_proc_macro,
115114 } ;
116115 if tree_id. is_block ( ) {
@@ -258,9 +257,6 @@ struct DefCollector<'a> {
258257 /// This also stores the attributes to skip when we resolve derive helpers and non-macro
259258 /// non-builtin attributes in general.
260259 skip_attrs : FxHashMap < InFile < ModItem > , AttrId > ,
261- /// Tracks which custom derives are in scope for an item, to allow resolution of derive helper
262- /// attributes.
263- derive_helpers_in_scope : FxHashMap < AstId < ast:: Item > , Vec < Name > > ,
264260}
265261
266262impl DefCollector < ' _ > {
@@ -1059,16 +1055,20 @@ impl DefCollector<'_> {
10591055 } ;
10601056 let mut res = ReachedFixedPoint :: Yes ;
10611057 macros. retain ( |directive| {
1062- let resolver = |path| {
1058+ let resolver2 = |path| {
10631059 let resolved_res = self . def_map . resolve_path_fp_with_macro (
10641060 self . db ,
10651061 ResolveMode :: Other ,
10661062 directive. module_id ,
10671063 & path,
10681064 BuiltinShadowMode :: Module ,
10691065 ) ;
1070- resolved_res. resolved_def . take_macros ( ) . map ( |it| macro_id_to_def_id ( self . db , it) )
1066+ resolved_res
1067+ . resolved_def
1068+ . take_macros ( )
1069+ . map ( |it| ( it, macro_id_to_def_id ( self . db , it) ) )
10711070 } ;
1071+ let resolver = |path| resolver2 ( path) . map ( |( _, it) | it) ;
10721072
10731073 match & directive. kind {
10741074 MacroDirectiveKind :: FnLike { ast_id, expand_to } => {
@@ -1087,21 +1087,37 @@ impl DefCollector<'_> {
10871087 }
10881088 }
10891089 MacroDirectiveKind :: Derive { ast_id, derive_attr, derive_pos } => {
1090- let call_id = derive_macro_as_call_id (
1090+ let id = derive_macro_as_call_id (
10911091 self . db ,
10921092 ast_id,
10931093 * derive_attr,
10941094 * derive_pos as u32 ,
10951095 self . def_map . krate ,
1096- & resolver ,
1096+ & resolver2 ,
10971097 ) ;
1098- if let Ok ( call_id) = call_id {
1098+
1099+ if let Ok ( ( macro_id, def_id, call_id) ) = id {
10991100 self . def_map . modules [ directive. module_id ] . scope . set_derive_macro_invoc (
11001101 ast_id. ast_id ,
11011102 call_id,
11021103 * derive_attr,
11031104 * derive_pos,
11041105 ) ;
1106+ // Record its helper attributes.
1107+ if def_id. krate != self . def_map . krate {
1108+ let def_map = self . db . crate_def_map ( def_id. krate ) ;
1109+ if let Some ( helpers) = def_map. exported_derives . get ( & def_id) {
1110+ self . def_map
1111+ . derive_helpers_in_scope
1112+ . entry ( ast_id. ast_id . map ( |it| it. upcast ( ) ) )
1113+ . or_default ( )
1114+ . extend ( izip ! (
1115+ helpers. iter( ) . cloned( ) ,
1116+ iter:: repeat( macro_id) ,
1117+ iter:: repeat( call_id) ,
1118+ ) ) ;
1119+ }
1120+ }
11051121
11061122 push_resolved ( directive, call_id) ;
11071123 res = ReachedFixedPoint :: No ;
@@ -1132,8 +1148,8 @@ impl DefCollector<'_> {
11321148 } ;
11331149
11341150 if let Some ( ident) = path. as_ident ( ) {
1135- if let Some ( helpers) = self . derive_helpers_in_scope . get ( & ast_id) {
1136- if helpers. contains ( ident) {
1151+ if let Some ( helpers) = self . def_map . derive_helpers_in_scope . get ( & ast_id) {
1152+ if helpers. iter ( ) . any ( | ( it , .. ) | it == ident) {
11371153 cov_mark:: hit!( resolved_derive_helper) ;
11381154 // Resolved to derive helper. Collect the item's attributes again,
11391155 // starting after the derive helper.
@@ -1148,7 +1164,7 @@ impl DefCollector<'_> {
11481164 } ;
11491165 if matches ! (
11501166 def,
1151- MacroDefId { kind: MacroDefKind :: BuiltInAttr ( expander, _) , .. }
1167+ MacroDefId { kind: MacroDefKind :: BuiltInAttr ( expander, _) , .. }
11521168 if expander. is_derive( )
11531169 ) {
11541170 // Resolved to `#[derive]`
@@ -1317,19 +1333,6 @@ impl DefCollector<'_> {
13171333 self . def_map . diagnostics . push ( diag) ;
13181334 }
13191335
1320- // If we've just resolved a derive, record its helper attributes.
1321- if let MacroCallKind :: Derive { ast_id, .. } = & loc. kind {
1322- if loc. def . krate != self . def_map . krate {
1323- let def_map = self . db . crate_def_map ( loc. def . krate ) ;
1324- if let Some ( helpers) = def_map. exported_derives . get ( & loc. def ) {
1325- self . derive_helpers_in_scope
1326- . entry ( ast_id. map ( |it| it. upcast ( ) ) )
1327- . or_default ( )
1328- . extend ( helpers. iter ( ) . cloned ( ) ) ;
1329- }
1330- }
1331- }
1332-
13331336 // Then, fetch and process the item tree. This will reuse the expansion result from above.
13341337 let item_tree = self . db . file_item_tree ( file_id) ;
13351338 let mod_dir = self . mod_dirs [ & module_id] . clone ( ) ;
@@ -2140,7 +2143,6 @@ mod tests {
21402143 proc_macros : Default :: default ( ) ,
21412144 from_glob_import : Default :: default ( ) ,
21422145 skip_attrs : Default :: default ( ) ,
2143- derive_helpers_in_scope : Default :: default ( ) ,
21442146 is_proc_macro : false ,
21452147 } ;
21462148 collector. seed_with_top_level ( ) ;
0 commit comments