@@ -532,41 +532,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
532532 parent_scope. module . legacy_macro_resolutions . borrow_mut ( )
533533 . push ( ( path[ 0 ] , kind, parent_scope. clone ( ) , result. ok ( ) ) ) ;
534534
535- if let Ok ( Def :: NonMacroAttr ( NonMacroAttrKind :: Custom ) ) = result { } else {
536- return result;
537- }
538-
539- // At this point we've found that the `attr` is determinately unresolved and thus can be
540- // interpreted as a custom attribute. Normally custom attributes are feature gated, but
541- // it may be a custom attribute whitelisted by a derive macro and they do not require
542- // a feature gate.
543- //
544- // So here we look through all of the derive annotations in scope and try to resolve them.
545- // If they themselves successfully resolve *and* one of the resolved derive macros
546- // whitelists this attribute's name, then this is a registered attribute and we can convert
547- // it from a "generic custom attrite" into a "known derive helper attribute".
548- assert ! ( kind == MacroKind :: Attr ) ;
549- enum ConvertToDeriveHelper { Yes , No , DontKnow }
550- let mut convert_to_derive_helper = ConvertToDeriveHelper :: No ;
551- for derive in & parent_scope. derives {
552- match self . resolve_macro_to_def ( derive, MacroKind :: Derive , parent_scope, force) {
553- Ok ( ( _, ext) ) => if let SyntaxExtension :: ProcMacroDerive ( _, inert_attrs, _) = & * ext {
554- if inert_attrs. contains ( & path[ 0 ] . name ) {
555- convert_to_derive_helper = ConvertToDeriveHelper :: Yes ;
556- break
557- }
558- } ,
559- Err ( Determinacy :: Undetermined ) =>
560- convert_to_derive_helper = ConvertToDeriveHelper :: DontKnow ,
561- Err ( Determinacy :: Determined ) => { }
562- }
563- }
564-
565- match convert_to_derive_helper {
566- ConvertToDeriveHelper :: Yes => Ok ( Def :: NonMacroAttr ( NonMacroAttrKind :: DeriveHelper ) ) ,
567- ConvertToDeriveHelper :: No => result,
568- ConvertToDeriveHelper :: DontKnow => Err ( Determinacy :: determined ( force) ) ,
569- }
535+ result
570536 }
571537
572538 // Resolve the initial segment of a non-global macro path
@@ -607,6 +573,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
607573 // 2b. Standard library prelude is currently implemented as `macro-use` (closed, controlled)
608574 // 3. Language prelude: builtin macros (closed, controlled, except for legacy plugins).
609575 // 4. Language prelude: builtin attributes (closed, controlled).
576+ // N (unordered). Derive helpers (open, not controlled). All ambiguities with other names
577+ // are currently reported as errors. They should be higher in priority than preludes
578+ // and maybe even names in modules according to the "general principles" above. They
579+ // also should be subject to restricted shadowing because are effectively produced by
580+ // derives (you need to resolve the derive first to add helpers into scope), but they
581+ // should be available before the derive is expanded for compatibility.
582+ // It's mess in general, so we are being conservative for now.
610583
611584 assert ! ( ns == TypeNS || ns == MacroNS ) ;
612585 assert ! ( force || !record_used) ; // `record_used` implies `force`
@@ -630,6 +603,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
630603 MacroUsePrelude ,
631604 BuiltinMacros ,
632605 BuiltinAttrs ,
606+ DeriveHelpers ,
633607 ExternPrelude ,
634608 ToolPrelude ,
635609 StdLibPrelude ,
@@ -679,6 +653,26 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
679653 Err ( Determinacy :: Determined )
680654 }
681655 }
656+ WhereToResolve :: DeriveHelpers => {
657+ let mut result = Err ( Determinacy :: Determined ) ;
658+ for derive in & parent_scope. derives {
659+ let parent_scope = ParentScope { derives : Vec :: new ( ) , ..* parent_scope } ;
660+ if let Ok ( ( _, ext) ) = self . resolve_macro_to_def ( derive, MacroKind :: Derive ,
661+ & parent_scope, force) {
662+ if let SyntaxExtension :: ProcMacroDerive ( _, helper_attrs, _) = & * ext {
663+ if helper_attrs. contains ( & ident. name ) {
664+ let binding =
665+ ( Def :: NonMacroAttr ( NonMacroAttrKind :: DeriveHelper ) ,
666+ ty:: Visibility :: Public , derive. span , Mark :: root ( ) )
667+ . to_name_binding ( self . arenas ) ;
668+ result = Ok ( ( binding, FromPrelude ( false ) ) ) ;
669+ break ;
670+ }
671+ }
672+ }
673+ }
674+ result
675+ }
682676 WhereToResolve :: ExternPrelude => {
683677 if use_prelude && self . extern_prelude . contains ( & ident. name ) {
684678 if !self . session . features_untracked ( ) . extern_prelude &&
@@ -758,7 +752,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
758752 }
759753 WhereToResolve :: MacroUsePrelude => WhereToResolve :: BuiltinMacros ,
760754 WhereToResolve :: BuiltinMacros => WhereToResolve :: BuiltinAttrs ,
761- WhereToResolve :: BuiltinAttrs => break , // nowhere else to search
755+ WhereToResolve :: BuiltinAttrs => WhereToResolve :: DeriveHelpers ,
756+ WhereToResolve :: DeriveHelpers => break , // nowhere else to search
762757 WhereToResolve :: ExternPrelude => WhereToResolve :: ToolPrelude ,
763758 WhereToResolve :: ToolPrelude => WhereToResolve :: StdLibPrelude ,
764759 WhereToResolve :: StdLibPrelude => WhereToResolve :: BuiltinTypes ,
@@ -780,9 +775,12 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
780775
781776 if let Some ( innermost_result) = innermost_result {
782777 // Found another solution, if the first one was "weak", report an error.
783- if result. 0 . def ( ) != innermost_result. 0 . def ( ) &&
778+ let ( def, innermost_def) = ( result. 0 . def ( ) , innermost_result. 0 . def ( ) ) ;
779+ if def != innermost_def &&
784780 ( innermost_result. 0 . is_glob_import ( ) ||
785- innermost_result. 0 . may_appear_after ( parent_scope. expansion , result. 0 ) ) {
781+ innermost_result. 0 . may_appear_after ( parent_scope. expansion , result. 0 ) ||
782+ innermost_def == Def :: NonMacroAttr ( NonMacroAttrKind :: DeriveHelper ) ||
783+ def == Def :: NonMacroAttr ( NonMacroAttrKind :: DeriveHelper ) ) {
786784 self . ambiguity_errors . push ( AmbiguityError {
787785 ident,
788786 b1 : innermost_result. 0 ,
0 commit comments