@@ -9,7 +9,7 @@ use base_db::{CrateId, Edition, FileId, ProcMacroId};
9
9
use cfg:: { CfgExpr , CfgOptions } ;
10
10
use hir_expand:: {
11
11
ast_id_map:: FileAstId ,
12
- builtin_attr_macro:: { find_builtin_attr, is_builtin_test_or_bench_attr } ,
12
+ builtin_attr_macro:: find_builtin_attr,
13
13
builtin_derive_macro:: find_builtin_derive,
14
14
builtin_fn_macro:: find_builtin_macro,
15
15
name:: { name, AsName , Name } ,
@@ -781,7 +781,7 @@ impl DefCollector<'_> {
781
781
}
782
782
783
783
fn resolve_extern_crate ( & self , name : & Name ) -> PerNs {
784
- if name == & name ! ( self ) {
784
+ if * name == name ! ( self ) {
785
785
cov_mark:: hit!( extern_crate_self_as) ;
786
786
let root = match self . def_map . block {
787
787
Some ( _) => {
@@ -1105,7 +1105,7 @@ impl DefCollector<'_> {
1105
1105
let mod_dir = self . mod_dirs [ & directive. module_id ] . clone ( ) ;
1106
1106
self . skip_attrs . insert ( InFile :: new ( file_id, * mod_item) , attr. id ) ;
1107
1107
ModCollector {
1108
- def_collector : & mut * self ,
1108
+ def_collector : self ,
1109
1109
macro_depth : directive. depth ,
1110
1110
module_id : directive. module_id ,
1111
1111
tree_id : TreeId :: new ( file_id, None ) ,
@@ -1121,6 +1121,65 @@ impl DefCollector<'_> {
1121
1121
}
1122
1122
}
1123
1123
1124
+ let def = resolver ( ast_id. path . clone ( ) ) . filter ( MacroDefId :: is_attribute) ;
1125
+ if matches ! (
1126
+ def,
1127
+ Some ( MacroDefId { kind: MacroDefKind :: BuiltInAttr ( expander, _) , .. } )
1128
+ if expander. is_derive( )
1129
+ ) {
1130
+ // Resolved to derive
1131
+ let file_id = ast_id. ast_id . file_id ;
1132
+ let item_tree = self . db . file_item_tree ( file_id) ;
1133
+
1134
+ let ast_id: FileAstId < ast:: Item > = match * mod_item {
1135
+ ModItem :: Struct ( it) => item_tree[ it] . ast_id . upcast ( ) ,
1136
+ ModItem :: Union ( it) => item_tree[ it] . ast_id . upcast ( ) ,
1137
+ ModItem :: Enum ( it) => item_tree[ it] . ast_id . upcast ( ) ,
1138
+ _ => {
1139
+ // Cannot use derive on this item.
1140
+ // FIXME: diagnose
1141
+ res = ReachedFixedPoint :: No ;
1142
+ return false ;
1143
+ }
1144
+ } ;
1145
+
1146
+ match attr. parse_derive ( ) {
1147
+ Some ( derive_macros) => {
1148
+ for path in derive_macros {
1149
+ let ast_id = AstIdWithPath :: new ( file_id, ast_id, path) ;
1150
+ self . unresolved_macros . push ( MacroDirective {
1151
+ module_id : directive. module_id ,
1152
+ depth : directive. depth + 1 ,
1153
+ kind : MacroDirectiveKind :: Derive {
1154
+ ast_id,
1155
+ derive_attr : attr. id ,
1156
+ } ,
1157
+ } ) ;
1158
+ }
1159
+ }
1160
+ None => {
1161
+ // FIXME: diagnose
1162
+ tracing:: debug!( "malformed derive: {:?}" , attr) ;
1163
+ }
1164
+ }
1165
+
1166
+ let mod_dir = self . mod_dirs [ & directive. module_id ] . clone ( ) ;
1167
+ self . skip_attrs . insert ( InFile :: new ( file_id, * mod_item) , attr. id ) ;
1168
+ ModCollector {
1169
+ def_collector : & mut * self ,
1170
+ macro_depth : directive. depth ,
1171
+ module_id : directive. module_id ,
1172
+ tree_id : TreeId :: new ( file_id, None ) ,
1173
+ item_tree : & item_tree,
1174
+ mod_dir,
1175
+ }
1176
+ . collect ( & [ * mod_item] ) ;
1177
+
1178
+ // Remove the original directive since we resolved it.
1179
+ res = ReachedFixedPoint :: No ;
1180
+ return false ;
1181
+ }
1182
+
1124
1183
if !self . db . enable_proc_attr_macros ( ) {
1125
1184
return true ;
1126
1185
}
@@ -1138,7 +1197,11 @@ impl DefCollector<'_> {
1138
1197
1139
1198
// Skip #[test]/#[bench] expansion, which would merely result in more memory usage
1140
1199
// due to duplicating functions into macro expansions
1141
- if is_builtin_test_or_bench_attr ( loc. def ) {
1200
+ if matches ! (
1201
+ loc. def. kind,
1202
+ MacroDefKind :: BuiltInAttr ( expander, _)
1203
+ if expander. is_test( ) || expander. is_bench( )
1204
+ ) {
1142
1205
let file_id = ast_id. ast_id . file_id ;
1143
1206
let item_tree = self . db . file_item_tree ( file_id) ;
1144
1207
let mod_dir = self . mod_dirs [ & directive. module_id ] . clone ( ) ;
@@ -1281,7 +1344,7 @@ impl DefCollector<'_> {
1281
1344
for directive in & self . unresolved_macros {
1282
1345
match & directive. kind {
1283
1346
MacroDirectiveKind :: FnLike { ast_id, expand_to } => {
1284
- match macro_call_as_call_id (
1347
+ let macro_call_as_call_id = macro_call_as_call_id (
1285
1348
ast_id,
1286
1349
* expand_to,
1287
1350
self . db ,
@@ -1297,15 +1360,13 @@ impl DefCollector<'_> {
1297
1360
resolved_res. resolved_def . take_macros ( )
1298
1361
} ,
1299
1362
& mut |_| ( ) ,
1300
- ) {
1301
- Ok ( _) => ( ) ,
1302
- Err ( UnresolvedMacro { path } ) => {
1303
- self . def_map . diagnostics . push ( DefDiagnostic :: unresolved_macro_call (
1304
- directive. module_id ,
1305
- ast_id. ast_id ,
1306
- path,
1307
- ) ) ;
1308
- }
1363
+ ) ;
1364
+ if let Err ( UnresolvedMacro { path } ) = macro_call_as_call_id {
1365
+ self . def_map . diagnostics . push ( DefDiagnostic :: unresolved_macro_call (
1366
+ directive. module_id ,
1367
+ ast_id. ast_id ,
1368
+ path,
1369
+ ) ) ;
1309
1370
}
1310
1371
}
1311
1372
MacroDirectiveKind :: Derive { .. } | MacroDirectiveKind :: Attr { .. } => {
@@ -1747,26 +1808,23 @@ impl ModCollector<'_, '_> {
1747
1808
} ) ;
1748
1809
1749
1810
for attr in iter {
1750
- if attr. path . as_ident ( ) == Some ( & hir_expand:: name![ derive] ) {
1751
- self . collect_derive ( attr, mod_item) ;
1752
- } else if self . is_builtin_or_registered_attr ( & attr. path ) {
1811
+ if self . is_builtin_or_registered_attr ( & attr. path ) {
1753
1812
continue ;
1754
- } else {
1755
- tracing:: debug!( "non-builtin attribute {}" , attr. path) ;
1813
+ }
1814
+ tracing:: debug!( "non-builtin attribute {}" , attr. path) ;
1756
1815
1757
- let ast_id = AstIdWithPath :: new (
1758
- self . file_id ( ) ,
1759
- mod_item. ast_id ( self . item_tree ) ,
1760
- attr. path . as_ref ( ) . clone ( ) ,
1761
- ) ;
1762
- self . def_collector . unresolved_macros . push ( MacroDirective {
1763
- module_id : self . module_id ,
1764
- depth : self . macro_depth + 1 ,
1765
- kind : MacroDirectiveKind :: Attr { ast_id, attr : attr. clone ( ) , mod_item } ,
1766
- } ) ;
1816
+ let ast_id = AstIdWithPath :: new (
1817
+ self . file_id ( ) ,
1818
+ mod_item. ast_id ( self . item_tree ) ,
1819
+ attr. path . as_ref ( ) . clone ( ) ,
1820
+ ) ;
1821
+ self . def_collector . unresolved_macros . push ( MacroDirective {
1822
+ module_id : self . module_id ,
1823
+ depth : self . macro_depth + 1 ,
1824
+ kind : MacroDirectiveKind :: Attr { ast_id, attr : attr. clone ( ) , mod_item } ,
1825
+ } ) ;
1767
1826
1768
- return Err ( ( ) ) ;
1769
- }
1827
+ return Err ( ( ) ) ;
1770
1828
}
1771
1829
1772
1830
Ok ( ( ) )
@@ -1800,36 +1858,6 @@ impl ModCollector<'_, '_> {
1800
1858
false
1801
1859
}
1802
1860
1803
- fn collect_derive ( & mut self , attr : & Attr , mod_item : ModItem ) {
1804
- let ast_id: FileAstId < ast:: Item > = match mod_item {
1805
- ModItem :: Struct ( it) => self . item_tree [ it] . ast_id . upcast ( ) ,
1806
- ModItem :: Union ( it) => self . item_tree [ it] . ast_id . upcast ( ) ,
1807
- ModItem :: Enum ( it) => self . item_tree [ it] . ast_id . upcast ( ) ,
1808
- _ => {
1809
- // Cannot use derive on this item.
1810
- // FIXME: diagnose
1811
- return ;
1812
- }
1813
- } ;
1814
-
1815
- match attr. parse_derive ( ) {
1816
- Some ( derive_macros) => {
1817
- for path in derive_macros {
1818
- let ast_id = AstIdWithPath :: new ( self . file_id ( ) , ast_id, path) ;
1819
- self . def_collector . unresolved_macros . push ( MacroDirective {
1820
- module_id : self . module_id ,
1821
- depth : self . macro_depth + 1 ,
1822
- kind : MacroDirectiveKind :: Derive { ast_id, derive_attr : attr. id } ,
1823
- } ) ;
1824
- }
1825
- }
1826
- None => {
1827
- // FIXME: diagnose
1828
- tracing:: debug!( "malformed derive: {:?}" , attr) ;
1829
- }
1830
- }
1831
- }
1832
-
1833
1861
/// If `attrs` registers a procedural macro, collects its definition.
1834
1862
fn collect_proc_macro_def ( & mut self , func_name : & Name , ast_id : AstId < ast:: Fn > , attrs : & Attrs ) {
1835
1863
// FIXME: this should only be done in the root module of `proc-macro` crates, not everywhere
0 commit comments