@@ -532,41 +532,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
532
532
parent_scope. module . legacy_macro_resolutions . borrow_mut ( )
533
533
. push ( ( path[ 0 ] , kind, parent_scope. clone ( ) , result. ok ( ) ) ) ;
534
534
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
570
536
}
571
537
572
538
// Resolve the initial segment of a non-global macro path
@@ -607,6 +573,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
607
573
// 2b. Standard library prelude is currently implemented as `macro-use` (closed, controlled)
608
574
// 3. Language prelude: builtin macros (closed, controlled, except for legacy plugins).
609
575
// 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.
610
583
611
584
assert ! ( ns == TypeNS || ns == MacroNS ) ;
612
585
assert ! ( force || !record_used) ; // `record_used` implies `force`
@@ -630,6 +603,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
630
603
MacroUsePrelude ,
631
604
BuiltinMacros ,
632
605
BuiltinAttrs ,
606
+ DeriveHelpers ,
633
607
ExternPrelude ,
634
608
ToolPrelude ,
635
609
StdLibPrelude ,
@@ -679,6 +653,26 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
679
653
Err ( Determinacy :: Determined )
680
654
}
681
655
}
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
+ }
682
676
WhereToResolve :: ExternPrelude => {
683
677
if use_prelude && self . extern_prelude . contains ( & ident. name ) {
684
678
if !self . session . features_untracked ( ) . extern_prelude &&
@@ -758,7 +752,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
758
752
}
759
753
WhereToResolve :: MacroUsePrelude => WhereToResolve :: BuiltinMacros ,
760
754
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
762
757
WhereToResolve :: ExternPrelude => WhereToResolve :: ToolPrelude ,
763
758
WhereToResolve :: ToolPrelude => WhereToResolve :: StdLibPrelude ,
764
759
WhereToResolve :: StdLibPrelude => WhereToResolve :: BuiltinTypes ,
@@ -780,9 +775,12 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
780
775
781
776
if let Some ( innermost_result) = innermost_result {
782
777
// 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 &&
784
780
( 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 ) ) {
786
784
self . ambiguity_errors . push ( AmbiguityError {
787
785
ident,
788
786
b1 : innermost_result. 0 ,
0 commit comments