@@ -51,6 +51,7 @@ struct TestCtxt<'a> {
5151 ext_cx : ExtCtxt < ' a > ,
5252 testfns : Vec < Test > ,
5353 reexport_mod_ident : ast:: Ident ,
54+ reexport_test_harness_main : Option < InternedString > ,
5455 is_test_crate : bool ,
5556 config : ast:: CrateConfig ,
5657}
@@ -64,8 +65,16 @@ pub fn modify_for_testing(sess: &Session,
6465 // command line options.
6566 let should_test = attr:: contains_name ( krate. config . as_slice ( ) , "test" ) ;
6667
68+ // Check for #[reexport_test_harness_main = "some_name"] which
69+ // creates a `use some_name = __test::main;`. This needs to be
70+ // unconditional, so that the attribute is still marked as used in
71+ // non-test builds.
72+ let reexport_test_harness_main =
73+ attr:: first_attr_value_str_by_name ( krate. attrs . as_slice ( ) ,
74+ "reexport_test_harness_main" ) ;
75+
6776 if should_test {
68- generate_test_harness ( sess, krate)
77+ generate_test_harness ( sess, reexport_test_harness_main , krate)
6978 } else {
7079 strip_test_functions ( krate)
7180 }
@@ -79,14 +88,17 @@ struct TestHarnessGenerator<'a> {
7988
8089impl < ' a > fold:: Folder for TestHarnessGenerator < ' a > {
8190 fn fold_crate ( & mut self , c : ast:: Crate ) -> ast:: Crate {
82- let folded = fold:: noop_fold_crate ( c, self ) ;
91+ let mut folded = fold:: noop_fold_crate ( c, self ) ;
8392
8493 // Add a special __test module to the crate that will contain code
8594 // generated for the test harness
86- ast:: Crate {
87- module : add_test_module ( & self . cx , & folded. module ) ,
88- .. folded
95+ let ( mod_, reexport) = mk_test_module ( & self . cx , & self . cx . reexport_test_harness_main ) ;
96+ folded. module . items . push ( mod_) ;
97+ match reexport {
98+ Some ( re) => folded. module . view_items . push ( re) ,
99+ None => { }
89100 }
101+ folded
90102 }
91103
92104 fn fold_item ( & mut self , i : Gc < ast:: Item > ) -> SmallVector < Gc < ast:: Item > > {
@@ -196,7 +208,9 @@ fn mk_reexport_mod(cx: &mut TestCtxt, tests: Vec<ast::Ident>,
196208 }
197209}
198210
199- fn generate_test_harness ( sess : & Session , krate : ast:: Crate ) -> ast:: Crate {
211+ fn generate_test_harness ( sess : & Session ,
212+ reexport_test_harness_main : Option < InternedString > ,
213+ krate : ast:: Crate ) -> ast:: Crate {
200214 let mut cx: TestCtxt = TestCtxt {
201215 sess : sess,
202216 ext_cx : ExtCtxt :: new ( & sess. parse_sess , sess. opts . cfg . clone ( ) ,
@@ -207,6 +221,7 @@ fn generate_test_harness(sess: &Session, krate: ast::Crate) -> ast::Crate {
207221 path : Vec :: new ( ) ,
208222 testfns : Vec :: new ( ) ,
209223 reexport_mod_ident : token:: gensym_ident ( "__test_reexports" ) ,
224+ reexport_test_harness_main : reexport_test_harness_main,
210225 is_test_crate : is_test_crate ( & krate) ,
211226 config : krate. config . clone ( ) ,
212227 } ;
@@ -314,14 +329,6 @@ fn should_fail(i: Gc<ast::Item>) -> bool {
314329 attr:: contains_name ( i. attrs . as_slice ( ) , "should_fail" )
315330}
316331
317- fn add_test_module ( cx : & TestCtxt , m : & ast:: Mod ) -> ast:: Mod {
318- let testmod = mk_test_module ( cx) ;
319- ast:: Mod {
320- items : m. items . clone ( ) . append_one ( testmod) ,
321- ..( * m) . clone ( )
322- }
323- }
324-
325332/*
326333
327334We're going to be building a module that looks more or less like:
@@ -359,7 +366,8 @@ fn mk_std(cx: &TestCtxt) -> ast::ViewItem {
359366 }
360367}
361368
362- fn mk_test_module ( cx : & TestCtxt ) -> Gc < ast:: Item > {
369+ fn mk_test_module ( cx : & TestCtxt , reexport_test_harness_main : & Option < InternedString > )
370+ -> ( Gc < ast:: Item > , Option < ast:: ViewItem > ) {
363371 // Link to test crate
364372 let view_items = vec ! ( mk_std( cx) ) ;
365373
@@ -383,18 +391,35 @@ fn mk_test_module(cx: &TestCtxt) -> Gc<ast::Item> {
383391 } ;
384392 let item_ = ast:: ItemMod ( testmod) ;
385393
394+ let mod_ident = token:: gensym_ident ( "__test" ) ;
386395 let item = ast:: Item {
387- ident : token :: gensym_ident ( "__test" ) ,
396+ ident : mod_ident ,
388397 attrs : Vec :: new ( ) ,
389398 id : ast:: DUMMY_NODE_ID ,
390399 node : item_,
391400 vis : ast:: Public ,
392401 span : DUMMY_SP ,
393- } ;
402+ } ;
403+ let reexport = reexport_test_harness_main. as_ref ( ) . map ( |s| {
404+ // building `use <ident> = __test::main`
405+ let reexport_ident = token:: str_to_ident ( s. get ( ) ) ;
406+
407+ let use_path =
408+ nospan ( ast:: ViewPathSimple ( reexport_ident,
409+ path_node ( vec ! [ mod_ident, token:: str_to_ident( "main" ) ] ) ,
410+ ast:: DUMMY_NODE_ID ) ) ;
411+
412+ ast:: ViewItem {
413+ node : ast:: ViewItemUse ( box ( GC ) use_path) ,
414+ attrs : vec ! [ ] ,
415+ vis : ast:: Inherited ,
416+ span : DUMMY_SP
417+ }
418+ } ) ;
394419
395420 debug ! ( "Synthetic test module:\n {}\n " , pprust:: item_to_string( & item) ) ;
396421
397- box ( GC ) item
422+ ( box ( GC ) item, reexport )
398423}
399424
400425fn nospan < T > ( t : T ) -> codemap:: Spanned < T > {
0 commit comments