@@ -327,7 +327,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
327327
328328 // FIXME(jseyfried): Refactor out the following logic
329329 let ( expanded_fragment, new_invocations) = if let Some ( ext) = ext {
330- let fragment = self . expand_invoc ( invoc, & ext) ;
330+ let fragment = self . expand_invoc ( invoc, & ext. kind ) ;
331331 self . collect_invocations ( fragment, & [ ] )
332332 } else if let InvocationKind :: Attr { attr : None , traits, item, .. } = invoc. kind {
333333 if !item. derive_allowed ( ) {
@@ -474,12 +474,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
474474 }
475475 }
476476
477- fn expand_invoc ( & mut self , invoc : Invocation , ext : & SyntaxExtension ) -> AstFragment {
478- if invoc . fragment_kind == AstFragmentKind :: ForeignItems &&
479- !self . cx . ecfg . macros_in_extern ( ) {
480- if let SyntaxExtensionKind :: NonMacroAttr { .. } = ext. kind { } else {
477+ fn expand_invoc ( & mut self , invoc : Invocation , ext : & SyntaxExtensionKind ) -> AstFragment {
478+ let ( fragment_kind, span ) = ( invoc . fragment_kind , invoc . span ( ) ) ;
479+ if fragment_kind == AstFragmentKind :: ForeignItems && !self . cx . ecfg . macros_in_extern ( ) {
480+ if let SyntaxExtensionKind :: NonMacroAttr { .. } = ext { } else {
481481 emit_feature_err ( & self . cx . parse_sess , sym:: macros_in_extern,
482- invoc . span ( ) , GateIssue :: Language ,
482+ span, GateIssue :: Language ,
483483 "macro invocations in `extern {}` blocks are experimental" ) ;
484484 }
485485 }
@@ -499,58 +499,84 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
499499 }
500500
501501 match invoc. kind {
502- InvocationKind :: Bang { .. } => self . expand_bang_invoc ( invoc , ext) ,
503- InvocationKind :: Attr { .. } => self . expand_attr_invoc ( invoc , ext ) ,
504- InvocationKind :: Derive { .. } => self . expand_derive_invoc ( invoc , ext ) ,
505- }
506- }
507-
508- fn expand_attr_invoc ( & mut self ,
509- invoc : Invocation ,
510- ext : & SyntaxExtension )
511- -> AstFragment {
512- let ( attr , mut item ) = match invoc . kind {
513- InvocationKind :: Attr { attr : Some ( attr ) , item , .. } => ( attr , item ) ,
514- _ => unreachable ! ( ) ,
515- } ;
516-
517- match & ext . kind {
518- SyntaxExtensionKind :: NonMacroAttr { mark_used } => {
519- attr :: mark_known ( & attr ) ;
520- if * mark_used {
521- attr :: mark_used ( & attr ) ;
502+ InvocationKind :: Bang { mac , .. } => match ext {
503+ SyntaxExtensionKind :: Bang ( expander ) => {
504+ self . gate_proc_macro_expansion_kind ( span , fragment_kind ) ;
505+ let tok_result = expander . expand ( self . cx , span , mac . node . stream ( ) ) ;
506+ let result =
507+ self . parse_ast_fragment ( tok_result , fragment_kind , & mac . node . path , span ) ;
508+ self . gate_proc_macro_expansion ( span , & result ) ;
509+ result
510+ }
511+ SyntaxExtensionKind :: LegacyBang ( expander ) => {
512+ let tok_result = expander . expand ( self . cx , span , mac . node . stream ( ) ) ;
513+ if let Some ( result ) = fragment_kind . make_from ( tok_result ) {
514+ result
515+ } else {
516+ let msg = format ! ( "non-{kind} macro in {kind} position: {path}" ,
517+ kind = fragment_kind . name ( ) , path = mac . node . path ) ;
518+ self . cx . span_err ( span , & msg ) ;
519+ self . cx . trace_macros_diag ( ) ;
520+ fragment_kind . dummy ( span )
521+ }
522522 }
523- item. visit_attrs ( |attrs| attrs. push ( attr) ) ;
524- invoc. fragment_kind . expect_from_annotatables ( iter:: once ( item) )
523+ _ => unreachable ! ( )
525524 }
526- SyntaxExtensionKind :: LegacyAttr ( expander) => {
527- match attr. parse_meta ( self . cx . parse_sess ) {
528- Ok ( meta) => {
529- let item = expander. expand ( self . cx , attr. span , & meta, item) ;
530- invoc. fragment_kind . expect_from_annotatables ( item)
525+ InvocationKind :: Attr { attr : Some ( attr) , mut item, .. } => match ext {
526+ SyntaxExtensionKind :: Attr ( expander) => {
527+ self . gate_proc_macro_attr_item ( span, & item) ;
528+ let item_tok = TokenTree :: token ( token:: Interpolated ( Lrc :: new ( match item {
529+ Annotatable :: Item ( item) => token:: NtItem ( item) ,
530+ Annotatable :: TraitItem ( item) => token:: NtTraitItem ( item. into_inner ( ) ) ,
531+ Annotatable :: ImplItem ( item) => token:: NtImplItem ( item. into_inner ( ) ) ,
532+ Annotatable :: ForeignItem ( item) => token:: NtForeignItem ( item. into_inner ( ) ) ,
533+ Annotatable :: Stmt ( stmt) => token:: NtStmt ( stmt. into_inner ( ) ) ,
534+ Annotatable :: Expr ( expr) => token:: NtExpr ( expr) ,
535+ } ) ) , DUMMY_SP ) . into ( ) ;
536+ let input = self . extract_proc_macro_attr_input ( attr. tokens , span) ;
537+ let tok_result = expander. expand ( self . cx , span, input, item_tok) ;
538+ let res = self . parse_ast_fragment ( tok_result, fragment_kind, & attr. path , span) ;
539+ self . gate_proc_macro_expansion ( span, & res) ;
540+ res
541+ }
542+ SyntaxExtensionKind :: LegacyAttr ( expander) => {
543+ match attr. parse_meta ( self . cx . parse_sess ) {
544+ Ok ( meta) => {
545+ let item = expander. expand ( self . cx , span, & meta, item) ;
546+ fragment_kind. expect_from_annotatables ( item)
547+ }
548+ Err ( mut err) => {
549+ err. emit ( ) ;
550+ fragment_kind. dummy ( span)
551+ }
531552 }
532- Err ( mut err) => {
533- err. emit ( ) ;
534- invoc. fragment_kind . dummy ( attr. span )
553+ }
554+ SyntaxExtensionKind :: NonMacroAttr { mark_used } => {
555+ attr:: mark_known ( & attr) ;
556+ if * mark_used {
557+ attr:: mark_used ( & attr) ;
535558 }
559+ item. visit_attrs ( |attrs| attrs. push ( attr) ) ;
560+ fragment_kind. expect_from_annotatables ( iter:: once ( item) )
536561 }
562+ _ => unreachable ! ( )
537563 }
538- SyntaxExtensionKind :: Attr ( expander ) => {
539- self . gate_proc_macro_attr_item ( attr . span , & item ) ;
540- let item_tok = TokenTree :: token ( token :: Interpolated ( Lrc :: new ( match item {
541- Annotatable :: Item ( item) => token :: NtItem ( item ) ,
542- Annotatable :: TraitItem ( item ) => token :: NtTraitItem ( item . into_inner ( ) ) ,
543- Annotatable :: ImplItem ( item ) => token :: NtImplItem ( item. into_inner ( ) ) ,
544- Annotatable :: ForeignItem ( item ) => token :: NtForeignItem ( item . into_inner ( ) ) ,
545- Annotatable :: Stmt ( stmt ) => token :: NtStmt ( stmt . into_inner ( ) ) ,
546- Annotatable :: Expr ( expr ) => token :: NtExpr ( expr ) ,
547- } ) ) , DUMMY_SP ) . into ( ) ;
548- let input = self . extract_proc_macro_attr_input ( attr . tokens , attr . span ) ;
549- let tok_result = expander . expand ( self . cx , attr . span , input , item_tok ) ;
550- let res = self . parse_ast_fragment ( tok_result , invoc . fragment_kind ,
551- & attr . path , attr . span ) ;
552- self . gate_proc_macro_expansion ( attr . span , & res ) ;
553- res
564+ InvocationKind :: Derive { path , item , item_with_markers } => match ext {
565+ SyntaxExtensionKind :: Derive ( expander ) |
566+ SyntaxExtensionKind :: LegacyDerive ( expander ) => {
567+ let ( path , item) = match ext {
568+ SyntaxExtensionKind :: LegacyDerive ( .. ) => ( path , item_with_markers ) ,
569+ _ => ( path , item) ,
570+ } ;
571+ if !item . derive_allowed ( ) {
572+ return fragment_kind . dummy ( span ) ;
573+ }
574+ let meta = ast :: MetaItem { node : ast :: MetaItemKind :: Word , span, path } ;
575+ let span = span . with_ctxt ( self . cx . backtrace ( ) ) ;
576+ let items = expander . expand ( self . cx , span , & meta , item ) ;
577+ fragment_kind . expect_from_annotatables ( items )
578+ }
579+ _ => unreachable ! ( )
554580 }
555581 _ => unreachable ! ( )
556582 }
@@ -634,42 +660,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
634660 }
635661 }
636662
637- /// Expand a macro invocation. Returns the resulting expanded AST fragment.
638- fn expand_bang_invoc ( & mut self ,
639- invoc : Invocation ,
640- ext : & SyntaxExtension )
641- -> AstFragment {
642- let kind = invoc. fragment_kind ;
643- let ( mac, span) = match invoc. kind {
644- InvocationKind :: Bang { mac, span } => ( mac, span) ,
645- _ => unreachable ! ( ) ,
646- } ;
647- let path = & mac. node . path ;
648-
649- match & ext. kind {
650- SyntaxExtensionKind :: Bang ( expander) => {
651- self . gate_proc_macro_expansion_kind ( span, kind) ;
652- let tok_result = expander. expand ( self . cx , span, mac. node . stream ( ) ) ;
653- let result = self . parse_ast_fragment ( tok_result, kind, path, span) ;
654- self . gate_proc_macro_expansion ( span, & result) ;
655- result
656- }
657- SyntaxExtensionKind :: LegacyBang ( expander) => {
658- let tok_result = expander. expand ( self . cx , span, mac. node . stream ( ) ) ;
659- if let Some ( result) = kind. make_from ( tok_result) {
660- result
661- } else {
662- let msg = format ! ( "non-{kind} macro in {kind} position: {name}" ,
663- name = path. segments[ 0 ] . ident. name, kind = kind. name( ) ) ;
664- self . cx . span_err ( path. span , & msg) ;
665- self . cx . trace_macros_diag ( ) ;
666- kind. dummy ( span)
667- }
668- }
669- _ => unreachable ! ( )
670- }
671- }
672-
673663 fn gate_proc_macro_expansion_kind ( & self , span : Span , kind : AstFragmentKind ) {
674664 let kind = match kind {
675665 AstFragmentKind :: Expr => "expressions" ,
@@ -694,34 +684,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
694684 ) ;
695685 }
696686
697- /// Expand a derive invocation. Returns the resulting expanded AST fragment.
698- fn expand_derive_invoc ( & mut self ,
699- invoc : Invocation ,
700- ext : & SyntaxExtension )
701- -> AstFragment {
702- let ( path, item) = match invoc. kind {
703- InvocationKind :: Derive { path, item, item_with_markers } => match ext. kind {
704- SyntaxExtensionKind :: LegacyDerive ( ..) => ( path, item_with_markers) ,
705- _ => ( path, item) ,
706- }
707- _ => unreachable ! ( ) ,
708- } ;
709- if !item. derive_allowed ( ) {
710- return invoc. fragment_kind . dummy ( path. span ) ;
711- }
712-
713- match & ext. kind {
714- SyntaxExtensionKind :: Derive ( expander) |
715- SyntaxExtensionKind :: LegacyDerive ( expander) => {
716- let meta = ast:: MetaItem { node : ast:: MetaItemKind :: Word , span : path. span , path } ;
717- let span = meta. span . with_ctxt ( self . cx . backtrace ( ) ) ;
718- let items = expander. expand ( self . cx , span, & meta, item) ;
719- invoc. fragment_kind . expect_from_annotatables ( items)
720- }
721- _ => unreachable ! ( )
722- }
723- }
724-
725687 fn parse_ast_fragment ( & mut self ,
726688 toks : TokenStream ,
727689 kind : AstFragmentKind ,
0 commit comments