@@ -118,11 +118,21 @@ pub struct ProcMacError {
118118 warn_msg : & ' static str ,
119119}
120120
121- // For compatibility bang macros are skipped when resolving potentially built-in attributes.
122- fn macro_kind_mismatch ( name : Name , requirement : Option < MacroKind > , candidate : Option < MacroKind > )
123- -> bool {
124- requirement == Some ( MacroKind :: Attr ) && candidate == Some ( MacroKind :: Bang ) &&
125- ( name == "test" || name == "bench" || is_builtin_attr_name ( name) )
121+ // Macro namespace is separated into two sub-namespaces, one for bang macros and
122+ // one for attribute-like macros (attributes, derives).
123+ // We ignore resolutions from one sub-namespace when searching names in scope for another.
124+ fn sub_namespace_mismatch ( requirement : Option < MacroKind > , candidate : Option < MacroKind > ) -> bool {
125+ #[ derive( PartialEq ) ]
126+ enum SubNS { Bang , AttrLike }
127+ let sub_ns = |kind| match kind {
128+ MacroKind :: Bang => Some ( SubNS :: Bang ) ,
129+ MacroKind :: Attr | MacroKind :: Derive => Some ( SubNS :: AttrLike ) ,
130+ MacroKind :: ProcMacroStub => None ,
131+ } ;
132+ let requirement = requirement. and_then ( |kind| sub_ns ( kind) ) ;
133+ let candidate = candidate. and_then ( |kind| sub_ns ( kind) ) ;
134+ // "No specific sub-namespace" means "matches anything" for both requirements and candidates.
135+ candidate. is_some ( ) && requirement. is_some ( ) && candidate != requirement
126136}
127137
128138impl < ' a , ' crateloader : ' a > base:: Resolver for Resolver < ' a , ' crateloader > {
@@ -641,10 +651,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
641651 }
642652 }
643653 WhereToResolve :: BuiltinAttrs => {
644- // FIXME: Only built-in attributes are not considered as candidates for
645- // non-attributes to fight off regressions on stable channel (#53205).
646- // We need to come up with some more principled approach instead.
647- if kind == Some ( MacroKind :: Attr ) && is_builtin_attr_name ( ident. name ) {
654+ if is_builtin_attr_name ( ident. name ) {
648655 let binding = ( Def :: NonMacroAttr ( NonMacroAttrKind :: Builtin ) ,
649656 ty:: Visibility :: Public , ident. span , Mark :: root ( ) )
650657 . to_name_binding ( self . arenas ) ;
@@ -765,7 +772,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
765772
766773 match result {
767774 Ok ( result) => {
768- if macro_kind_mismatch ( ident . name , kind, result. 0 . macro_kind ( ) ) {
775+ if sub_namespace_mismatch ( kind, result. 0 . macro_kind ( ) ) {
769776 continue_search ! ( ) ;
770777 }
771778
@@ -829,7 +836,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
829836 parent_scope : & ParentScope < ' a > ,
830837 record_used : bool ,
831838 ) -> Option < & ' a NameBinding < ' a > > {
832- if macro_kind_mismatch ( ident . name , kind, Some ( MacroKind :: Bang ) ) {
839+ if sub_namespace_mismatch ( kind, Some ( MacroKind :: Bang ) ) {
833840 return None ;
834841 }
835842
0 commit comments