about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-06-26 07:32:14 -0700
committerbors <bors@rust-lang.org>2013-06-26 07:32:14 -0700
commit4e5b4807a5b620627cf6e782524fbe6fc1463c2d (patch)
treef959815068602829c513a55c32093e7cd8bb8b27
parenta30ab764e10232d8e9c1f9282c33b65ca9ef7daf (diff)
parent73e3dbf9c082659d9f7aa9281ef4af4080ed019d (diff)
downloadrust-4e5b4807a5b620627cf6e782524fbe6fc1463c2d.tar.gz
rust-4e5b4807a5b620627cf6e782524fbe6fc1463c2d.zip
auto merge of #7297 : huonw/rust/strip-expand-strip, r=cmr
This allows macros to both be conditionally defined, and expand
to items with #[cfg]'s.

This seems to have a performance improvement, e.g. for `std`:

```
# Before 
time: 1.660 s   expansion
time: 0.125 s   configuration
# After
time: 0.080 s   configuration 1
time: 1.127 s   expansion
time: 0.132 s   configuration 2
```

And for `extra`:

```
# Before
time: 0.593 s   expansion
time: 0.062 s   configuration
# After
time: 0.047 s   configuration 1
time: 0.147 s   expansion
time: 0.058 s   configuration 2
```

(This seems a little peculiar, but it is possibly because the expansion AST traversal is very slow, so removing as much as possible as early as possible has big benefits.)
-rw-r--r--src/librustc/driver/driver.rs13
-rw-r--r--src/test/run-pass/cfg-macros-foo.rs35
-rw-r--r--src/test/run-pass/cfg-macros-notfoo.rs35
3 files changed, 82 insertions, 1 deletions
diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index fbb273450df..f6b05711c13 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -188,11 +188,22 @@ pub fn compile_rest(sess: Session,
         *sess.building_library = session::building_library(
             sess.opts.crate_type, crate_opt.unwrap(), sess.opts.test);
 
+        // strip before expansion to allow macros to depend on
+        // configuration variables e.g/ in
+        //
+        //   #[macro_escape] #[cfg(foo)]
+        //   mod bar { macro_rules! baz!(() => {{}}) }
+        //
+        // baz! should not use this definition unless foo is enabled.
+        crate_opt = Some(time(time_passes, ~"configuration 1", ||
+                     front::config::strip_unconfigured_items(crate_opt.unwrap())));
+
         crate_opt = Some(time(time_passes, ~"expansion", ||
                      syntax::ext::expand::expand_crate(sess.parse_sess, copy cfg,
                                                        crate_opt.unwrap())));
 
-        crate_opt = Some(time(time_passes, ~"configuration", ||
+        // strip again, in case expansion added anything with a #[cfg].
+        crate_opt = Some(time(time_passes, ~"configuration 2", ||
                      front::config::strip_unconfigured_items(crate_opt.unwrap())));
 
         crate_opt = Some(time(time_passes, ~"maybe building test harness", ||
diff --git a/src/test/run-pass/cfg-macros-foo.rs b/src/test/run-pass/cfg-macros-foo.rs
new file mode 100644
index 00000000000..8dfb7190c21
--- /dev/null
+++ b/src/test/run-pass/cfg-macros-foo.rs
@@ -0,0 +1,35 @@
+// Copyright 2013 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.
+
+// xfail-fast compile-flags directive doesn't work for check-fast
+// compile-flags: --cfg foo
+
+// check that cfg correctly chooses between the macro impls (see also
+// cfg-macros-notfoo.rs)
+
+#[cfg(foo)]
+#[macro_escape]
+mod foo {
+    macro_rules! bar {
+        () => { true }
+    }
+}
+
+#[cfg(not(foo))]
+#[macro_escape]
+mod foo {
+    macro_rules! bar {
+        () => { false }
+    }
+}
+
+fn main() {
+    assert!(bar!())
+}
diff --git a/src/test/run-pass/cfg-macros-notfoo.rs b/src/test/run-pass/cfg-macros-notfoo.rs
new file mode 100644
index 00000000000..8ede6eff2dd
--- /dev/null
+++ b/src/test/run-pass/cfg-macros-notfoo.rs
@@ -0,0 +1,35 @@
+// Copyright 2013 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.
+
+// xfail-fast compile-flags directive doesn't work for check-fast
+// compile-flags:
+
+// check that cfg correctly chooses between the macro impls (see also
+// cfg-macros-foo.rs)
+
+#[cfg(foo)]
+#[macro_escape]
+mod foo {
+    macro_rules! bar {
+        () => { true }
+    }
+}
+
+#[cfg(not(foo))]
+#[macro_escape]
+mod foo {
+    macro_rules! bar {
+        () => { false }
+    }
+}
+
+fn main() {
+    assert!(!bar!())
+}