about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorKeegan McAllister <kmcallister@mozilla.com>2015-01-02 12:50:45 -0800
committerKeegan McAllister <kmcallister@mozilla.com>2015-01-05 18:21:13 -0800
commitaa69cbde8279cd90457454c3b3f40a36e8a79dff (patch)
tree6fadc77e821fb42ff743b355a5432180848e1a30 /src
parent0816255c80ee3f2a8870ee5e4379e3739d8ed72e (diff)
downloadrust-aa69cbde8279cd90457454c3b3f40a36e8a79dff.tar.gz
rust-aa69cbde8279cd90457454c3b3f40a36e8a79dff.zip
Allow selective macro import
Diffstat (limited to 'src')
-rw-r--r--src/librustc/metadata/creader.rs5
-rw-r--r--src/librustc/plugin/load.rs33
-rw-r--r--src/libsyntax/ast.rs1
-rw-r--r--src/libsyntax/ext/base.rs6
-rw-r--r--src/libsyntax/ext/expand.rs1
-rw-r--r--src/test/auxiliary/macro_reexport_2_no_use.rs15
-rw-r--r--src/test/auxiliary/two_macros.rs19
-rw-r--r--src/test/compile-fail/empty-macro-use.rs19
-rw-r--r--src/test/compile-fail/macro-reexport-not-locally-visible.rs20
-rw-r--r--src/test/compile-fail/macro-use-bad-args-1.rs15
-rw-r--r--src/test/compile-fail/macro-use-bad-args-2.rs15
-rw-r--r--src/test/compile-fail/macro-use-wrong-name.rs19
-rw-r--r--src/test/compile-fail/missing-macro-use.rs18
-rw-r--r--src/test/run-pass/macro-reexport-no-intermediate-use.rs20
-rw-r--r--src/test/run-pass/macro-use-all-and-none.rs21
-rw-r--r--src/test/run-pass/macro-use-all.rs20
-rw-r--r--src/test/run-pass/macro-use-both.rs20
-rw-r--r--src/test/run-pass/macro-use-one.rs19
-rw-r--r--src/test/run-pass/two-macro-use.rs21
19 files changed, 299 insertions, 8 deletions
diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs
index d83bd8b9223..171bfd74a81 100644
--- a/src/librustc/metadata/creader.rs
+++ b/src/librustc/metadata/creader.rs
@@ -552,7 +552,10 @@ impl<'a> PluginMetadata<'a> {
                     id: ast::DUMMY_NODE_ID,
                     span: span,
                     imported_from: imported_from,
-                    export: false,  // overridden in plugin/load.rs
+                    // overridden in plugin/load.rs
+                    export: false,
+                    use_locally: false,
+
                     body: body,
                 });
                 true
diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs
index 93c97f6caa6..3a9083828fc 100644
--- a/src/librustc/plugin/load.rs
+++ b/src/librustc/plugin/load.rs
@@ -87,8 +87,8 @@ 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 macro_selection = Some(HashSet::new());  // None => load all
         let mut reexport = HashSet::new();
         for attr in vi.attrs.iter() {
             let mut used = true;
@@ -98,7 +98,22 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
                                        #[macro_use], #[plugin], and/or #[no_link]");
                 }
                 "plugin" => load_registrar = true,
