From 51499b6e1fd892b68eeb28eaec9031f01a6a9409 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Thu, 2 Jun 2016 01:14:33 +0000 Subject: Load macros from `extern crate`s during expansion. --- src/libsyntax/ext/expand.rs | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'src/libsyntax/ext/expand.rs') diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 7fee27c5dd4..c581a149f43 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -750,6 +750,15 @@ fn expand_annotatable(a: Annotatable, } result.into_iter().map(|i| Annotatable::Item(i)).collect() }, + ast::ItemKind::ExternCrate(_) => { + // We need to error on `#[macro_use] extern crate` when it isn't at the + // crate root, because `$crate` won't work properly. + let allows_macros = fld.cx.syntax_env.is_crate_root(); + for def in fld.cx.loader.load_crate(&it, allows_macros) { + fld.cx.insert_macro(def); + } + SmallVector::one(Annotatable::Item(it)) + }, _ => noop_fold_item(it, fld).into_iter().map(|i| Annotatable::Item(i)).collect(), }, @@ -1137,8 +1146,6 @@ impl<'feat> ExpansionConfig<'feat> { } pub fn expand_crate(mut cx: ExtCtxt, - // these are the macros being imported to this crate: - imported_macros: Vec, user_exts: Vec, c: Crate) -> (Crate, HashSet) { if std_inject::no_core(&c) { @@ -1151,10 +1158,6 @@ pub fn expand_crate(mut cx: ExtCtxt, let ret = { let mut expander = MacroExpander::new(&mut cx); - for def in imported_macros { - expander.cx.insert_macro(def); - } - for (name, extension) in user_exts { expander.cx.syntax_env.insert(name, extension); } @@ -1220,7 +1223,7 @@ mod tests { use ast; use ast::Name; use codemap; - use ext::base::ExtCtxt; + use ext::base::{ExtCtxt, DummyMacroLoader}; use ext::mtwt; use fold::Folder; use parse; @@ -1291,9 +1294,9 @@ mod tests { src, Vec::new(), &sess).unwrap(); // should fail: - let mut gated_cfgs = vec![]; - let ecx = ExtCtxt::new(&sess, vec![], test_ecfg(), &mut gated_cfgs); - expand_crate(ecx, vec![], vec![], crate_ast); + let (mut gated_cfgs, mut loader) = (vec![], DummyMacroLoader); + let ecx = ExtCtxt::new(&sess, vec![], test_ecfg(), &mut gated_cfgs, &mut loader); + expand_crate(ecx, vec![], crate_ast); } // make sure that macros can't escape modules @@ -1306,9 +1309,9 @@ mod tests { "".to_string(), src, Vec::new(), &sess).unwrap(); - let mut gated_cfgs = vec![]; - let ecx = ExtCtxt::new(&sess, vec![], test_ecfg(), &mut gated_cfgs); - expand_crate(ecx, vec![], vec![], crate_ast); + let (mut gated_cfgs, mut loader) = (vec![], DummyMacroLoader); + let ecx = ExtCtxt::new(&sess, vec![], test_ecfg(), &mut gated_cfgs, &mut loader); + expand_crate(ecx, vec![], crate_ast); } // macro_use modules should allow macros to escape @@ -1320,18 +1323,18 @@ mod tests { "".to_string(), src, Vec::new(), &sess).unwrap(); - let mut gated_cfgs = vec![]; - let ecx = ExtCtxt::new(&sess, vec![], test_ecfg(), &mut gated_cfgs); - expand_crate(ecx, vec![], vec![], crate_ast); + let (mut gated_cfgs, mut loader) = (vec![], DummyMacroLoader); + let ecx = ExtCtxt::new(&sess, vec![], test_ecfg(), &mut gated_cfgs, &mut loader); + expand_crate(ecx, vec![], crate_ast); } fn expand_crate_str(crate_str: String) -> ast::Crate { let ps = parse::ParseSess::new(); let crate_ast = panictry!(string_to_parser(&ps, crate_str).parse_crate_mod()); // the cfg argument actually does matter, here... - let mut gated_cfgs = vec![]; - let ecx = ExtCtxt::new(&ps, vec![], test_ecfg(), &mut gated_cfgs); - expand_crate(ecx, vec![], vec![], crate_ast).0 + let (mut gated_cfgs, mut loader) = (vec![], DummyMacroLoader); + let ecx = ExtCtxt::new(&ps, vec![], test_ecfg(), &mut gated_cfgs, &mut loader); + expand_crate(ecx, vec![], crate_ast).0 } // find the pat_ident paths in a crate -- cgit 1.4.1-3-g733a5