@@ -17,9 +17,10 @@ use syntax::parse::token;
17
17
use syntax:: parse:: parser:: Parser ;
18
18
use syntax:: print:: pprust;
19
19
use syntax:: ptr:: P ;
20
+ use syntax:: sess:: ParseSess ;
20
21
use syntax:: symbol:: { sym, Symbol } ;
21
22
use syntax:: tokenstream:: { TokenStream , TokenTree } ;
22
- use syntax:: visit:: Visitor ;
23
+ use syntax:: visit:: { self , Visitor } ;
23
24
use syntax:: util:: map_in_place:: MapInPlace ;
24
25
25
26
use errors:: { Applicability , FatalError } ;
@@ -615,6 +616,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
615
616
}
616
617
InvocationKind :: Attr { attr, mut item, .. } => match ext {
617
618
SyntaxExtensionKind :: Attr ( expander) => {
619
+ self . gate_proc_macro_input ( & item) ;
618
620
self . gate_proc_macro_attr_item ( span, & item) ;
619
621
let item_tok = TokenTree :: token ( token:: Interpolated ( Lrc :: new ( match item {
620
622
Annotatable :: Item ( item) => token:: NtItem ( item) ,
@@ -664,6 +666,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
664
666
if !item. derive_allowed ( ) {
665
667
return fragment_kind. dummy ( span) ;
666
668
}
669
+ if let SyntaxExtensionKind :: Derive ( ..) = ext {
670
+ self . gate_proc_macro_input ( & item) ;
671
+ }
667
672
let meta = ast:: MetaItem { kind : ast:: MetaItemKind :: Word , span, path } ;
668
673
let items = expander. expand ( self . cx , span, & meta, item) ;
669
674
fragment_kind. expect_from_annotatables ( items)
@@ -692,21 +697,16 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
692
697
}
693
698
694
699
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 ,
702
704
}
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" ,
710
710
Annotatable :: Arm ( ..)
711
711
| Annotatable :: Field ( ..)
712
712
| Annotatable :: FieldPat ( ..)
@@ -716,15 +716,49 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
716
716
| Annotatable :: Variant ( ..)
717
717
=> panic ! ( "unexpected annotatable" ) ,
718
718
} ;
719
+ if self . cx . ecfg . proc_macro_hygiene ( ) {
720
+ return
721
+ }
719
722
emit_feature_err (
720
723
self . cx . parse_sess ,
721
- gate ,
724
+ sym :: proc_macro_hygiene ,
722
725
span,
723
726
GateIssue :: Language ,
724
727
& format ! ( "custom attributes cannot be applied to {}" , kind) ,
725
728
) ;
726
729
}
727
730
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
+
728
762
fn gate_proc_macro_expansion_kind ( & self , span : Span , kind : AstFragmentKind ) {
729
763
let kind = match kind {
730
764
AstFragmentKind :: Expr |
0 commit comments