@@ -206,7 +206,7 @@ fn generate_test_harness(sess: &Session, krate: ast::Crate) -> ast::Crate {
206
206
} ) ,
207
207
path : Vec :: new ( ) ,
208
208
testfns : Vec :: new ( ) ,
209
- reexport_mod_ident : token:: str_to_ident ( "__test_reexports" ) ,
209
+ reexport_mod_ident : token:: gensym_ident ( "__test_reexports" ) ,
210
210
is_test_crate : is_test_crate ( & krate) ,
211
211
config : krate. config . clone ( ) ,
212
212
} ;
@@ -384,7 +384,7 @@ fn mk_test_module(cx: &TestCtxt) -> Gc<ast::Item> {
384
384
let item_ = ast:: ItemMod ( testmod) ;
385
385
386
386
let item = ast:: Item {
387
- ident : token:: str_to_ident ( "__test" ) ,
387
+ ident : token:: gensym_ident ( "__test" ) ,
388
388
attrs : Vec :: new ( ) ,
389
389
id : ast:: DUMMY_NODE_ID ,
390
390
node : item_,
@@ -417,11 +417,27 @@ fn mk_tests(cx: &TestCtxt) -> Gc<ast::Item> {
417
417
// The vector of test_descs for this crate
418
418
let test_descs = mk_test_descs ( cx) ;
419
419
420
- ( quote_item ! ( & cx. ext_cx,
421
- pub static TESTS : & ' static [ self :: test:: TestDescAndFn ] =
422
- $test_descs
423
- ;
424
- ) ) . unwrap ( )
420
+ // FIXME #15962: should be using quote_item, but that stringifies
421
+ // __test_reexports, causing it to be reinterned, losing the
422
+ // gensym information.
423
+ let sp = DUMMY_SP ;
424
+ let ecx = & cx. ext_cx ;
425
+ let struct_type = ecx. ty_path ( ecx. path ( sp, vec ! [ ecx. ident_of( "self" ) ,
426
+ ecx. ident_of( "test" ) ,
427
+ ecx. ident_of( "TestDescAndFn" ) ] ) ,
428
+ None ) ;
429
+ let static_lt = ecx. lifetime ( sp, token:: special_idents:: static_lifetime. name ) ;
430
+ // &'static [self::test::TestDescAndFn]
431
+ let static_type = ecx. ty_rptr ( sp,
432
+ ecx. ty ( sp, ast:: TyVec ( struct_type) ) ,
433
+ Some ( static_lt) ,
434
+ ast:: MutImmutable ) ;
435
+ // static TESTS: $static_type = &[...];
436
+ ecx. item_static ( sp,
437
+ ecx. ident_of ( "TESTS" ) ,
438
+ static_type,
439
+ ast:: MutImmutable ,
440
+ test_descs)
425
441
}
426
442
427
443
fn is_test_crate ( krate : & ast:: Crate ) -> bool {
@@ -448,59 +464,58 @@ fn mk_test_descs(cx: &TestCtxt) -> Gc<ast::Expr> {
448
464
}
449
465
450
466
fn mk_test_desc_and_fn_rec ( cx : & TestCtxt , test : & Test ) -> Gc < ast:: Expr > {
467
+ // FIXME #15962: should be using quote_expr, but that stringifies
468
+ // __test_reexports, causing it to be reinterned, losing the
469
+ // gensym information.
470
+
451
471
let span = test. span ;
452
472
let path = test. path . clone ( ) ;
473
+ let ecx = & cx. ext_cx ;
474
+ let self_id = ecx. ident_of ( "self" ) ;
475
+ let test_id = ecx. ident_of ( "test" ) ;
476
+
477
+ // creates self::test::$name
478
+ let test_path = |name| {
479
+ ecx. path ( span, vec ! [ self_id, test_id, ecx. ident_of( name) ] )
480
+ } ;
481
+ // creates $name: $expr
482
+ let field = |name, expr| ecx. field_imm ( span, ecx. ident_of ( name) , expr) ;
453
483
454
484
debug ! ( "encoding {}" , ast_util:: path_name_i( path. as_slice( ) ) ) ;
455
485
456
- let name_lit: ast:: Lit =
457
- nospan ( ast:: LitStr ( token:: intern_and_get_ident (
458
- ast_util:: path_name_i ( path. as_slice ( ) ) . as_slice ( ) ) ,
459
- ast:: CookedStr ) ) ;
486
+ // path to the #[test] function: "foo::bar::baz"
487
+ let path_string = ast_util:: path_name_i ( path. as_slice ( ) ) ;
488
+ let name_expr = ecx. expr_str ( span, token:: intern_and_get_ident ( path_string. as_slice ( ) ) ) ;
460
489
461
- let name_expr = box ( GC ) ast:: Expr {
462
- id : ast:: DUMMY_NODE_ID ,
463
- node : ast:: ExprLit ( box ( GC ) name_lit) ,
464
- span : span
465
- } ;
490
+ // self::test::StaticTestName($name_expr)
491
+ let name_expr = ecx. expr_call ( span,
492
+ ecx. expr_path ( test_path ( "StaticTestName" ) ) ,
493
+ vec ! [ name_expr] ) ;
466
494
467
- let mut visible_path = vec ! [ cx. reexport_mod_ident. clone( ) ] ;
468
- visible_path. extend ( path. move_iter ( ) ) ;
469
- let fn_path = cx. ext_cx . path_global ( DUMMY_SP , visible_path) ;
495
+ let ignore_expr = ecx. expr_bool ( span, test. ignore ) ;
496
+ let fail_expr = ecx. expr_bool ( span, test. should_fail ) ;
470
497
471
- let fn_expr = box ( GC ) ast:: Expr {
472
- id : ast:: DUMMY_NODE_ID ,
473
- node : ast:: ExprPath ( fn_path) ,
474
- span : span,
475
- } ;
498
+ // self::test::TestDesc { ... }
499
+ let desc_expr = ecx. expr_struct (
500
+ span,
501
+ test_path ( "TestDesc" ) ,
502
+ vec ! [ field( "name" , name_expr) ,
503
+ field( "ignore" , ignore_expr) ,
504
+ field( "should_fail" , fail_expr) ] ) ;
476
505
477
- let t_expr = if test. bench {
478
- quote_expr ! ( & cx. ext_cx, self :: test:: StaticBenchFn ( $fn_expr) )
479
- } else {
480
- quote_expr ! ( & cx. ext_cx, self :: test:: StaticTestFn ( $fn_expr) )
481
- } ;
482
506
483
- let ignore_expr = if test. ignore {
484
- quote_expr ! ( & cx. ext_cx, true )
485
- } else {
486
- quote_expr ! ( & cx. ext_cx, false )
487
- } ;
507
+ let mut visible_path = vec ! [ cx. reexport_mod_ident. clone( ) ] ;
508
+ visible_path. extend ( path. move_iter ( ) ) ;
488
509
489
- let fail_expr = if test. should_fail {
490
- quote_expr ! ( & cx. ext_cx, true )
491
- } else {
492
- quote_expr ! ( & cx. ext_cx, false )
493
- } ;
510
+ let fn_expr = ecx. expr_path ( ecx. path_global ( span, visible_path) ) ;
494
511
495
- let e = quote_expr ! ( & cx. ext_cx,
496
- self :: test:: TestDescAndFn {
497
- desc: self :: test:: TestDesc {
498
- name: self :: test:: StaticTestName ( $name_expr) ,
499
- ignore: $ignore_expr,
500
- should_fail: $fail_expr
501
- } ,
502
- testfn: $t_expr,
503
- }
504
- ) ;
505
- e
512
+ let variant_name = if test. bench { "StaticBenchFn" } else { "StaticTestFn" } ;
513
+ // self::test::$variant_name($fn_expr)
514
+ let testfn_expr = ecx. expr_call ( span, ecx. expr_path ( test_path ( variant_name) ) , vec ! [ fn_expr] ) ;
515
+
516
+ // self::test::TestDescAndFn { ... }
517
+ ecx. expr_struct ( span,
518
+ test_path ( "TestDescAndFn" ) ,
519
+ vec ! [ field( "desc" , desc_expr) ,
520
+ field( "testfn" , testfn_expr) ] )
506
521
}
0 commit comments