@@ -59,7 +59,7 @@ mod tests;
59
59
60
60
use std:: { cmp:: Ord , ops:: Deref } ;
61
61
62
- use base_db:: { CrateId , Edition , FileId } ;
62
+ use base_db:: { CrateId , Edition , FileId , ProcMacroKind } ;
63
63
use hir_expand:: { name:: Name , InFile , MacroCallId , MacroDefId } ;
64
64
use itertools:: Itertools ;
65
65
use la_arena:: Arena ;
@@ -77,7 +77,8 @@ use crate::{
77
77
path:: ModPath ,
78
78
per_ns:: PerNs ,
79
79
visibility:: Visibility ,
80
- AstId , BlockId , BlockLoc , FunctionId , LocalModuleId , MacroId , ModuleId , ProcMacroId ,
80
+ AstId , BlockId , BlockLoc , FunctionId , LocalModuleId , Lookup , MacroExpander , MacroId , ModuleId ,
81
+ ProcMacroId ,
81
82
} ;
82
83
83
84
/// Contains the results of (early) name resolution.
@@ -380,9 +381,16 @@ impl DefMap {
380
381
original_module : LocalModuleId ,
381
382
path : & ModPath ,
382
383
shadow : BuiltinShadowMode ,
384
+ expected_macro_subns : Option < MacroSubNs > ,
383
385
) -> ( PerNs , Option < usize > ) {
384
- let res =
385
- self . resolve_path_fp_with_macro ( db, ResolveMode :: Other , original_module, path, shadow) ;
386
+ let res = self . resolve_path_fp_with_macro (
387
+ db,
388
+ ResolveMode :: Other ,
389
+ original_module,
390
+ path,
391
+ shadow,
392
+ expected_macro_subns,
393
+ ) ;
386
394
( res. resolved_def , res. segment_index )
387
395
}
388
396
@@ -399,6 +407,7 @@ impl DefMap {
399
407
original_module,
400
408
path,
401
409
shadow,
410
+ None , // Currently this function isn't used for macro resolution.
402
411
) ;
403
412
( res. resolved_def , res. segment_index )
404
413
}
@@ -568,3 +577,48 @@ pub enum ModuleSource {
568
577
Module ( ast:: Module ) ,
569
578
BlockExpr ( ast:: BlockExpr ) ,
570
579
}
580
+
581
+ /// See `sub_namespace_match()`.
582
+ #[ derive( Clone , Copy , PartialEq , Eq ) ]
583
+ pub enum MacroSubNs {
584
+ /// Function-like macros, suffixed with `!`.
585
+ Bang ,
586
+ /// Macros inside attributes, i.e. attribute macros and derive macros.
587
+ Attr ,
588
+ }
589
+
590
+ impl MacroSubNs {
591
+ fn from_id ( db : & dyn DefDatabase , macro_id : MacroId ) -> Self {
592
+ let expander = match macro_id {
593
+ MacroId :: Macro2Id ( it) => it. lookup ( db) . expander ,
594
+ MacroId :: MacroRulesId ( it) => it. lookup ( db) . expander ,
595
+ MacroId :: ProcMacroId ( it) => {
596
+ return match it. lookup ( db) . kind {
597
+ ProcMacroKind :: CustomDerive | ProcMacroKind :: Attr => Self :: Attr ,
598
+ ProcMacroKind :: FuncLike => Self :: Bang ,
599
+ } ;
600
+ }
601
+ } ;
602
+
603
+ // Eager macros aren't *guaranteed* to be bang macros, but they *are* all bang macros currently.
604
+ match expander {
605
+ MacroExpander :: Declarative
606
+ | MacroExpander :: BuiltIn ( _)
607
+ | MacroExpander :: BuiltInEager ( _) => Self :: Bang ,
608
+ MacroExpander :: BuiltInAttr ( _) | MacroExpander :: BuiltInDerive ( _) => Self :: Attr ,
609
+ }
610
+ }
611
+ }
612
+
613
+ /// Quoted from [rustc]:
614
+ /// Macro namespace is separated into two sub-namespaces, one for bang macros and
615
+ /// one for attribute-like macros (attributes, derives).
616
+ /// We ignore resolutions from one sub-namespace when searching names in scope for another.
617
+ ///
618
+ /// [rustc]: https://github.com/rust-lang/rust/blob/1.69.0/compiler/rustc_resolve/src/macros.rs#L75
619
+ fn sub_namespace_match ( candidate : Option < MacroSubNs > , expected : Option < MacroSubNs > ) -> bool {
620
+ match ( candidate, expected) {
621
+ ( Some ( candidate) , Some ( expected) ) => candidate == expected,
622
+ _ => true ,
623
+ }
624
+ }
0 commit comments