@@ -321,10 +321,18 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
321
321
322
322
fn resolve_invoc ( & mut self , invoc : & Invocation , scope : Mark , force : bool )
323
323
-> Result < Option < Lrc < SyntaxExtension > > , Determinacy > {
324
- let def = match invoc. kind {
325
- InvocationKind :: Attr { attr : None , .. } => return Ok ( None ) ,
326
- _ => self . resolve_invoc_to_def ( invoc, scope, force) ?,
324
+ let ( path, macro_kind, derives_in_scope) = match invoc. kind {
325
+ InvocationKind :: Attr { attr : None , .. } =>
326
+ return Ok ( None ) ,
327
+ InvocationKind :: Attr { attr : Some ( ref attr) , ref traits, .. } =>
328
+ ( & attr. path , MacroKind :: Attr , & traits[ ..] ) ,
329
+ InvocationKind :: Bang { ref mac, .. } =>
330
+ ( & mac. node . path , MacroKind :: Bang , & [ ] [ ..] ) ,
331
+ InvocationKind :: Derive { ref path, .. } =>
332
+ ( path, MacroKind :: Derive , & [ ] [ ..] ) ,
327
333
} ;
334
+ let def = self . resolve_macro_to_def ( scope, path, macro_kind, derives_in_scope, force) ?;
335
+
328
336
if let Def :: Macro ( _, MacroKind :: ProcMacroStub ) = def {
329
337
self . report_proc_macro_stub ( invoc. span ( ) ) ;
330
338
return Err ( Determinacy :: Determined ) ;
@@ -396,7 +404,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
396
404
397
405
fn resolve_macro ( & mut self , scope : Mark , path : & ast:: Path , kind : MacroKind , force : bool )
398
406
-> Result < Lrc < SyntaxExtension > , Determinacy > {
399
- self . resolve_macro_to_def ( scope, path, kind, force) . and_then ( |def| {
407
+ self . resolve_macro_to_def ( scope, path, kind, & [ ] , force) . and_then ( |def| {
400
408
if let Def :: Macro ( _, MacroKind :: ProcMacroStub ) = def {
401
409
self . report_proc_macro_stub ( path. span ) ;
402
410
return Err ( Determinacy :: Determined ) ;
@@ -437,60 +445,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
437
445
self . session . span_err ( span, & format ! ( "expected a macro, found {}" , def. kind_name( ) ) ) ;
438
446
}
439
447
440
- fn resolve_invoc_to_def ( & mut self , invoc : & Invocation , scope : Mark , force : bool )
448
+ fn resolve_macro_to_def ( & mut self , scope : Mark , path : & ast:: Path , kind : MacroKind ,
449
+ derives_in_scope : & [ ast:: Path ] , force : bool )
441
450
-> Result < Def , Determinacy > {
442
- let ( attr, traits) = match invoc. kind {
443
- InvocationKind :: Attr { ref attr, ref traits, .. } => ( attr, traits) ,
444
- InvocationKind :: Bang { ref mac, .. } => {
445
- return self . resolve_macro_to_def ( scope, & mac. node . path , MacroKind :: Bang , force) ;
446
- }
447
- InvocationKind :: Derive { ref path, .. } => {
448
- return self . resolve_macro_to_def ( scope, path, MacroKind :: Derive , force) ;
449
- }
450
- } ;
451
-
452
- let path = attr. as_ref ( ) . unwrap ( ) . path . clone ( ) ;
453
- let def = self . resolve_macro_to_def ( scope, & path, MacroKind :: Attr , force) ;
454
- if let Ok ( Def :: NonMacroAttr ( NonMacroAttrKind :: Custom ) ) = def { } else {
455
- return def;
456
- }
457
-
458
- // At this point we've found that the `attr` is determinately unresolved and thus can be
459
- // interpreted as a custom attribute. Normally custom attributes are feature gated, but
460
- // it may be a custom attribute whitelisted by a derive macro and they do not require
461
- // a feature gate.
462
- //
463
- // So here we look through all of the derive annotations in scope and try to resolve them.
464
- // If they themselves successfully resolve *and* one of the resolved derive macros
465
- // whitelists this attribute's name, then this is a registered attribute and we can convert
466
- // it from a "generic custom attrite" into a "known derive helper attribute".
467
- enum ConvertToDeriveHelper { Yes , No , DontKnow }
468
- let mut convert_to_derive_helper = ConvertToDeriveHelper :: No ;
469
- let attr_name = path. segments [ 0 ] . ident . name ;
470
- for path in traits {
471
- match self . resolve_macro ( scope, path, MacroKind :: Derive , force) {
472
- Ok ( ext) => if let SyntaxExtension :: ProcMacroDerive ( _, ref inert_attrs, _) = * ext {
473
- if inert_attrs. contains ( & attr_name) {
474
- convert_to_derive_helper = ConvertToDeriveHelper :: Yes ;
475
- break
476
- }
477
- } ,
478
- Err ( Determinacy :: Undetermined ) =>
479
- convert_to_derive_helper = ConvertToDeriveHelper :: DontKnow ,
480
- Err ( Determinacy :: Determined ) => { }
481
- }
482
- }
483
-
484
- match convert_to_derive_helper {
485
- ConvertToDeriveHelper :: Yes => Ok ( Def :: NonMacroAttr ( NonMacroAttrKind :: DeriveHelper ) ) ,
486
- ConvertToDeriveHelper :: No => def,
487
- ConvertToDeriveHelper :: DontKnow => Err ( Determinacy :: determined ( force) ) ,
488
- }
489
- }
490
-
491
- fn resolve_macro_to_def ( & mut self , scope : Mark , path : & ast:: Path , kind : MacroKind , force : bool )
492
- -> Result < Def , Determinacy > {
493
- let def = self . resolve_macro_to_def_inner ( scope, path, kind, force) ;
451
+ let def = self . resolve_macro_to_def_inner ( scope, path, kind, derives_in_scope, force) ;
494
452
if def != Err ( Determinacy :: Undetermined ) {
495
453
// Do not report duplicated errors on every undetermined resolution.
496
454
path. segments . iter ( ) . find ( |segment| segment. args . is_some ( ) ) . map ( |segment| {
@@ -514,9 +472,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
514
472
def
515
473
}
516
474
517
- pub fn resolve_macro_to_def_inner ( & mut self , scope : Mark , path : & ast:: Path ,
518
- kind : MacroKind , force : bool )
519
- -> Result < Def , Determinacy > {
475
+ pub fn resolve_macro_to_def_inner ( & mut self , scope : Mark , path : & ast:: Path , kind : MacroKind ,
476
+ derives_in_scope : & [ ast :: Path ] , force : bool )
477
+ -> Result < Def , Determinacy > {
520
478
let ast:: Path { ref segments, span } = * path;
521
479
let mut path: Vec < _ > = segments. iter ( ) . map ( |seg| seg. ident ) . collect ( ) ;
522
480
let invocation = self . invocations [ & scope] ;
@@ -575,7 +533,41 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
575
533
self . current_module . nearest_item_scope ( ) . legacy_macro_resolutions . borrow_mut ( )
576
534
. push ( ( scope, path[ 0 ] , kind, result. ok ( ) ) ) ;
577
535
578
- result
536
+ if let Ok ( Def :: NonMacroAttr ( NonMacroAttrKind :: Custom ) ) = result { } else {
537
+ return result;
538
+ }
539
+
540
+ // At this point we've found that the `attr` is determinately unresolved and thus can be
541
+ // interpreted as a custom attribute. Normally custom attributes are feature gated, but
542
+ // it may be a custom attribute whitelisted by a derive macro and they do not require
543
+ // a feature gate.
544
+ //
545
+ // So here we look through all of the derive annotations in scope and try to resolve them.
546
+ // If they themselves successfully resolve *and* one of the resolved derive macros
547
+ // whitelists this attribute's name, then this is a registered attribute and we can convert
548
+ // it from a "generic custom attrite" into a "known derive helper attribute".
549
+ assert ! ( kind == MacroKind :: Attr ) ;
550
+ enum ConvertToDeriveHelper { Yes , No , DontKnow }
551
+ let mut convert_to_derive_helper = ConvertToDeriveHelper :: No ;
552
+ for derive in derives_in_scope {
553
+ match self . resolve_macro ( scope, derive, MacroKind :: Derive , force) {
554
+ Ok ( ext) => if let SyntaxExtension :: ProcMacroDerive ( _, ref inert_attrs, _) = * ext {
555
+ if inert_attrs. contains ( & path[ 0 ] . name ) {
556
+ convert_to_derive_helper = ConvertToDeriveHelper :: Yes ;
557
+ break
558
+ }
559
+ } ,
560
+ Err ( Determinacy :: Undetermined ) =>
561
+ convert_to_derive_helper = ConvertToDeriveHelper :: DontKnow ,
562
+ Err ( Determinacy :: Determined ) => { }
563
+ }
564
+ }
565
+
566
+ match convert_to_derive_helper {
567
+ ConvertToDeriveHelper :: Yes => Ok ( Def :: NonMacroAttr ( NonMacroAttrKind :: DeriveHelper ) ) ,
568
+ ConvertToDeriveHelper :: No => result,
569
+ ConvertToDeriveHelper :: DontKnow => Err ( Determinacy :: determined ( force) ) ,
570
+ }
579
571
}
580
572
581
573
// Resolve the initial segment of a non-global macro path
0 commit comments