@@ -11,7 +11,7 @@ use either::Either;
11
11
use hir_expand:: {
12
12
ast_id_map:: FileAstId ,
13
13
attrs:: { Attr , AttrId } ,
14
- builtin_attr_macro:: find_builtin_attr,
14
+ builtin_attr_macro:: { find_builtin_attr, BuiltinAttrExpander } ,
15
15
builtin_derive_macro:: find_builtin_derive,
16
16
builtin_fn_macro:: find_builtin_macro,
17
17
name:: { name, AsName , Name } ,
@@ -98,9 +98,13 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI
98
98
} ;
99
99
(
100
100
name. as_name ( ) ,
101
- CustomProcMacroExpander :: new ( hir_expand:: proc_macro:: ProcMacroId (
102
- idx as u32 ,
103
- ) ) ,
101
+ if it. disabled {
102
+ CustomProcMacroExpander :: disabled ( )
103
+ } else {
104
+ CustomProcMacroExpander :: new ( hir_expand:: proc_macro:: ProcMacroId (
105
+ idx as u32 ,
106
+ ) )
107
+ } ,
104
108
)
105
109
} )
106
110
. collect ( ) )
@@ -604,9 +608,6 @@ impl DefCollector<'_> {
604
608
id : ItemTreeId < item_tree:: Function > ,
605
609
fn_id : FunctionId ,
606
610
) {
607
- if self . def_map . block . is_some ( ) {
608
- return ;
609
- }
610
611
let kind = def. kind . to_basedb_kind ( ) ;
611
612
let ( expander, kind) =
612
613
match self . proc_macros . as_ref ( ) . map ( |it| it. iter ( ) . find ( |( n, _) | n == & def. name ) ) {
@@ -1120,9 +1121,16 @@ impl DefCollector<'_> {
1120
1121
let mut push_resolved = |directive : & MacroDirective , call_id| {
1121
1122
resolved. push ( ( directive. module_id , directive. depth , directive. container , call_id) ) ;
1122
1123
} ;
1124
+
1125
+ #[ derive( PartialEq , Eq ) ]
1126
+ enum Resolved {
1127
+ Yes ,
1128
+ No ,
1129
+ }
1130
+
1123
1131
let mut res = ReachedFixedPoint :: Yes ;
1124
1132
// Retain unresolved macros after this round of resolution.
1125
- macros . retain ( |directive| {
1133
+ let mut retain = |directive : & MacroDirective | {
1126
1134
let subns = match & directive. kind {
1127
1135
MacroDirectiveKind :: FnLike { .. } => MacroSubNs :: Bang ,
1128
1136
MacroDirectiveKind :: Attr { .. } | MacroDirectiveKind :: Derive { .. } => {
@@ -1156,10 +1164,11 @@ impl DefCollector<'_> {
1156
1164
self . def_map . modules [ directive. module_id ]
1157
1165
. scope
1158
1166
. add_macro_invoc ( ast_id. ast_id , call_id) ;
1167
+
1159
1168
push_resolved ( directive, call_id) ;
1160
1169
1161
1170
res = ReachedFixedPoint :: No ;
1162
- return false ;
1171
+ return Resolved :: Yes ;
1163
1172
}
1164
1173
}
1165
1174
MacroDirectiveKind :: Derive { ast_id, derive_attr, derive_pos, call_site } => {
@@ -1198,7 +1207,7 @@ impl DefCollector<'_> {
1198
1207
1199
1208
push_resolved ( directive, call_id) ;
1200
1209
res = ReachedFixedPoint :: No ;
1201
- return false ;
1210
+ return Resolved :: Yes ;
1202
1211
}
1203
1212
}
1204
1213
MacroDirectiveKind :: Attr { ast_id : file_ast_id, mod_item, attr, tree } => {
@@ -1221,7 +1230,7 @@ impl DefCollector<'_> {
1221
1230
}
1222
1231
. collect ( & [ * mod_item] , directive. container ) ;
1223
1232
res = ReachedFixedPoint :: No ;
1224
- false
1233
+ Resolved :: Yes
1225
1234
} ;
1226
1235
1227
1236
if let Some ( ident) = path. as_ident ( ) {
@@ -1237,13 +1246,18 @@ impl DefCollector<'_> {
1237
1246
1238
1247
let def = match resolver_def_id ( path. clone ( ) ) {
1239
1248
Some ( def) if def. is_attribute ( ) => def,
1240
- _ => return true ,
1249
+ _ => return Resolved :: No ,
1241
1250
} ;
1242
- if matches ! (
1243
- def,
1244
- MacroDefId { kind: MacroDefKind :: BuiltInAttr ( expander, _) , .. }
1245
- if expander. is_derive( )
1246
- ) {
1251
+
1252
+ if let MacroDefId {
1253
+ kind :
1254
+ MacroDefKind :: BuiltInAttr (
1255
+ BuiltinAttrExpander :: Derive | BuiltinAttrExpander :: DeriveConst ,
1256
+ _,
1257
+ ) ,
1258
+ ..
1259
+ } = def
1260
+ {
1247
1261
// Resolved to `#[derive]`, we don't actually expand this attribute like
1248
1262
// normal (as that would just be an identity expansion with extra output)
1249
1263
// Instead we treat derive attributes special and apply them separately.
@@ -1316,16 +1330,6 @@ impl DefCollector<'_> {
1316
1330
let call_id =
1317
1331
attr_macro_as_call_id ( self . db , file_ast_id, attr, self . def_map . krate , def) ;
1318
1332
1319
- // If proc attribute macro expansion is disabled, skip expanding it here
1320
- if !self . db . expand_proc_attr_macros ( ) {
1321
- self . def_map . diagnostics . push ( DefDiagnostic :: unresolved_proc_macro (
1322
- directive. module_id ,
1323
- self . db . lookup_intern_macro_call ( call_id) . kind ,
1324
- def. krate ,
1325
- ) ) ;
1326
- return recollect_without ( self ) ;
1327
- }
1328
-
1329
1333
// Skip #[test]/#[bench] expansion, which would merely result in more memory usage
1330
1334
// due to duplicating functions into macro expansions
1331
1335
if matches ! (
@@ -1337,17 +1341,29 @@ impl DefCollector<'_> {
1337
1341
}
1338
1342
1339
1343
if let MacroDefKind :: ProcMacro ( exp, ..) = def. kind {
1340
- if exp. is_dummy ( ) {
1341
- // If there's no expander for the proc macro (e.g.
1342
- // because proc macros are disabled, or building the
1343
- // proc macro crate failed), report this and skip
1344
- // expansion like we would if it was disabled
1344
+ // If proc attribute macro expansion is disabled, skip expanding it here
1345
+ if !self . db . expand_proc_attr_macros ( ) {
1345
1346
self . def_map . diagnostics . push ( DefDiagnostic :: unresolved_proc_macro (
1346
1347
directive. module_id ,
1347
1348
self . db . lookup_intern_macro_call ( call_id) . kind ,
1348
1349
def. krate ,
1349
1350
) ) ;
1351
+ return recollect_without ( self ) ;
1352
+ }
1350
1353
1354
+ // If there's no expander for the proc macro (e.g.
1355
+ // because proc macros are disabled, or building the
1356
+ // proc macro crate failed), report this and skip
1357
+ // expansion like we would if it was disabled
1358
+ if exp. is_dummy ( ) {
1359
+ self . def_map . diagnostics . push ( DefDiagnostic :: unresolved_proc_macro (
1360
+ directive. module_id ,
1361
+ self . db . lookup_intern_macro_call ( call_id) . kind ,
1362
+ def. krate ,
1363
+ ) ) ;
1364
+ return recollect_without ( self ) ;
1365
+ }
1366
+ if exp. is_disabled ( ) {
1351
1367
return recollect_without ( self ) ;
1352
1368
}
1353
1369
}
@@ -1358,12 +1374,13 @@ impl DefCollector<'_> {
1358
1374
1359
1375
push_resolved ( directive, call_id) ;
1360
1376
res = ReachedFixedPoint :: No ;
1361
- return false ;
1377
+ return Resolved :: Yes ;
1362
1378
}
1363
1379
}
1364
1380
1365
- true
1366
- } ) ;
1381
+ Resolved :: No
1382
+ } ;
1383
+ macros. retain ( |it| retain ( it) == Resolved :: No ) ;
1367
1384
// Attribute resolution can add unresolved macro invocations, so concatenate the lists.
1368
1385
macros. extend ( mem:: take ( & mut self . unresolved_macros ) ) ;
1369
1386
self . unresolved_macros = macros;
@@ -1673,7 +1690,11 @@ impl ModCollector<'_, '_> {
1673
1690
FunctionLoc { container, id : ItemTreeId :: new ( self . tree_id , id) } . intern ( db) ;
1674
1691
1675
1692
let vis = resolve_vis ( def_map, & self . item_tree [ it. visibility ] ) ;
1676
- if self . def_collector . is_proc_macro && self . module_id == DefMap :: ROOT {
1693
+
1694
+ if self . def_collector . def_map . block . is_none ( )
1695
+ && self . def_collector . is_proc_macro
1696
+ && self . module_id == DefMap :: ROOT
1697
+ {
1677
1698
if let Some ( proc_macro) = attrs. parse_proc_macro_decl ( & it. name ) {
1678
1699
self . def_collector . export_proc_macro (
1679
1700
proc_macro,
0 commit comments