diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index c7a8457c6d24a..d83bd8b922395 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -552,6 +552,7 @@ impl<'a> PluginMetadata<'a> { id: ast::DUMMY_NODE_ID, span: span, imported_from: imported_from, + export: false, // overridden in plugin/load.rs body: body, }); true diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs index d17ef199aa1bd..93c97f6caa66a 100644 --- a/src/librustc/plugin/load.rs +++ b/src/librustc/plugin/load.rs @@ -17,8 +17,10 @@ use plugin::registry::Registry; use std::mem; use std::os; use std::dynamic_lib::DynamicLibrary; +use std::collections::HashSet; use syntax::ast; use syntax::attr; +use syntax::parse::token; use syntax::visit; use syntax::visit::Visitor; use syntax::attr::AttrMetaMethods; @@ -87,6 +89,7 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> { // Parse the attributes relating to macro / plugin loading. let mut load_macros = false; let mut load_registrar = false; + let mut reexport = HashSet::new(); for attr in vi.attrs.iter() { let mut used = true; match attr.name().get() { @@ -96,6 +99,23 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> { } "plugin" => load_registrar = true, "macro_use" => load_macros = true, + "macro_reexport" => { + let names = match attr.meta_item_list() { + Some(names) => names, + None => { + self.sess.span_err(attr.span, "bad macro reexport"); + continue; + } + }; + + for name in names.iter() { + if let ast::MetaWord(ref name) = name.node { + reexport.insert(name.clone()); + } else { + self.sess.span_err(name.span, "bad macro reexport"); + } + } + } _ => used = false, } if used { @@ -116,7 +136,13 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> { } } - self.plugins.macros.extend(macros.into_iter()); + for mut def in macros.into_iter() { + if reexport.contains(&token::get_ident(def.ident)) { + def.export = true; + } + self.plugins.macros.push(def); + } + if let Some((lib, symbol)) = registrar { self.dylink_registrar(vi, lib, symbol); } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index f23cddf833cc9..261d73b5bf07a 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -275,8 +275,6 @@ pub fn phase_2_configure_and_expand(sess: &Session, deriving_hash_type_parameter: sess.features.borrow().default_type_params, enable_quotes: sess.features.borrow().quote, recursion_limit: sess.recursion_limit.get(), - reexported_macros: syntax::ext::tt::reexport::gather(sess.diagnostic(), - &krate), }; let ret = syntax::ext::expand::expand_crate(&sess.parse_sess, cfg, diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 3eda6d3374ed9..65c36d813f478 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -117,9 +117,6 @@ #![reexport_test_harness_main = "test_main"] -#![macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq, - unreachable, unimplemented, write, writeln, vec)] - #[cfg(all(test, stage0))] #[phase(plugin, link)] extern crate log; @@ -134,6 +131,8 @@ extern crate core; #[cfg(not(stage0))] #[macro_use] +#[macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq, + unreachable, unimplemented, write, writeln)] extern crate core; #[cfg(stage0)] @@ -142,6 +141,7 @@ extern crate "collections" as core_collections; #[cfg(not(stage0))] #[macro_use] +#[macro_reexport(vec)] extern crate "collections" as core_collections; extern crate "rand" as core_rand; diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 36fc8a691dc30..e34060a73c154 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1708,6 +1708,7 @@ pub struct MacroDef { pub id: NodeId, pub span: Span, pub imported_from: Option, + pub export: bool, pub body: Vec, } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 9a06745967f0d..815159e94c82a 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -16,6 +16,7 @@ use codemap; use codemap::{CodeMap, Span, ExpnId, ExpnInfo, NO_EXPANSION}; use ext; use ext::expand; +use ext::tt::macro_rules; use parse; use parse::parser; use parse::token; @@ -568,6 +569,15 @@ impl<'a> ExtCtxt<'a> { } } } + + pub fn insert_macro(&mut self, def: ast::MacroDef) { + if def.export { + self.exported_macros.push(def.clone()); + } + let ext = macro_rules::compile(self, &def); + self.syntax_env.insert(def.ident.name, ext); + } + /// Emit `msg` attached to `sp`, and stop compilation immediately. /// /// `span_err` should be strongly preferred where-ever possible: diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index d56df2d7fb4e0..6c2b0610fa037 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -17,7 +17,6 @@ use ast; use ast_util::path_to_ident; use ext::mtwt; use ext::build::AstBuilder; -use ext::tt::macro_rules; use attr; use attr::AttrMetaMethods; use codemap; @@ -636,14 +635,10 @@ pub fn expand_item_mac(it: P, id: ast::DUMMY_NODE_ID, span: it.span, imported_from: None, + export: attr::contains_name(it.attrs.as_slice(), "macro_export"), body: tts, }; - let ext = macro_rules::compile(fld.cx, &def); - fld.cx.syntax_env.insert(def.ident.name, ext); - - if attr::contains_name(def.attrs.as_slice(), "macro_export") { - fld.cx.exported_macros.push(def); - } + fld.cx.insert_macro(def); // macro_rules! has a side effect but expands to nothing. fld.cx.bt_pop(); @@ -1178,7 +1173,6 @@ pub struct ExpansionConfig { pub deriving_hash_type_parameter: bool, pub enable_quotes: bool, pub recursion_limit: uint, - pub reexported_macros: Vec, } impl ExpansionConfig { @@ -1188,7 +1182,6 @@ impl ExpansionConfig { deriving_hash_type_parameter: false, enable_quotes: false, recursion_limit: 64, - reexported_macros: vec![], } } } @@ -1202,15 +1195,8 @@ pub fn expand_crate(parse_sess: &parse::ParseSess, let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg); let mut expander = MacroExpander::new(&mut cx); - for def in imported_macros.iter() { - let ext = macro_rules::compile(expander.cx, def); - expander.cx.syntax_env.insert(def.ident.name, ext); - - if expander.cx.ecfg.reexported_macros.iter() - .any(|e| e[] == token::get_ident(def.ident).get()) { - - expander.cx.exported_macros.push(def.clone()); - } + for def in imported_macros.into_iter() { + expander.cx.insert_macro(def); } for (name, extension) in user_exts.into_iter() { diff --git a/src/libsyntax/ext/tt/reexport.rs b/src/libsyntax/ext/tt/reexport.rs deleted file mode 100644 index 104f37872535c..0000000000000 --- a/src/libsyntax/ext/tt/reexport.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Defines the crate attribute syntax for macro re-export. - -use ast; -use attr::AttrMetaMethods; -use diagnostic::SpanHandler; - -/// Return a vector of the names of all macros re-exported from the crate. -pub fn gather(diag: &SpanHandler, krate: &ast::Crate) -> Vec { - let usage = "malformed macro_reexport attribute, expected \ - #![macro_reexport(ident, ident, ...)]"; - - let mut reexported: Vec = vec!(); - for attr in krate.attrs.iter() { - if !attr.check_name("macro_reexport") { - continue; - } - - match attr.meta_item_list() { - None => diag.span_err(attr.span, usage), - Some(list) => for mi in list.iter() { - match mi.node { - ast::MetaWord(ref word) - => reexported.push(word.to_string()), - _ => diag.span_err(mi.span, usage), - } - } - } - } - - reexported -} diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 774a9f61cf9af..b7bfd346d506b 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -111,6 +111,5 @@ pub mod ext { pub mod transcribe; pub mod macro_parser; pub mod macro_rules; - pub mod reexport; } } diff --git a/src/test/auxiliary/macro_reexport_2.rs b/src/test/auxiliary/macro_reexport_2.rs index f54e5e5c4e122..15d9f9cc9146d 100644 --- a/src/test/auxiliary/macro_reexport_2.rs +++ b/src/test/auxiliary/macro_reexport_2.rs @@ -10,7 +10,6 @@ #![crate_type = "dylib"] -#![macro_reexport(reexported)] - +#[macro_reexport(reexported)] #[macro_use] #[no_link] extern crate macro_reexport_1; diff --git a/src/test/compile-fail/macro-reexport-malformed-1.rs b/src/test/compile-fail/macro-reexport-malformed-1.rs index ea3074db124d6..b9f754b2778bc 100644 --- a/src/test/compile-fail/macro-reexport-malformed-1.rs +++ b/src/test/compile-fail/macro-reexport-malformed-1.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![macro_reexport] //~ ERROR malformed macro_reexport attribute +#[macro_reexport] //~ ERROR bad macro reexport +extern crate std; fn main() { } diff --git a/src/test/compile-fail/macro-reexport-malformed-2.rs b/src/test/compile-fail/macro-reexport-malformed-2.rs index 3daa089d2c677..9ced5be8479ba 100644 --- a/src/test/compile-fail/macro-reexport-malformed-2.rs +++ b/src/test/compile-fail/macro-reexport-malformed-2.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![macro_reexport="foo"] //~ ERROR malformed macro_reexport attribute +#[macro_reexport="foo"] //~ ERROR bad macro reexport +extern crate std; fn main() { } diff --git a/src/test/compile-fail/macro-reexport-malformed-3.rs b/src/test/compile-fail/macro-reexport-malformed-3.rs index b3c0bf95ce981..c8bd0a0509cdc 100644 --- a/src/test/compile-fail/macro-reexport-malformed-3.rs +++ b/src/test/compile-fail/macro-reexport-malformed-3.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![macro_reexport(foo="bar")] //~ ERROR malformed macro_reexport attribute +#[macro_reexport(foo="bar")] //~ ERROR bad macro reexport +extern crate std; fn main() { }