@@ -136,8 +136,8 @@ expansions! {
136
136
}
137
137
138
138
impl ExpansionKind {
139
- fn dummy ( self , span : Span ) -> Expansion {
140
- self . make_from ( DummyResult :: any ( span) ) . unwrap ( )
139
+ fn dummy ( self , span : Span ) -> Option < Expansion > {
140
+ self . make_from ( DummyResult :: any ( span) )
141
141
}
142
142
143
143
fn expect_from_annotatables < I : IntoIterator < Item = Annotatable > > ( self , items : I ) -> Expansion {
@@ -304,21 +304,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
304
304
// FIXME(jseyfried): Refactor out the following logic
305
305
let ( expansion, new_invocations) = if let Some ( ext) = ext {
306
306
if let Some ( ext) = ext {
307
- let expansion = self . expand_invoc ( invoc, ext) ;
307
+ let dummy = invoc. expansion_kind . dummy ( invoc. span ( ) ) . unwrap ( ) ;
308
+ let expansion = self . expand_invoc ( invoc, ext) . unwrap_or ( dummy) ;
308
309
self . collect_invocations ( expansion, & [ ] )
309
310
} else if let InvocationKind :: Attr { attr : None , traits, item } = invoc. kind {
310
- let derive_allowed = match item {
311
- Annotatable :: Item ( ref item) => match item. node {
312
- ast:: ItemKind :: Struct ( ..) |
313
- ast:: ItemKind :: Enum ( ..) |
314
- ast:: ItemKind :: Union ( ..) => true ,
315
- _ => false ,
316
- } ,
317
- _ => false ,
318
- } ;
319
- if !derive_allowed {
320
- let attr = item. attrs ( ) . iter ( )
321
- . find ( |attr| attr. check_name ( "derive" ) )
311
+ if !item. derive_allowed ( ) {
312
+ let attr = attr:: find_by_name ( item. attrs ( ) , "derive" )
322
313
. expect ( "`derive` attribute should exist" ) ;
323
314
let span = attr. span ;
324
315
let mut err = self . cx . mut_span_err ( span,
@@ -366,7 +357,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
366
357
unreachable ! ( )
367
358
}
368
359
} else {
369
- self . collect_invocations ( invoc. expansion_kind . dummy ( invoc. span ( ) ) , & [ ] )
360
+ self . collect_invocations ( invoc. expansion_kind . dummy ( invoc. span ( ) ) . unwrap ( ) , & [ ] )
370
361
} ;
371
362
372
363
if expansions. len ( ) < depth {
@@ -446,11 +437,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
446
437
}
447
438
}
448
439
449
- fn expand_invoc ( & mut self , invoc : Invocation , ext : Rc < SyntaxExtension > ) -> Expansion {
440
+ fn expand_invoc ( & mut self , invoc : Invocation , ext : Rc < SyntaxExtension > ) -> Option < Expansion > {
450
441
let result = match invoc. kind {
451
- InvocationKind :: Bang { .. } => self . expand_bang_invoc ( invoc, ext) ,
452
- InvocationKind :: Attr { .. } => self . expand_attr_invoc ( invoc, ext) ,
453
- InvocationKind :: Derive { .. } => self . expand_derive_invoc ( invoc, ext) ,
442
+ InvocationKind :: Bang { .. } => self . expand_bang_invoc ( invoc, ext) ? ,
443
+ InvocationKind :: Attr { .. } => self . expand_attr_invoc ( invoc, ext) ? ,
444
+ InvocationKind :: Derive { .. } => self . expand_derive_invoc ( invoc, ext) ? ,
454
445
} ;
455
446
456
447
if self . cx . current_expansion . depth > self . cx . ecfg . recursion_limit {
@@ -467,13 +458,16 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
467
458
panic ! ( FatalError ) ;
468
459
}
469
460
470
- result
461
+ Some ( result)
471
462
}
472
463
473
- fn expand_attr_invoc ( & mut self , invoc : Invocation , ext : Rc < SyntaxExtension > ) -> Expansion {
464
+ fn expand_attr_invoc ( & mut self ,
465
+ invoc : Invocation ,
466
+ ext : Rc < SyntaxExtension > )
467
+ -> Option < Expansion > {
474
468
let Invocation { expansion_kind : kind, .. } = invoc;
475
469
let ( attr, item) = match invoc. kind {
476
- InvocationKind :: Attr { attr, item, .. } => ( attr. unwrap ( ) , item) ,
470
+ InvocationKind :: Attr { attr, item, .. } => ( attr? , item) ,
477
471
_ => unreachable ! ( ) ,
478
472
} ;
479
473
@@ -490,16 +484,16 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
490
484
491
485
match * ext {
492
486
MultiModifier ( ref mac) => {
493
- let meta = panictry ! ( attr. parse_meta( self . cx. parse_sess) ) ;
487
+ let meta = attr. parse_meta ( self . cx . parse_sess ) . ok ( ) ? ;
494
488
let item = mac. expand ( self . cx , attr. span , & meta, item) ;
495
- kind. expect_from_annotatables ( item)
489
+ Some ( kind. expect_from_annotatables ( item) )
496
490
}
497
491
MultiDecorator ( ref mac) => {
498
492
let mut items = Vec :: new ( ) ;
499
- let meta = panictry ! ( attr. parse_meta( self . cx. parse_sess) ) ;
493
+ let meta = attr. parse_meta ( self . cx . parse_sess ) . ok ( ) ? ;
500
494
mac. expand ( self . cx , attr. span , & meta, & item, & mut |item| items. push ( item) ) ;
501
495
items. push ( item) ;
502
- kind. expect_from_annotatables ( items)
496
+ Some ( kind. expect_from_annotatables ( items) )
503
497
}
504
498
AttrProcMacro ( ref mac) => {
505
499
let item_tok = TokenTree :: Token ( DUMMY_SP , Token :: interpolated ( match item {
@@ -525,7 +519,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
525
519
}
526
520
527
521
/// Expand a macro invocation. Returns the result of expansion.
528
- fn expand_bang_invoc ( & mut self , invoc : Invocation , ext : Rc < SyntaxExtension > ) -> Expansion {
522
+ fn expand_bang_invoc ( & mut self ,
523
+ invoc : Invocation ,
524
+ ext : Rc < SyntaxExtension > )
525
+ -> Option < Expansion > {
529
526
let ( mark, kind) = ( invoc. expansion_data . mark , invoc. expansion_kind ) ;
530
527
let ( mac, ident, span) = match invoc. kind {
531
528
InvocationKind :: Bang { mac, ident, span } => ( mac, ident, span) ,
@@ -558,9 +555,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
558
555
false , false ) {
559
556
self . cx . span_err ( path. span , & msg) ;
560
557
self . cx . trace_macros_diag ( ) ;
561
- return kind. dummy ( span) ;
558
+ kind. dummy ( span)
559
+ } else {
560
+ kind. make_from ( expand. expand ( self . cx , span, mac. node . stream ( ) ) )
562
561
}
563
- kind. make_from ( expand. expand ( self . cx , span, mac. node . stream ( ) ) )
564
562
}
565
563
566
564
NormalTT {
@@ -574,44 +572,45 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
574
572
allow_internal_unsafe) {
575
573
self . cx . span_err ( path. span , & msg) ;
576
574
self . cx . trace_macros_diag ( ) ;
577
- return kind. dummy ( span) ;
575
+ kind. dummy ( span)
576
+ } else {
577
+ kind. make_from ( expander. expand ( self . cx , span, mac. node . stream ( ) ) )
578
578
}
579
- kind. make_from ( expander. expand ( self . cx , span, mac. node . stream ( ) ) )
580
579
}
581
580
582
581
IdentTT ( ref expander, tt_span, allow_internal_unstable) => {
583
582
if ident. name == keywords:: Invalid . name ( ) {
584
583
self . cx . span_err ( path. span ,
585
584
& format ! ( "macro {}! expects an ident argument" , path) ) ;
586
585
self . cx . trace_macros_diag ( ) ;
587
- return kind. dummy ( span) ;
588
- } ;
589
-
590
- invoc. expansion_data . mark . set_expn_info ( ExpnInfo {
591
- call_site : span,
592
- callee : NameAndSpan {
593
- format : macro_bang_format ( path) ,
594
- span : tt_span,
595
- allow_internal_unstable,
596
- allow_internal_unsafe : false ,
597
- }
598
- } ) ;
586
+ kind. dummy ( span)
587
+ } else {
588
+ invoc. expansion_data . mark . set_expn_info ( ExpnInfo {
589
+ call_site : span,
590
+ callee : NameAndSpan {
591
+ format : macro_bang_format ( path) ,
592
+ span : tt_span,
593
+ allow_internal_unstable,
594
+ allow_internal_unsafe : false ,
595
+ }
596
+ } ) ;
599
597
600
- let input: Vec < _ > = mac. node . stream ( ) . into_trees ( ) . collect ( ) ;
601
- kind. make_from ( expander. expand ( self . cx , span, ident, input) )
598
+ let input: Vec < _ > = mac. node . stream ( ) . into_trees ( ) . collect ( ) ;
599
+ kind. make_from ( expander. expand ( self . cx , span, ident, input) )
600
+ }
602
601
}
603
602
604
603
MultiDecorator ( ..) | MultiModifier ( ..) | AttrProcMacro ( ..) => {
605
604
self . cx . span_err ( path. span ,
606
605
& format ! ( "`{}` can only be used in attributes" , path) ) ;
607
606
self . cx . trace_macros_diag ( ) ;
608
- return kind. dummy ( span) ;
607
+ kind. dummy ( span)
609
608
}
610
609
611
610
ProcMacroDerive ( ..) | BuiltinDerive ( ..) => {
612
611
self . cx . span_err ( path. span , & format ! ( "`{}` is a derive mode" , path) ) ;
613
612
self . cx . trace_macros_diag ( ) ;
614
- return kind. dummy ( span) ;
613
+ kind. dummy ( span)
615
614
}
616
615
617
616
ProcMacro ( ref expandfun) => {
@@ -620,43 +619,51 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
620
619
format ! ( "macro {}! expects no ident argument, given '{}'" , path, ident) ;
621
620
self . cx . span_err ( path. span , & msg) ;
622
621
self . cx . trace_macros_diag ( ) ;
623
- return kind. dummy ( span) ;
624
- }
622
+ kind. dummy ( span)
623
+ } else {
624
+ invoc. expansion_data . mark . set_expn_info ( ExpnInfo {
625
+ call_site : span,
626
+ callee : NameAndSpan {
627
+ format : macro_bang_format ( path) ,
628
+ // FIXME procedural macros do not have proper span info
629
+ // yet, when they do, we should use it here.
630
+ span : None ,
631
+ // FIXME probably want to follow macro_rules macros here.
632
+ allow_internal_unstable : false ,
633
+ allow_internal_unsafe : false ,
634
+ } ,
635
+ } ) ;
625
636
626
- invoc. expansion_data . mark . set_expn_info ( ExpnInfo {
627
- call_site : span,
628
- callee : NameAndSpan {
629
- format : macro_bang_format ( path) ,
630
- // FIXME procedural macros do not have proper span info
631
- // yet, when they do, we should use it here.
632
- span : None ,
633
- // FIXME probably want to follow macro_rules macros here.
634
- allow_internal_unstable : false ,
635
- allow_internal_unsafe : false ,
636
- } ,
637
- } ) ;
638
-
639
- let tok_result = expandfun. expand ( self . cx , span, mac. node . stream ( ) ) ;
640
- Some ( self . parse_expansion ( tok_result, kind, path, span) )
637
+ let tok_result = expandfun. expand ( self . cx , span, mac. node . stream ( ) ) ;
638
+ self . parse_expansion ( tok_result, kind, path, span)
639
+ }
641
640
}
642
641
} ;
643
642
644
- unwrap_or ! ( opt_expanded, {
643
+ if opt_expanded. is_some ( ) {
644
+ opt_expanded
645
+ } else {
645
646
let msg = format ! ( "non-{kind} macro in {kind} position: {name}" ,
646
647
name = path. segments[ 0 ] . identifier. name, kind = kind. name( ) ) ;
647
648
self . cx . span_err ( path. span , & msg) ;
648
649
self . cx . trace_macros_diag ( ) ;
649
650
kind. dummy ( span)
650
- } )
651
+ }
651
652
}
652
653
653
654
/// Expand a derive invocation. Returns the result of expansion.
654
- fn expand_derive_invoc ( & mut self , invoc : Invocation , ext : Rc < SyntaxExtension > ) -> Expansion {
655
+ fn expand_derive_invoc ( & mut self ,
656
+ invoc : Invocation ,
657
+ ext : Rc < SyntaxExtension > )
658
+ -> Option < Expansion > {
655
659
let Invocation { expansion_kind : kind, .. } = invoc;
656
660
let ( path, item) = match invoc. kind {
657
661
InvocationKind :: Derive { path, item } => ( path, item) ,
658
662
_ => unreachable ! ( ) ,
659
663
} ;
664
+ if !item. derive_allowed ( ) {
665
+ return None ;
666
+ }
660
667
661
668
let pretty_name = Symbol :: intern ( & format ! ( "derive({})" , path) ) ;
662
669
let span = path. span ;
@@ -686,15 +693,15 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
686
693
span : DUMMY_SP ,
687
694
node : ast:: MetaItemKind :: Word ,
688
695
} ;
689
- kind. expect_from_annotatables ( ext. expand ( self . cx , span, & dummy, item) )
696
+ Some ( kind. expect_from_annotatables ( ext. expand ( self . cx , span, & dummy, item) ) )
690
697
}
691
698
BuiltinDerive ( func) => {
692
699
expn_info. callee . allow_internal_unstable = true ;
693
700
invoc. expansion_data . mark . set_expn_info ( expn_info) ;
694
701
let span = span. with_ctxt ( self . cx . backtrace ( ) ) ;
695
702
let mut items = Vec :: new ( ) ;
696
- func ( self . cx , span, & attr. meta ( ) . unwrap ( ) , & item, & mut |a| items. push ( a) ) ;
697
- kind. expect_from_annotatables ( items)
703
+ func ( self . cx , span, & attr. meta ( ) ? , & item, & mut |a| items. push ( a) ) ;
704
+ Some ( kind. expect_from_annotatables ( items) )
698
705
}
699
706
_ => {
700
707
let msg = & format ! ( "macro `{}` may not be used for derive attributes" , attr. path) ;
@@ -705,19 +712,24 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
705
712
}
706
713
}
707
714
708
- fn parse_expansion ( & mut self , toks : TokenStream , kind : ExpansionKind , path : & Path , span : Span )
709
- -> Expansion {
715
+ fn parse_expansion ( & mut self ,
716
+ toks : TokenStream ,
717
+ kind : ExpansionKind ,
718
+ path : & Path ,
719
+ span : Span )
720
+ -> Option < Expansion > {
710
721
let mut parser = self . cx . new_parser_from_tts ( & toks. into_trees ( ) . collect :: < Vec < _ > > ( ) ) ;
711
- let expansion = match parser. parse_expansion ( kind, false ) {
712
- Ok ( expansion) => expansion,
722
+ match parser. parse_expansion ( kind, false ) {
723
+ Ok ( expansion) => {
724
+ parser. ensure_complete_parse ( path, kind. name ( ) , span) ;
725
+ Some ( expansion)
726
+ }
713
727
Err ( mut err) => {
714
728
err. emit ( ) ;
715
729
self . cx . trace_macros_diag ( ) ;
716
- return kind. dummy ( span) ;
730
+ kind. dummy ( span)
717
731
}
718
- } ;
719
- parser. ensure_complete_parse ( path, kind. name ( ) , span) ;
720
- expansion
732
+ }
721
733
}
722
734
}
723
735
0 commit comments