diff options
| author | bors <bors@rust-lang.org> | 2013-07-16 11:19:20 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-07-16 11:19:20 -0700 |
| commit | ad212ecee47e8f9126c9fa4ea1679435136e854e (patch) | |
| tree | f17032be22f93517c8a682486eece167ea313fb5 /src/libsyntax | |
| parent | a317584e4f7643c862e94138eb210ce154974d0e (diff) | |
| parent | 4797dd4087104246b5d5c2d3edf1623acfbc06e5 (diff) | |
| download | rust-ad212ecee47e8f9126c9fa4ea1679435136e854e.tar.gz rust-ad212ecee47e8f9126c9fa4ea1679435136e854e.zip | |
auto merge of #7822 : huonw/rust/cond-debug, r=graydon
As per @pcwalton's request, `debug!(..)` is only activated when the `debug` cfg is set; that is, for `RUST_LOG=some_module=4 ./some_program` to work, it needs to be compiled with `rustc --cfg debug some_program.rs`. (Although, there is the sneaky `__debug!(..)` macro that is always active, if you *really* need it.)
It functions by making `debug!` expand to `if false { __debug!(..) }` (expanding to an `if` like this is required to make sure `debug!` statements are typechecked and to avoid unused variable warnings), and adjusting trans to skip the pointless branches in `if true ...` and `if false ...`.
The conditional expansion change also required moving the inject-std-macros step into a new pass, and makes it actually insert them at the top of the crate; this means that the cfg stripping traverses over the macros and so filters out the unused ones.
This appears to takes an unoptimised build of `librustc` from 65s to 59s; and the full bootstrap from 18m41s to 18m26s on my computer (with general background use).
`./configure --enable-debug` will enable `debug!` statements in the bootstrap build.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 102 |
1 files changed, 60 insertions, 42 deletions
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index b45cde6a8e3..c421da06795 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -8,15 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast::{blk_, attribute_, attr_outer, meta_word}; -use ast::{crate, expr_, expr_mac, mac_invoc_tt}; +use ast::{blk_, crate, expr_, expr_mac, mac_invoc_tt}; use ast::{item_mac, stmt_, stmt_mac, stmt_expr, stmt_semi}; use ast::{illegal_ctxt}; use ast; use ast_util::{new_rename, new_mark, resolve}; use attr; use codemap; -use codemap::{span, ExpnInfo, NameAndSpan, spanned}; +use codemap::{span, ExpnInfo, NameAndSpan}; use ext::base::*; use fold::*; use parse; @@ -452,9 +451,12 @@ pub fn new_span(cx: @ExtCtxt, sp: span) -> span { // the default compilation environment. It would be much nicer to use // a mechanism like syntax_quote to ensure hygiene. -pub fn core_macros() -> @str { +pub fn std_macros() -> @str { return -@"pub mod macros { +@"mod __std_macros { + #[macro_escape]; + #[doc(hidden)]; + macro_rules! ignore (($($x:tt)*) => (())) macro_rules! error ( @@ -484,7 +486,9 @@ pub fn core_macros() -> @str { ) ) - macro_rules! debug ( + // conditionally define debug!, but keep it type checking even + // in non-debug builds. + macro_rules! __debug ( ($arg:expr) => ( __log(4u32, fmt!( \"%?\", $arg )) ); @@ -493,6 +497,22 @@ pub fn core_macros() -> @str { ) ) + #[cfg(debug)] + #[macro_escape] + mod debug_macro { + macro_rules! debug (($($arg:expr),*) => { + __debug!($($arg),*) + }) + } + + #[cfg(not(debug))] + #[macro_escape] + mod debug_macro { + macro_rules! debug (($($arg:expr),*) => { + if false { __debug!($($arg),*) } + }) + } + macro_rules! fail( () => ( fail!(\"explicit failure\") @@ -668,6 +688,35 @@ pub fn core_macros() -> @str { }"; } +// add a bunch of macros as though they were placed at the head of the +// program (ick). This should run before cfg stripping. +pub fn inject_std_macros(parse_sess: @mut parse::ParseSess, + cfg: ast::crate_cfg, c: &crate) -> @crate { + let sm = match parse_item_from_source_str(@"<std-macros>", + std_macros(), + copy cfg, + ~[], + parse_sess) { + Some(item) => item, + None => fail!("expected core macros to parse correctly") + }; + + let injecter = @AstFoldFns { + fold_mod: |modd, _| { + // just inject the std macros at the start of the first + // module in the crate (i.e the crate file itself.) + let items = vec::append(~[sm], modd.items); + ast::_mod { + items: items, + // FIXME #2543: Bad copy. + .. copy *modd + } + }, + .. *default_ast_fold() + }; + @make_fold(injecter).fold_crate(c) +} + pub fn expand_crate(parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg, c: &crate) -> @crate { // adding *another* layer of indirection here so that the block @@ -692,33 +741,6 @@ pub fn expand_crate(parse_sess: @mut parse::ParseSess, new_span: |a| new_span(cx, a), .. *afp}; let f = make_fold(f_pre); - // add a bunch of macros as though they were placed at the - // head of the program (ick). - let attrs = ~[ - spanned { - span: codemap::dummy_sp(), - node: attribute_ { - style: attr_outer, - value: @spanned { - node: meta_word(@"macro_escape"), - span: codemap::dummy_sp(), - }, - is_sugared_doc: false, - } - } - ]; - - let cm = match parse_item_from_source_str(@"<core-macros>", - core_macros(), - copy cfg, - attrs, - parse_sess) { - Some(item) => item, - None => cx.bug("expected core macros to parse correctly") - }; - // This is run for its side-effects on the expander env, - // as it registers all the core macros as expanders. - f.fold_item(cm); @f.fold_crate(c) } @@ -789,6 +811,8 @@ mod test { @"<test>", src, ~[],sess); + let crate_ast = inject_std_macros(sess, ~[], crate_ast); + // don't bother with striping, doesn't affect fail!. expand_crate(sess,~[],crate_ast); } @@ -836,20 +860,14 @@ mod test { expand_crate(sess,~[],crate_ast); } - #[test] fn core_macros_must_parse () { - let src = @" - pub mod macros { - macro_rules! ignore (($($x:tt)*) => (())) - - macro_rules! error ( ($( $arg:expr ),+) => ( - log(::core::error, fmt!( $($arg),+ )) )) -}"; + #[test] fn std_macros_must_parse () { + let src = super::std_macros(); let sess = parse::new_parse_sess(None); let cfg = ~[]; let item_ast = parse::parse_item_from_source_str( @"<test>", src, - cfg,~[make_dummy_attr (@"macro_escape")],sess); + cfg,~[],sess); match item_ast { Some(_) => (), // success None => fail!("expected this to parse") |
