@@ -17,9 +17,10 @@ use syntax::parse::token;
1717use syntax:: parse:: parser:: Parser ;
1818use syntax:: print:: pprust;
1919use syntax:: ptr:: P ;
20+ use syntax:: sess:: ParseSess ;
2021use syntax:: symbol:: { sym, Symbol } ;
2122use syntax:: tokenstream:: { TokenStream , TokenTree } ;
22- use syntax:: visit:: Visitor ;
23+ use syntax:: visit:: { self , Visitor } ;
2324use syntax:: util:: map_in_place:: MapInPlace ;
2425
2526use errors:: { Applicability , FatalError } ;
@@ -615,6 +616,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
615616 }
616617 InvocationKind :: Attr { attr, mut item, .. } => match ext {
617618 SyntaxExtensionKind :: Attr ( expander) => {
619+ self . gate_proc_macro_input ( & item) ;
618620 self . gate_proc_macro_attr_item ( span, & item) ;
619621 let item_tok = TokenTree :: token ( token:: Interpolated ( Lrc :: new ( match item {
620622 Annotatable :: Item ( item) => token:: NtItem ( item) ,
@@ -664,6 +666,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
664666 if !item. derive_allowed ( ) {
665667 return fragment_kind. dummy ( span) ;
666668 }
669+ if let SyntaxExtensionKind :: Derive ( ..) = ext {
670+ self . gate_proc_macro_input ( & item) ;
671+ }
667672 let meta = ast:: MetaItem { kind : ast:: MetaItemKind :: Word , span, path } ;
668673 let items = expander. expand ( self . cx , span, & meta, item) ;
669674 fragment_kind. expect_from_annotatables ( items)
@@ -692,21 +697,16 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
692697 }
693698
694699 fn gate_proc_macro_attr_item ( & self , span : Span , item : & Annotatable ) {
695- let ( kind, gate) = match * item {
696- Annotatable :: Item ( ref item) => {
697- match item. kind {
698- ItemKind :: Mod ( _) if self . cx . ecfg . proc_macro_hygiene ( ) => return ,
699- ItemKind :: Mod ( _) => ( "modules" , sym:: proc_macro_hygiene) ,
700- _ => return ,
701- }
700+ let kind = match item {
701+ Annotatable :: Item ( item) => match & item. kind {
702+ ItemKind :: Mod ( m) if m. inline => "modules" ,
703+ _ => return ,
702704 }
703- Annotatable :: TraitItem ( _) => return ,
704- Annotatable :: ImplItem ( _) => return ,
705- Annotatable :: ForeignItem ( _) => return ,
706- Annotatable :: Stmt ( _) |
707- Annotatable :: Expr ( _) if self . cx . ecfg . proc_macro_hygiene ( ) => return ,
708- Annotatable :: Stmt ( _) => ( "statements" , sym:: proc_macro_hygiene) ,
709- Annotatable :: Expr ( _) => ( "expressions" , sym:: proc_macro_hygiene) ,
705+ Annotatable :: TraitItem ( _)
706+ | Annotatable :: ImplItem ( _)
707+ | Annotatable :: ForeignItem ( _) => return ,
708+ Annotatable :: Stmt ( _) => "statements" ,
709+ Annotatable :: Expr ( _) => "expressions" ,
710710 Annotatable :: Arm ( ..)
711711 | Annotatable :: Field ( ..)
712712 | Annotatable :: FieldPat ( ..)
@@ -716,15 +716,49 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
716716 | Annotatable :: Variant ( ..)
717717 => panic ! ( "unexpected annotatable" ) ,
718718 } ;
719+ if self . cx . ecfg . proc_macro_hygiene ( ) {
720+ return
721+ }
719722 emit_feature_err (
720723 self . cx . parse_sess ,
721- gate ,
724+ sym :: proc_macro_hygiene ,
722725 span,
723726 GateIssue :: Language ,
724727 & format ! ( "custom attributes cannot be applied to {}" , kind) ,
725728 ) ;
726729 }
727730
731+ fn gate_proc_macro_input ( & self , annotatable : & Annotatable ) {
732+ struct GateProcMacroInput < ' a > {
733+ parse_sess : & ' a ParseSess ,
734+ }
735+
736+ impl < ' ast , ' a > Visitor < ' ast > for GateProcMacroInput < ' a > {
737+ fn visit_item ( & mut self , item : & ' ast ast:: Item ) {
738+ match & item. kind {
739+ ast:: ItemKind :: Mod ( module) if !module. inline => {
740+ emit_feature_err (
741+ self . parse_sess ,
742+ sym:: proc_macro_hygiene,
743+ item. span ,
744+ GateIssue :: Language ,
745+ "non-inline modules in proc macro input are unstable" ,
746+ ) ;
747+ }
748+ _ => { }
749+ }
750+
751+ visit:: walk_item ( self , item) ;
752+ }
753+
754+ fn visit_mac ( & mut self , _: & ' ast ast:: Mac ) { }
755+ }
756+
757+ if !self . cx . ecfg . proc_macro_hygiene ( ) {
758+ annotatable. visit_with ( & mut GateProcMacroInput { parse_sess : self . cx . parse_sess } ) ;
759+ }
760+ }
761+
728762 fn gate_proc_macro_expansion_kind ( & self , span : Span , kind : AstFragmentKind ) {
729763 let kind = match kind {
730764 AstFragmentKind :: Expr |
0 commit comments