@@ -338,6 +338,7 @@ fn expand_mac_invoc<T>(mac: ast::Mac, ident: Option<Ident>, attrs: Vec<ast::Attr
338
338
339
339
let marked = expanded. fold_with ( & mut Marker { mark : mark, expn_id : Some ( fld. cx . backtrace ( ) ) } ) ;
340
340
let configured = marked. fold_with ( & mut fld. strip_unconfigured ( ) ) ;
341
+ fld. load_macros ( & configured) ;
341
342
let fully_expanded = configured. fold_with ( fld) ;
342
343
fld. cx . bt_pop ( ) ;
343
344
fully_expanded
@@ -760,15 +761,6 @@ fn expand_annotatable(a: Annotatable,
760
761
}
761
762
result
762
763
} ,
763
- ast:: ItemKind :: ExternCrate ( _) => {
764
- // We need to error on `#[macro_use] extern crate` when it isn't at the
765
- // crate root, because `$crate` won't work properly.
766
- let allows_macros = fld. cx . syntax_env . is_crate_root ( ) ;
767
- for def in fld. cx . loader . load_crate ( & it, allows_macros) {
768
- fld. cx . insert_macro ( def) ;
769
- }
770
- SmallVector :: one ( it)
771
- } ,
772
764
_ => noop_fold_item ( it, fld) ,
773
765
} . into_iter ( ) . map ( |i| Annotatable :: Item ( i) ) . collect ( ) ,
774
766
@@ -1017,6 +1009,40 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
1017
1009
& self . cx . parse_sess . span_diagnostic ,
1018
1010
self . cx . feature_gated_cfgs )
1019
1011
}
1012
+
1013
+ fn load_macros < T : MacroGenerable > ( & mut self , node : & T ) {
1014
+ struct MacroLoadingVisitor < ' a , ' b : ' a > {
1015
+ cx : & ' a mut ExtCtxt < ' b > ,
1016
+ at_crate_root : bool ,
1017
+ }
1018
+
1019
+ impl < ' a , ' b , ' v > Visitor < ' v > for MacroLoadingVisitor < ' a , ' b > {
1020
+ fn visit_mac ( & mut self , _: & ' v ast:: Mac ) { }
1021
+ fn visit_item ( & mut self , item : & ' v ast:: Item ) {
1022
+ if let ast:: ItemKind :: ExternCrate ( ..) = item. node {
1023
+ // We need to error on `#[macro_use] extern crate` when it isn't at the
1024
+ // crate root, because `$crate` won't work properly.
1025
+ for def in self . cx . loader . load_crate ( item, self . at_crate_root ) {
1026
+ self . cx . insert_macro ( def) ;
1027
+ }
1028
+ } else {
1029
+ let at_crate_root = :: std:: mem:: replace ( & mut self . at_crate_root , false ) ;
1030
+ visit:: walk_item ( self , item) ;
1031
+ self . at_crate_root = at_crate_root;
1032
+ }
1033
+ }
1034
+ fn visit_block ( & mut self , block : & ' v ast:: Block ) {
1035
+ let at_crate_root = :: std:: mem:: replace ( & mut self . at_crate_root , false ) ;
1036
+ visit:: walk_block ( self , block) ;
1037
+ self . at_crate_root = at_crate_root;
1038
+ }
1039
+ }
1040
+
1041
+ node. visit_with ( & mut MacroLoadingVisitor {
1042
+ at_crate_root : self . cx . syntax_env . is_crate_root ( ) ,
1043
+ cx : self . cx ,
1044
+ } ) ;
1045
+ }
1020
1046
}
1021
1047
1022
1048
impl < ' a , ' b > Folder for MacroExpander < ' a , ' b > {
@@ -1160,7 +1186,7 @@ impl<'feat> ExpansionConfig<'feat> {
1160
1186
1161
1187
pub fn expand_crate ( mut cx : ExtCtxt ,
1162
1188
user_exts : Vec < NamedSyntaxExtension > ,
1163
- c : Crate ) -> ( Crate , HashSet < Name > ) {
1189
+ mut c : Crate ) -> ( Crate , HashSet < Name > ) {
1164
1190
if std_inject:: no_core ( & c) {
1165
1191
cx. crate_root = None ;
1166
1192
} else if std_inject:: no_std ( & c) {
@@ -1175,6 +1201,10 @@ pub fn expand_crate(mut cx: ExtCtxt,
1175
1201
expander. cx . syntax_env . insert ( name, extension) ;
1176
1202
}
1177
1203
1204
+ let items = SmallVector :: many ( c. module . items ) ;
1205
+ expander. load_macros ( & items) ;
1206
+ c. module . items = items. into ( ) ;
1207
+
1178
1208
let err_count = cx. parse_sess . span_diagnostic . err_count ( ) ;
1179
1209
let mut ret = expander. fold_crate ( c) ;
1180
1210
ret. exported_macros = expander. cx . exported_macros . clone ( ) ;
0 commit comments