@@ -726,13 +726,11 @@ fn expand_annotatable(a: Annotatable,
726
726
let new_items: SmallVector < Annotatable > = match a {
727
727
Annotatable :: Item ( it) => match it. node {
728
728
ast:: ItemKind :: Mac ( ..) => {
729
- let new_items : SmallVector < P < ast :: Item > > = it. and_then ( |it| match it. node {
729
+ it. and_then ( |it| match it. node {
730
730
ItemKind :: Mac ( mac) =>
731
731
expand_mac_invoc ( mac, Some ( it. ident ) , it. attrs , it. span , fld) ,
732
732
_ => unreachable ! ( ) ,
733
- } ) ;
734
-
735
- new_items. into_iter ( ) . map ( |i| Annotatable :: Item ( i) ) . collect ( )
733
+ } )
736
734
}
737
735
ast:: ItemKind :: Mod ( _) | ast:: ItemKind :: ForeignMod ( _) => {
738
736
let valid_ident =
@@ -748,10 +746,19 @@ fn expand_annotatable(a: Annotatable,
748
746
if valid_ident {
749
747
fld. cx . mod_pop ( ) ;
750
748
}
751
- result. into_iter ( ) . map ( |i| Annotatable :: Item ( i ) ) . collect ( )
749
+ result
752
750
} ,
753
- _ => noop_fold_item ( it, fld) . into_iter ( ) . map ( |i| Annotatable :: Item ( i) ) . collect ( ) ,
754
- } ,
751
+ ast:: ItemKind :: ExternCrate ( _) => {
752
+ // We need to error on `#[macro_use] extern crate` when it isn't at the
753
+ // crate root, because `$crate` won't work properly.
754
+ let allows_macros = fld. cx . syntax_env . is_crate_root ( ) ;
755
+ for def in fld. cx . loader . load_crate ( & it, allows_macros) {
756
+ fld. cx . insert_macro ( def) ;
757
+ }
758
+ SmallVector :: one ( it)
759
+ } ,
760
+ _ => noop_fold_item ( it, fld) ,
761
+ } . into_iter ( ) . map ( |i| Annotatable :: Item ( i) ) . collect ( ) ,
755
762
756
763
Annotatable :: TraitItem ( it) => match it. node {
757
764
ast:: TraitItemKind :: Method ( _, Some ( _) ) => {
@@ -1137,8 +1144,6 @@ impl<'feat> ExpansionConfig<'feat> {
1137
1144
}
1138
1145
1139
1146
pub fn expand_crate ( mut cx : ExtCtxt ,
1140
- // these are the macros being imported to this crate:
1141
- imported_macros : Vec < ast:: MacroDef > ,
1142
1147
user_exts : Vec < NamedSyntaxExtension > ,
1143
1148
c : Crate ) -> ( Crate , HashSet < Name > ) {
1144
1149
if std_inject:: no_core ( & c) {
@@ -1151,10 +1156,6 @@ pub fn expand_crate(mut cx: ExtCtxt,
1151
1156
let ret = {
1152
1157
let mut expander = MacroExpander :: new ( & mut cx) ;
1153
1158
1154
- for def in imported_macros {
1155
- expander. cx . insert_macro ( def) ;
1156
- }
1157
-
1158
1159
for ( name, extension) in user_exts {
1159
1160
expander. cx . syntax_env . insert ( name, extension) ;
1160
1161
}
@@ -1220,7 +1221,7 @@ mod tests {
1220
1221
use ast;
1221
1222
use ast:: Name ;
1222
1223
use codemap;
1223
- use ext:: base:: ExtCtxt ;
1224
+ use ext:: base:: { ExtCtxt , DummyMacroLoader } ;
1224
1225
use ext:: mtwt;
1225
1226
use fold:: Folder ;
1226
1227
use parse;
@@ -1291,9 +1292,9 @@ mod tests {
1291
1292
src,
1292
1293
Vec :: new ( ) , & sess) . unwrap ( ) ;
1293
1294
// should fail:
1294
- let mut gated_cfgs = vec ! [ ] ;
1295
- let ecx = ExtCtxt :: new ( & sess, vec ! [ ] , test_ecfg ( ) , & mut gated_cfgs) ;
1296
- expand_crate ( ecx, vec ! [ ] , vec ! [ ] , crate_ast) ;
1295
+ let ( mut gated_cfgs, mut loader ) = ( vec ! [ ] , DummyMacroLoader ) ;
1296
+ let ecx = ExtCtxt :: new ( & sess, vec ! [ ] , test_ecfg ( ) , & mut gated_cfgs, & mut loader ) ;
1297
+ expand_crate ( ecx, vec ! [ ] , crate_ast) ;
1297
1298
}
1298
1299
1299
1300
// make sure that macros can't escape modules
@@ -1306,9 +1307,9 @@ mod tests {
1306
1307
"<test>" . to_string ( ) ,
1307
1308
src,
1308
1309
Vec :: new ( ) , & sess) . unwrap ( ) ;
1309
- let mut gated_cfgs = vec ! [ ] ;
1310
- let ecx = ExtCtxt :: new ( & sess, vec ! [ ] , test_ecfg ( ) , & mut gated_cfgs) ;
1311
- expand_crate ( ecx, vec ! [ ] , vec ! [ ] , crate_ast) ;
1310
+ let ( mut gated_cfgs, mut loader ) = ( vec ! [ ] , DummyMacroLoader ) ;
1311
+ let ecx = ExtCtxt :: new ( & sess, vec ! [ ] , test_ecfg ( ) , & mut gated_cfgs, & mut loader ) ;
1312
+ expand_crate ( ecx, vec ! [ ] , crate_ast) ;
1312
1313
}
1313
1314
1314
1315
// macro_use modules should allow macros to escape
@@ -1320,18 +1321,18 @@ mod tests {
1320
1321
"<test>" . to_string ( ) ,
1321
1322
src,
1322
1323
Vec :: new ( ) , & sess) . unwrap ( ) ;
1323
- let mut gated_cfgs = vec ! [ ] ;
1324
- let ecx = ExtCtxt :: new ( & sess, vec ! [ ] , test_ecfg ( ) , & mut gated_cfgs) ;
1325
- expand_crate ( ecx, vec ! [ ] , vec ! [ ] , crate_ast) ;
1324
+ let ( mut gated_cfgs, mut loader ) = ( vec ! [ ] , DummyMacroLoader ) ;
1325
+ let ecx = ExtCtxt :: new ( & sess, vec ! [ ] , test_ecfg ( ) , & mut gated_cfgs, & mut loader ) ;
1326
+ expand_crate ( ecx, vec ! [ ] , crate_ast) ;
1326
1327
}
1327
1328
1328
1329
fn expand_crate_str ( crate_str : String ) -> ast:: Crate {
1329
1330
let ps = parse:: ParseSess :: new ( ) ;
1330
1331
let crate_ast = panictry ! ( string_to_parser( & ps, crate_str) . parse_crate_mod( ) ) ;
1331
1332
// the cfg argument actually does matter, here...
1332
- let mut gated_cfgs = vec ! [ ] ;
1333
- let ecx = ExtCtxt :: new ( & ps, vec ! [ ] , test_ecfg ( ) , & mut gated_cfgs) ;
1334
- expand_crate ( ecx, vec ! [ ] , vec ! [ ] , crate_ast) . 0
1333
+ let ( mut gated_cfgs, mut loader ) = ( vec ! [ ] , DummyMacroLoader ) ;
1334
+ let ecx = ExtCtxt :: new ( & ps, vec ! [ ] , test_ecfg ( ) , & mut gated_cfgs, & mut loader ) ;
1335
+ expand_crate ( ecx, vec ! [ ] , crate_ast) . 0
1335
1336
}
1336
1337
1337
1338
// find the pat_ident paths in a crate
0 commit comments