-                "macro_use" => load_macros = true,
+                "macro_use" => {
+                    let names = attr.meta_item_list();
+                    if names.is_none() {
+                        // no names => load all
+                        macro_selection = None;
+                    }
+                    if let (Some(sel), Some(names)) = (macro_selection.as_mut(), names) {
+                        for name in names.iter() {
+                            if let ast::MetaWord(ref name) = name.node {
+                                sel.insert(name.clone());
+                            } else {
+                                self.sess.span_err(name.span, "bad macro import");
+                            }
+                        }
+                    }
+                }
                 "macro_reexport" => {
                     let names = match attr.meta_item_list() {
                         Some(names) => names,
@@ -126,6 +141,11 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
         let mut macros = vec![];
         let mut registrar = None;
 
+        let load_macros = match macro_selection.as_ref() {
+            Some(sel) => sel.len() != 0 || reexport.len() != 0,
+            None => true,
+        };
+
         if load_macros || load_registrar {
             let pmd = self.reader.read_plugin_metadata(vi);
             if load_macros {
@@ -137,9 +157,12 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
         }
 
         for mut def in macros.into_iter() {
-            if reexport.contains(&token::get_ident(def.ident)) {
-                def.export = true;
-            }
+            let name = token::get_ident(def.ident);
+            def.use_locally = match macro_selection.as_ref() {
+                None => true,
+                Some(sel) => sel.contains(&name),
+            };
+            def.export = reexport.contains(&name);
             self.plugins.macros.push(def);
         }
 
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index e34060a73c1..0f90e31c17e 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1709,6 +1709,7 @@ pub struct MacroDef {
     pub span: Span,
     pub imported_from: Option<Ident>,
     pub export: bool,
+    pub use_locally: bool,
     pub body: Vec<TokenTree>,
 }
 
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 815159e94c8..91ae7396ea4 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -574,8 +574,10 @@ impl<'a> ExtCtxt<'a> {
         if def.export {
             self.exported_macros.push(def.clone());
         }
-        let ext = macro_rules::compile(self, &def);
-        self.syntax_env.insert(def.ident.name, ext);
+        if def.use_locally {
+            let ext = macro_rules::compile(self, &def);
+            self.syntax_env.insert(def.ident.name, ext);
+        }
     }
 
     /// Emit `msg` attached to `sp`, and stop compilation immediately.
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 6c2b0610fa0..d3f2e0ea095 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -636,6 +636,7 @@ pub fn expand_item_mac(it: P<ast::Item>,
                         span: it.span,
                         imported_from: None,
                         export: attr::contains_name(it.attrs.as_slice(), "macro_export"),
+                        use_locally: true,
                         body: tts,
                     };
                     fld.cx.insert_macro(def);
diff --git a/src/test/auxiliary/macro_reexport_2_no_use.rs b/src/test/auxiliary/macro_reexport_2_no_use.rs
new file mode 100644
index 00000000000..63142b0a699
--- /dev/null
+++ b/src/test/auxiliary/macro_reexport_2_no_use.rs
@@ -0,0 +1,15 @@
+// Copyright 2015 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "dylib"]
+
+#[macro_reexport(reexported)]
+#[no_link]
+extern crate macro_reexport_1;
diff --git a/src/test/auxiliary/two_macros.rs b/src/test/auxiliary/two_macros.rs
new file mode 100644
index 00000000000..39393b77f25
--- /dev/null
+++ b/src/test/auxiliary/two_macros.rs
@@ -0,0 +1,19 @@
+// Copyright 2015 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// force-host
+
+#![feature(macro_rules)]
+
+#[macro_export]
+macro_rules! macro_one { () => ("one") }
+
+#[macro_export]
+macro_rules! macro_two { () => ("two") }
diff --git a/src/test/compile-fail/empty-macro-use.rs b/src/test/compile-fail/empty-macro-use.rs
new file mode 100644
index 00000000000..fbf6287db94
--- /dev/null
+++ b/src/test/compile-fail/empty-macro-use.rs
@@ -0,0 +1,19 @@
+// Copyright 2015 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use()]
+extern crate two_macros;
+
+pub fn main() {
+    macro_two!();  //~ ERROR macro undefined
+}
diff --git a/src/test/compile-fail/macro-reexport-not-locally-visible.rs b/src/test/compile-fail/macro-reexport-not-locally-visible.rs
new file mode 100644
index 00000000000..c8e59f98d3c
--- /dev/null
+++ b/src/test/compile-fail/macro-reexport-not-locally-visible.rs
@@ -0,0 +1,20 @@
+// Copyright 2015 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:macro_reexport_1.rs
+// ignore-stage1
+
+#[macro_reexport(reexported)]
+#[no_link]
+extern crate macro_reexport_1;
+
+fn main() {
+    assert_eq!(reexported!(), 3u);  //~ ERROR macro undefined
+}
diff --git a/src/test/compile-fail/macro-use-bad-args-1.rs b/src/test/compile-fail/macro-use-bad-args-1.rs
new file mode 100644
index 00000000000..a73c4adb71f
--- /dev/null
+++ b/src/test/compile-fail/macro-use-bad-args-1.rs
@@ -0,0 +1,15 @@
+// Copyright 2015 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[macro_use(foo(bar))]  //~ ERROR bad macro import
+extern crate std;
+
+fn main() {
+}
diff --git a/src/test/compile-fail/macro-use-bad-args-2.rs b/src/test/compile-fail/macro-use-bad-args-2.rs
new file mode 100644
index 00000000000..31efe857605
--- /dev/null
+++ b/src/test/compile-fail/macro-use-bad-args-2.rs
@@ -0,0 +1,15 @@
+// Copyright 2015 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[macro_use(foo="bar")]  //~ ERROR bad macro import
+extern crate std;
+
+fn main() {
+}
diff --git a/src/test/compile-fail/macro-use-wrong-name.rs b/src/test/compile-fail/macro-use-wrong-name.rs
new file mode 100644
index 00000000000..4e0486f0db7
--- /dev/null
+++ b/src/test/compile-fail/macro-use-wrong-name.rs
@@ -0,0 +1,19 @@
+// Copyright 2015 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use(macro_one)]
+extern crate two_macros;
+
+pub fn main() {
+    macro_two!();  //~ ERROR macro undefined
+}
diff --git a/src/test/compile-fail/missing-macro-use.rs b/src/test/compile-fail/missing-macro-use.rs
new file mode 100644
index 00000000000..0153d71fb26
--- /dev/null
+++ b/src/test/compile-fail/missing-macro-use.rs
@@ -0,0 +1,18 @@
+// Copyright 2015 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+extern crate two_macros;
+
+pub fn main() {
+    macro_two!();  //~ ERROR macro undefined
+}
diff --git a/src/test/run-pass/macro-reexport-no-intermediate-use.rs b/src/test/run-pass/macro-reexport-no-intermediate-use.rs
new file mode 100644
index 00000000000..77ef9421273
--- /dev/null
+++ b/src/test/run-pass/macro-reexport-no-intermediate-use.rs
@@ -0,0 +1,20 @@
+// Copyright 2015 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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_no_use.rs
+// ignore-stage1
+
+#[macro_use] #[no_link]
+extern crate macro_reexport_2_no_use;
+
+fn main() {
+    assert_eq!(reexported!(), 3u);
+}
diff --git a/src/test/run-pass/macro-use-all-and-none.rs b/src/test/run-pass/macro-use-all-and-none.rs
new file mode 100644
index 00000000000..b46910290a8
--- /dev/null
+++ b/src/test/run-pass/macro-use-all-and-none.rs
@@ -0,0 +1,21 @@
+// Copyright 2015 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use]
+#[macro_use()]
+extern crate two_macros;
+
+pub fn main() {
+    macro_one!();
+    macro_two!();
+}
diff --git a/src/test/run-pass/macro-use-all.rs b/src/test/run-pass/macro-use-all.rs
new file mode 100644
index 00000000000..cf72d2c6230
--- /dev/null
+++ b/src/test/run-pass/macro-use-all.rs
@@ -0,0 +1,20 @@
+// Copyright 2015 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use]
+extern crate two_macros;
+
+pub fn main() {
+    macro_one!();
+    macro_two!();
+}
diff --git a/src/test/run-pass/macro-use-both.rs b/src/test/run-pass/macro-use-both.rs
new file mode 100644
index 00000000000..4b0814bef04
--- /dev/null
+++ b/src/test/run-pass/macro-use-both.rs
@@ -0,0 +1,20 @@
+// Copyright 2015 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use(macro_one, macro_two)]
+extern crate two_macros;
+
+pub fn main() {
+    macro_one!();
+    macro_two!();
+}
diff --git a/src/test/run-pass/macro-use-one.rs b/src/test/run-pass/macro-use-one.rs
new file mode 100644
index 00000000000..7911fec94da
--- /dev/null
+++ b/src/test/run-pass/macro-use-one.rs
@@ -0,0 +1,19 @@
+// Copyright 2015 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use(macro_two)]
+extern crate two_macros;
+
+pub fn main() {
+    macro_two!();
+}
diff --git a/src/test/run-pass/two-macro-use.rs b/src/test/run-pass/two-macro-use.rs
new file mode 100644
index 00000000000..51c0b75e8fb
--- /dev/null
+++ b/src/test/run-pass/two-macro-use.rs
@@ -0,0 +1,21 @@
+// Copyright 2015 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use(macro_one)]
+#[macro_use(macro_two)]
+extern crate two_macros;
+
+pub fn main() {
+    macro_one!();
+    macro_two!();
+}