8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- use ast:: { blk_, attribute_, attr_outer, meta_word} ;
12
- use ast:: { crate , expr_, expr_mac, mac_invoc_tt} ;
11
+ use ast:: { blk_, crate , expr_, expr_mac, mac_invoc_tt} ;
13
12
use ast:: { item_mac, stmt_, stmt_mac, stmt_expr, stmt_semi} ;
14
13
use ast:: { illegal_ctxt} ;
15
14
use ast;
16
15
use ast_util:: { new_rename, new_mark, resolve} ;
17
16
use attr;
18
17
use codemap;
19
- use codemap:: { span, ExpnInfo , NameAndSpan , spanned } ;
18
+ use codemap:: { span, ExpnInfo , NameAndSpan } ;
20
19
use ext:: base:: * ;
21
20
use fold:: * ;
22
21
use parse;
@@ -452,9 +451,11 @@ pub fn new_span(cx: @ExtCtxt, sp: span) -> span {
452
451
// the default compilation environment. It would be much nicer to use
453
452
// a mechanism like syntax_quote to ensure hygiene.
454
453
455
- pub fn core_macros ( ) -> @str {
454
+ pub fn std_macros ( ) -> @str {
456
455
return
457
- @"pub mod macros {
456
+ @"pub mod __std_macros {
457
+ #[ macro_escape] ;
458
+
458
459
macro_rules! ignore ( ( $( $x: tt) * ) => ( ( ) ) )
459
460
460
461
macro_rules! error (
@@ -484,7 +485,9 @@ pub fn core_macros() -> @str {
484
485
)
485
486
)
486
487
487
- macro_rules! debug (
488
+ // conditionally define debug!, but keep it type checking even
489
+ // in non-debug builds.
490
+ macro_rules! __debug (
488
491
( $arg: expr) => (
489
492
__log( 4u32 , fmt!( \"%?\" , $arg ) )
490
493
) ;
@@ -493,6 +496,22 @@ pub fn core_macros() -> @str {
493
496
)
494
497
)
495
498
499
+ #[ cfg( debug) ]
500
+ #[ macro_escape]
501
+ mod debug_macro {
502
+ macro_rules! debug ( ( $( $arg: expr) ,* ) => {
503
+ __debug!( $( $arg) ,* )
504
+ } )
505
+ }
506
+
507
+ #[ cfg( not( debug) ) ]
508
+ #[ macro_escape]
509
+ mod debug_macro {
510
+ macro_rules! debug ( ( $( $arg: expr) ,* ) => {
511
+ if false { __debug!( $( $arg) ,* ) }
512
+ } )
513
+ }
514
+
496
515
macro_rules! fail(
497
516
( ) => (
498
517
fail!( \" explicit failure\" )
@@ -668,6 +687,35 @@ pub fn core_macros() -> @str {
668
687
} ";
669
688
}
670
689
690
+ // add a bunch of macros as though they were placed at the head of the
691
+ // program (ick). This should run before cfg stripping.
692
+ pub fn inject_std_macros(parse_sess: @mut parse::ParseSess,
693
+ cfg: ast::crate_cfg, c: &crate) -> @crate {
694
+ let sm = match parse_item_from_source_str(@" <std-macros>",
695
+ std_macros(),
696
+ copy cfg,
697
+ ~[],
698
+ parse_sess) {
699
+ Some(item) => item,
700
+ None => fail!(" expected core macros to parse correctly")
701
+ } ;
702
+
703
+ let injecter = @AstFoldFns {
704
+ fold_mod : |modd, _| {
705
+ // just inject the std macros at the start of the first
706
+ // module in the crate (i.e the crate file itself.)
707
+ let items = vec:: append ( ~[ sm] , modd. items ) ;
708
+ ast:: _mod {
709
+ items : items,
710
+ // FIXME #2543: Bad copy.
711
+ .. copy * modd
712
+ }
713
+ } ,
714
+ .. * default_ast_fold ( )
715
+ } ;
716
+ @make_fold ( injecter) . fold_crate ( c)
717
+ }
718
+
671
719
pub fn expand_crate( parse_sess : @mut parse:: ParseSess ,
672
720
cfg : ast:: crate_cfg , c: & crate ) -> @crate {
673
721
// adding *another* layer of indirection here so that the block
@@ -692,33 +740,6 @@ pub fn expand_crate(parse_sess: @mut parse::ParseSess,
692
740
new_span : |a| new_span ( cx, a) ,
693
741
.. * afp} ;
694
742
let f = make_fold ( f_pre) ;
695
- // add a bunch of macros as though they were placed at the
696
- // head of the program (ick).
697
- let attrs = ~[
698
- spanned {
699
- span: codemap::dummy_sp(),
700
- node: attribute_ {
701
- style: attr_outer,
702
- value: @spanned {
703
- node: meta_word(@" macro_escape") ,
704
- span: codemap:: dummy_sp( ) ,
705
- } ,
706
- is_sugared_doc: false ,
707
- }
708
- }
709
- ] ;
710
-
711
- let cm = match parse_item_from_source_str ( @"<core-macros>",
712
- core_macros(),
713
- copy cfg,
714
- attrs,
715
- parse_sess) {
716
- Some(item) => item,
717
- None => cx.bug(" expected core macros to parse correctly")
718
- } ;
719
- // This is run for its side-effects on the expander env,
720
- // as it registers all the core macros as expanders.
721
- f. fold_item ( cm) ;
722
743
723
744
@f. fold_crate ( c)
724
745
}
@@ -789,6 +810,8 @@ mod test {
789
810
@"<test>",
790
811
src,
791
812
~[],sess);
813
+ let crate_ast = inject_std_macros(sess, ~[], crate_ast);
814
+ // don't bother with striping, doesn't affect fail!.
792
815
expand_crate(sess,~[],crate_ast);
793
816
}
794
817
@@ -836,20 +859,14 @@ mod test {
836
859
expand_crate(sess,~[],crate_ast);
837
860
}
838
861
839
- #[ test] fn core_macros_must_parse ( ) {
840
- let src = @"
841
- pub mod macros {
842
- macro_rules! ignore (($($x:tt)*) => (()))
843
-
844
- macro_rules! error ( ($( $arg:expr ),+) => (
845
- log(::core::error, fmt!( $($arg),+ )) ))
846
- }" ;
862
+ #[test] fn std_macros_must_parse () {
863
+ let src = super::std_macros();
847
864
let sess = parse::new_parse_sess(None);
848
865
let cfg = ~[];
849
866
let item_ast = parse::parse_item_from_source_str(
850
867
@" <test>",
851
868
src,
852
- cfg, ~[ make_dummy_attr ( @ "macro_escape" ) ] , sess) ;
869
+ cfg,~[],sess);
853
870
match item_ast {
854
871
Some(_) => (), // success
855
872
None => fail!(" expected this to parse")
0 commit comments