@@ -21,7 +21,7 @@ use ext::placeholders::{placeholder, PlaceholderExpander};
21
21
use feature_gate:: { self , Features , GateIssue , is_builtin_attr, emit_feature_err} ;
22
22
use fold;
23
23
use fold:: * ;
24
- use parse:: { DirectoryOwnership , PResult } ;
24
+ use parse:: { DirectoryOwnership , PResult , ParseSess } ;
25
25
use parse:: token:: { self , Token } ;
26
26
use parse:: parser:: Parser ;
27
27
use ptr:: P ;
@@ -532,7 +532,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
532
532
} ) ) . into ( ) ;
533
533
let input = self . extract_proc_macro_attr_input ( attr. tokens , attr. span ) ;
534
534
let tok_result = mac. expand ( self . cx , attr. span , input, item_tok) ;
535
- self . parse_expansion ( tok_result, kind, & attr. path , attr. span )
535
+ let res = self . parse_expansion ( tok_result, kind, & attr. path , attr. span ) ;
536
+ self . gate_proc_macro_expansion ( attr. span , & res) ;
537
+ res
536
538
}
537
539
ProcMacroDerive ( ..) | BuiltinDerive ( ..) => {
538
540
self . cx . span_err ( attr. span , & format ! ( "`{}` is a derive mode" , attr. path) ) ;
@@ -591,6 +593,46 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
591
593
) ;
592
594
}
593
595
596
+ fn gate_proc_macro_expansion ( & self , span : Span , expansion : & Option < Expansion > ) {
597
+ if self . cx . ecfg . proc_macro_mod ( ) {
598
+ return
599
+ }
600
+ let expansion = match expansion {
601
+ Some ( expansion) => expansion,
602
+ None => return ,
603
+ } ;
604
+
605
+ expansion. visit_with ( & mut DisallowModules {
606
+ span,
607
+ parse_sess : self . cx . parse_sess ,
608
+ } ) ;
609
+
610
+ struct DisallowModules < ' a > {
611
+ span : Span ,
612
+ parse_sess : & ' a ParseSess ,
613
+ }
614
+
615
+ impl < ' ast , ' a > Visitor < ' ast > for DisallowModules < ' a > {
616
+ fn visit_mod ( & mut self ,
617
+ _m : & ' ast ast:: Mod ,
618
+ _s : Span ,
619
+ _attrs : & [ ast:: Attribute ] ,
620
+ _n : NodeId ) {
621
+ emit_feature_err (
622
+ self . parse_sess ,
623
+ "proc_macro_mod" ,
624
+ self . span ,
625
+ GateIssue :: Language ,
626
+ "procedural macros cannot expand to modules" ,
627
+ ) ;
628
+ }
629
+
630
+ fn visit_mac ( & mut self , _mac : & ' ast ast:: Mac ) {
631
+ // ...
632
+ }
633
+ }
634
+ }
635
+
594
636
/// Expand a macro invocation. Returns the result of expansion.
595
637
fn expand_bang_invoc ( & mut self ,
596
638
invoc : Invocation ,
@@ -732,7 +774,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
732
774
} ) ;
733
775
734
776
let tok_result = expandfun. expand ( self . cx , span, mac. node . stream ( ) ) ;
735
- self . parse_expansion ( tok_result, kind, path, span)
777
+ let result = self . parse_expansion ( tok_result, kind, path, span) ;
778
+ self . gate_proc_macro_expansion ( span, & result) ;
779
+ result
736
780
}
737
781
}
738
782
} ;
@@ -814,7 +858,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
814
858
span : DUMMY_SP ,
815
859
node : ast:: MetaItemKind :: Word ,
816
860
} ;
817
- Some ( kind. expect_from_annotatables ( ext. expand ( self . cx , span, & dummy, item) ) )
861
+ let items = ext. expand ( self . cx , span, & dummy, item) ;
862
+ let res = Some ( kind. expect_from_annotatables ( items) ) ;
863
+ self . gate_proc_macro_expansion ( span, & res) ;
864
+ res
818
865
}
819
866
BuiltinDerive ( func) => {
820
867
expn_info. callee . allow_internal_unstable = true ;
0 commit comments