@@ -136,8 +136,8 @@ expansions! {
136136}
137137
138138impl 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) )
141141 }
142142
143143 fn expect_from_annotatables < I : IntoIterator < Item = Annotatable > > ( self , items : I ) -> Expansion {
@@ -304,21 +304,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
304304 // FIXME(jseyfried): Refactor out the following logic
305305 let ( expansion, new_invocations) = if let Some ( ext) = ext {
306306 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) ;
308309 self . collect_invocations ( expansion, & [ ] )
309310 } 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" )
322313 . expect ( "`derive` attribute should exist" ) ;
323314 let span = attr. span ;
324315 let mut err = self . cx . mut_span_err ( span,
@@ -366,7 +357,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
366357 unreachable ! ( )
367358 }
368359 } else {
369- self . collect_invocations ( invoc. expansion_kind . dummy ( invoc. span ( ) ) , & [ ] )
360+ self . collect_invocations ( invoc. expansion_kind . dummy ( invoc. span ( ) ) . unwrap ( ) , & [ ] )
370361 } ;
371362
372363 if expansions. len ( ) < depth {
@@ -446,11 +437,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
446437 }
447438 }
448439
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 > {
450441 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) ? ,
454445 } ;
455446
456447 if self . cx . current_expansion . depth > self . cx . ecfg . recursion_limit {
@@ -467,13 +458,16 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
467458 panic ! ( FatalError ) ;
468459 }
469460
470- result
461+ Some ( result)
471462 }
472463
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 > {
474468 let Invocation { expansion_kind : kind, .. } = invoc;
475469 let ( attr, item) = match invoc. kind {
476- InvocationKind :: Attr { attr, item, .. } => ( attr. unwrap ( ) , item) ,
470+ InvocationKind :: Attr { attr, item, .. } => ( attr? , item) ,
477471 _ => unreachable ! ( ) ,
478472 } ;
479473
@@ -490,16 +484,16 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
490484
491485 match * ext {
492486 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 ( ) ? ;
494488 let item = mac. expand ( self . cx , attr. span , & meta, item) ;
495- kind. expect_from_annotatables ( item)
489+ Some ( kind. expect_from_annotatables ( item) )
496490 }
497491 MultiDecorator ( ref mac) => {
498492 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 ( ) ? ;
500494 mac. expand ( self . cx , attr. span , & meta, & item, & mut |item| items. push ( item) ) ;
501495 items. push ( item) ;
502- kind. expect_from_annotatables ( items)
496+ Some ( kind. expect_from_annotatables ( items) )
503497 }
504498 AttrProcMacro ( ref mac) => {
505499 let item_tok = TokenTree :: Token ( DUMMY_SP , Token :: interpolated ( match item {
@@ -525,7 +519,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
525519 }
526520
527521 /// 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 > {
529526 let ( mark, kind) = ( invoc. expansion_data . mark , invoc. expansion_kind ) ;
530527 let ( mac, ident, span) = match invoc. kind {
531528 InvocationKind :: Bang { mac, ident, span } => ( mac, ident, span) ,
@@ -558,9 +555,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
558555 false , false ) {
559556 self . cx . span_err ( path. span , & msg) ;
560557 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 ( ) ) )
562561 }
563- kind. make_from ( expand. expand ( self . cx , span, mac. node . stream ( ) ) )
564562 }
565563
566564 NormalTT {
@@ -574,44 +572,45 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
574572 allow_internal_unsafe) {
575573 self . cx . span_err ( path. span , & msg) ;
576574 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 ( ) ) )
578578 }
579- kind. make_from ( expander. expand ( self . cx , span, mac. node . stream ( ) ) )
580579 }
581580
582581 IdentTT ( ref expander, tt_span, allow_internal_unstable) => {
583582 if ident. name == keywords:: Invalid . name ( ) {
584583 self . cx . span_err ( path. span ,
585584 & format ! ( "macro {}! expects an ident argument" , path) ) ;
586585 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+ } ) ;
599597
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+ }
602601 }
603602
604603 MultiDecorator ( ..) | MultiModifier ( ..) | AttrProcMacro ( ..) => {
605604 self . cx . span_err ( path. span ,
606605 & format ! ( "`{}` can only be used in attributes" , path) ) ;
607606 self . cx . trace_macros_diag ( ) ;
608- return kind. dummy ( span) ;
607+ kind. dummy ( span)
609608 }
610609
611610 ProcMacroDerive ( ..) | BuiltinDerive ( ..) => {
612611 self . cx . span_err ( path. span , & format ! ( "`{}` is a derive mode" , path) ) ;
613612 self . cx . trace_macros_diag ( ) ;
614- return kind. dummy ( span) ;
613+ kind. dummy ( span)
615614 }
616615
617616 ProcMacro ( ref expandfun) => {
@@ -620,43 +619,51 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
620619 format ! ( "macro {}! expects no ident argument, given '{}'" , path, ident) ;
621620 self . cx . span_err ( path. span , & msg) ;
622621 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+ } ) ;
625636
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+ }
641640 }
642641 } ;
643642
644- unwrap_or ! ( opt_expanded, {
643+ if opt_expanded. is_some ( ) {
644+ opt_expanded
645+ } else {
645646 let msg = format ! ( "non-{kind} macro in {kind} position: {name}" ,
646647 name = path. segments[ 0 ] . identifier. name, kind = kind. name( ) ) ;
647648 self . cx . span_err ( path. span , & msg) ;
648649 self . cx . trace_macros_diag ( ) ;
649650 kind. dummy ( span)
650- } )
651+ }
651652 }
652653
653654 /// 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 > {
655659 let Invocation { expansion_kind : kind, .. } = invoc;
656660 let ( path, item) = match invoc. kind {
657661 InvocationKind :: Derive { path, item } => ( path, item) ,
658662 _ => unreachable ! ( ) ,
659663 } ;
664+ if !item. derive_allowed ( ) {
665+ return None ;
666+ }
660667
661668 let pretty_name = Symbol :: intern ( & format ! ( "derive({})" , path) ) ;
662669 let span = path. span ;
@@ -686,15 +693,15 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
686693 span : DUMMY_SP ,
687694 node : ast:: MetaItemKind :: Word ,
688695 } ;
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) ) )
690697 }
691698 BuiltinDerive ( func) => {
692699 expn_info. callee . allow_internal_unstable = true ;
693700 invoc. expansion_data . mark . set_expn_info ( expn_info) ;
694701 let span = span. with_ctxt ( self . cx . backtrace ( ) ) ;
695702 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) )
698705 }
699706 _ => {
700707 let msg = & format ! ( "macro `{}` may not be used for derive attributes" , attr. path) ;
@@ -705,19 +712,24 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
705712 }
706713 }
707714
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 > {
710721 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+ }
713727 Err ( mut err) => {
714728 err. emit ( ) ;
715729 self . cx . trace_macros_diag ( ) ;
716- return kind. dummy ( span) ;
730+ kind. dummy ( span)
717731 }
718- } ;
719- parser. ensure_complete_parse ( path, kind. name ( ) , span) ;
720- expansion
732+ }
721733 }
722734}
723735
0 commit comments