@@ -21,7 +21,7 @@ use ext::placeholders::{placeholder, PlaceholderExpander};
2121use feature_gate:: { self , Features , GateIssue , is_builtin_attr, emit_feature_err} ;
2222use fold;
2323use fold:: * ;
24- use parse:: { DirectoryOwnership , PResult } ;
24+ use parse:: { DirectoryOwnership , PResult , ParseSess } ;
2525use parse:: token:: { self , Token } ;
2626use parse:: parser:: Parser ;
2727use ptr:: P ;
@@ -532,7 +532,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
532532 } ) ) . into ( ) ;
533533 let input = self . extract_proc_macro_attr_input ( attr. tokens , attr. span ) ;
534534 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
536538 }
537539 ProcMacroDerive ( ..) | BuiltinDerive ( ..) => {
538540 self . cx . span_err ( attr. span , & format ! ( "`{}` is a derive mode" , attr. path) ) ;
@@ -591,6 +593,46 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
591593 ) ;
592594 }
593595
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+
594636 /// Expand a macro invocation. Returns the result of expansion.
595637 fn expand_bang_invoc ( & mut self ,
596638 invoc : Invocation ,
@@ -732,7 +774,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
732774 } ) ;
733775
734776 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
736780 }
737781 }
738782 } ;
@@ -814,7 +858,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
814858 span : DUMMY_SP ,
815859 node : ast:: MetaItemKind :: Word ,
816860 } ;
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
818865 }
819866 BuiltinDerive ( func) => {
820867 expn_info. callee . allow_internal_unstable = true ;
0 commit comments