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.)
This commit is contained in:
bors 2013-06-26 07:32:14 -07:00
commit 4e5b4807a5
3 changed files with 82 additions and 1 deletions

View File

@ -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", ||

View File

@ -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!())
}

View File

@ -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!())
}