@@ -59,7 +59,7 @@ mod tests;
5959
6060use std:: { cmp:: Ord , ops:: Deref } ;
6161
62- use base_db:: { CrateId , Edition , FileId } ;
62+ use base_db:: { CrateId , Edition , FileId , ProcMacroKind } ;
6363use hir_expand:: { name:: Name , InFile , MacroCallId , MacroDefId } ;
6464use itertools:: Itertools ;
6565use la_arena:: Arena ;
@@ -77,7 +77,8 @@ use crate::{
7777 path:: ModPath ,
7878 per_ns:: PerNs ,
7979 visibility:: Visibility ,
80- AstId , BlockId , BlockLoc , FunctionId , LocalModuleId , MacroId , ModuleId , ProcMacroId ,
80+ AstId , BlockId , BlockLoc , FunctionId , LocalModuleId , Lookup , MacroExpander , MacroId , ModuleId ,
81+ ProcMacroId ,
8182} ;
8283
8384/// Contains the results of (early) name resolution.
@@ -380,9 +381,16 @@ impl DefMap {
380381 original_module : LocalModuleId ,
381382 path : & ModPath ,
382383 shadow : BuiltinShadowMode ,
384+ expected_macro_subns : Option < MacroSubNs > ,
383385 ) -> ( 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+ ) ;
386394 ( res. resolved_def , res. segment_index )
387395 }
388396
@@ -399,6 +407,7 @@ impl DefMap {
399407 original_module,
400408 path,
401409 shadow,
410+ None , // Currently this function isn't used for macro resolution.
402411 ) ;
403412 ( res. resolved_def , res. segment_index )
404413 }
@@ -568,3 +577,48 @@ pub enum ModuleSource {
568577 Module ( ast:: Module ) ,
569578 BlockExpr ( ast:: BlockExpr ) ,
570579}
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