From 538288176a22b4d3755df085783f84d476386019 Mon Sep 17 00:00:00 2001 From: Keegan McAllister Date: Mon, 15 Sep 2014 19:02:14 -0700 Subject: [PATCH] Implement macro re-export Fixes #17103. --- src/librustc_driver/driver.rs | 2 + src/libsyntax/ext/expand.rs | 9 +++- src/libsyntax/ext/tt/reexport.rs | 41 +++++++++++++++++++ src/libsyntax/lib.rs | 1 + src/test/auxiliary/macro_reexport_1.rs | 17 ++++++++ src/test/auxiliary/macro_reexport_2.rs | 17 ++++++++ .../macro-reexport-malformed-1.rs | 13 ++++++ .../macro-reexport-malformed-2.rs | 13 ++++++ .../macro-reexport-malformed-3.rs | 13 ++++++ src/test/run-pass/macro-reexport.rs | 22 ++++++++++ 10 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 src/libsyntax/ext/tt/reexport.rs create mode 100644 src/test/auxiliary/macro_reexport_1.rs create mode 100644 src/test/auxiliary/macro_reexport_2.rs create mode 100644 src/test/compile-fail/macro-reexport-malformed-1.rs create mode 100644 src/test/compile-fail/macro-reexport-malformed-2.rs create mode 100644 src/test/compile-fail/macro-reexport-malformed-3.rs create mode 100644 src/test/run-pass/macro-reexport.rs diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 0d9736a82736..5056ada6a8c1 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -275,6 +275,8 @@ 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/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 325d8aa594a3..d4be46d025ec 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -616,7 +616,12 @@ pub fn expand_item_mac(it: P, imported_from, tts); fld.cx.syntax_env.insert(intern(name.as_slice()), ext); - if attr::contains_name(it.attrs.as_slice(), "macro_export") { + + if match imported_from { + None => attr::contains_name(it.attrs.as_slice(), "macro_export"), + Some(_) => fld.cx.ecfg.reexported_macros.iter() + .any(|e| e.as_slice() == name.as_slice()), + } { fld.cx.exported_macros.push(it); } @@ -1156,6 +1161,7 @@ pub struct ExpansionConfig { pub deriving_hash_type_parameter: bool, pub enable_quotes: bool, pub recursion_limit: uint, + pub reexported_macros: Vec, } impl ExpansionConfig { @@ -1165,6 +1171,7 @@ impl ExpansionConfig { deriving_hash_type_parameter: false, enable_quotes: false, recursion_limit: 64, + reexported_macros: vec![], } } } diff --git a/src/libsyntax/ext/tt/reexport.rs b/src/libsyntax/ext/tt/reexport.rs new file mode 100644 index 000000000000..104f37872535 --- /dev/null +++ b/src/libsyntax/ext/tt/reexport.rs @@ -0,0 +1,41 @@ +// 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 18cdb3fc6478..0503d88cca20 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -104,5 +104,6 @@ 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_1.rs b/src/test/auxiliary/macro_reexport_1.rs new file mode 100644 index 000000000000..bd00b33f2801 --- /dev/null +++ b/src/test/auxiliary/macro_reexport_1.rs @@ -0,0 +1,17 @@ +// 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. + +#![crate_type = "dylib"] +#![feature(macro_rules)] + +#[macro_export] +macro_rules! reexported { + () => ( 3u ) +} diff --git a/src/test/auxiliary/macro_reexport_2.rs b/src/test/auxiliary/macro_reexport_2.rs new file mode 100644 index 000000000000..3b68d47c5586 --- /dev/null +++ b/src/test/auxiliary/macro_reexport_2.rs @@ -0,0 +1,17 @@ +// 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. + +#![crate_type = "dylib"] +#![feature(phase)] + +#![macro_reexport(reexported)] + +#[phase(plugin)] +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 new file mode 100644 index 000000000000..ea3074db124d --- /dev/null +++ b/src/test/compile-fail/macro-reexport-malformed-1.rs @@ -0,0 +1,13 @@ +// 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. + +#![macro_reexport] //~ ERROR malformed macro_reexport attribute + +fn main() { } diff --git a/src/test/compile-fail/macro-reexport-malformed-2.rs b/src/test/compile-fail/macro-reexport-malformed-2.rs new file mode 100644 index 000000000000..3daa089d2c67 --- /dev/null +++ b/src/test/compile-fail/macro-reexport-malformed-2.rs @@ -0,0 +1,13 @@ +// 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. + +#![macro_reexport="foo"] //~ ERROR malformed macro_reexport attribute + +fn main() { } diff --git a/src/test/compile-fail/macro-reexport-malformed-3.rs b/src/test/compile-fail/macro-reexport-malformed-3.rs new file mode 100644 index 000000000000..b3c0bf95ce98 --- /dev/null +++ b/src/test/compile-fail/macro-reexport-malformed-3.rs @@ -0,0 +1,13 @@ +// 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. + +#![macro_reexport(foo="bar")] //~ ERROR malformed macro_reexport attribute + +fn main() { } diff --git a/src/test/run-pass/macro-reexport.rs b/src/test/run-pass/macro-reexport.rs new file mode 100644 index 000000000000..bc3632e76ba4 --- /dev/null +++ b/src/test/run-pass/macro-reexport.rs @@ -0,0 +1,22 @@ +// 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. + +// aux-build:macro_reexport_1.rs +// aux-build:macro_reexport_2.rs +// ignore-stage1 + +#![feature(phase)] + +#[phase(plugin)] +extern crate macro_reexport_2; + +fn main() { + assert_eq!(reexported!(), 3u); +}