diff options
| author | Brian Anderson <banderson@mozilla.com> | 2015-01-21 18:13:08 -0800 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2015-01-22 13:47:53 -0800 |
| commit | 2b879a08b503f3ea45e7206c6bcd47d966603598 (patch) | |
| tree | ba4b03baab6e1895fde54421dff400f8ecc409c3 | |
| parent | 41278c5441f484a68a20ca12d93cab368a2a943f (diff) | |
| download | rust-2b879a08b503f3ea45e7206c6bcd47d966603598.tar.gz rust-2b879a08b503f3ea45e7206c6bcd47d966603598.zip | |
Make test harness use unstable APIs without allow(unstable)
| -rw-r--r-- | src/libsyntax/test.rs | 94 |
1 files changed, 79 insertions, 15 deletions
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 5f869d5093f..c7d7b57e66e 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -282,6 +282,24 @@ fn strip_test_functions(krate: ast::Crate) -> ast::Crate { }) } +/// Craft a span that will be ignored by the stability lint's +/// call to codemap's is_internal check. +/// The expanded code calls some unstable functions in the test crate. +fn ignored_span(cx: &TestCtxt, sp: Span) -> Span { + let info = ExpnInfo { + call_site: DUMMY_SP, + callee: NameAndSpan { + name: "test".to_string(), + format: MacroAttribute, + span: None + } + }; + let expn_id = cx.sess.span_diagnostic.cm.record_expansion(info); + let mut sp = sp; + sp.expn_id = expn_id; + return sp; +} + #[derive(PartialEq)] enum HasTestSignature { Yes, @@ -408,6 +426,64 @@ fn mk_std(cx: &TestCtxt) -> ast::ViewItem { } } +fn mk_main(cx: &mut TestCtxt) -> P<ast::Item> { + // Writing this out by hand with 'ignored_span': + // pub fn main() { + // #![main] + // use std::slice::AsSlice; + // test::test_main_static(::std::os::args().as_slice(), TESTS); + // } + + let sp = ignored_span(cx, DUMMY_SP); + let ecx = &cx.ext_cx; + + // std::slice::AsSlice + let as_slice_path = ecx.path(sp, vec![token::str_to_ident("std"), + token::str_to_ident("slice"), + token::str_to_ident("AsSlice")]); + // test::test_main_static + let test_main_path = ecx.path(sp, vec![token::str_to_ident("test"), + token::str_to_ident("test_main_static")]); + // ::std::os::args + let os_args_path = ecx.path_global(sp, vec![token::str_to_ident("std"), + token::str_to_ident("os"), + token::str_to_ident("args")]); + // use std::slice::AsSlice + let as_slice_path = P(nospan(ast::ViewPathSimple(token::str_to_ident("AsSlice"), + as_slice_path, ast::DUMMY_NODE_ID))); + let use_as_slice = ecx.view_use(sp, ast::Inherited, as_slice_path); + // ::std::os::args() + let os_args_path_expr = ecx.expr_path(os_args_path); + let call_os_args = ecx.expr_call(sp, os_args_path_expr, vec![]); + // ::std::os::args().as_slice() + let call_as_slice = ecx.expr_method_call(sp, call_os_args, + token::str_to_ident("as_slice"), vec![]); + // test::test_main_static(...) + let test_main_path_expr = ecx.expr_path(test_main_path); + let tests_ident_expr = ecx.expr_ident(sp, token::str_to_ident("TESTS")); + let call_test_main = ecx.expr_call(sp, test_main_path_expr, + vec![call_as_slice, tests_ident_expr]); + let call_test_main = ecx.stmt_expr(call_test_main); + // #![main] + let main_meta = ecx.meta_word(sp, token::intern_and_get_ident("main")); + let main_attr = ecx.attribute(sp, main_meta); + // pub fn main() { ... } + let main_ret_ty = ecx.ty(sp, ast::TyTup(vec![])); + let main_body = ecx.block_all(sp, vec![use_as_slice], vec![call_test_main], None); + let main = ast::ItemFn(ecx.fn_decl(vec![], main_ret_ty), + ast::Unsafety::Normal, ::abi::Rust, empty_generics(), main_body); + let main = P(ast::Item { + ident: token::str_to_ident("main"), + attrs: vec![main_attr], + id: ast::DUMMY_NODE_ID, + node: main, + vis: ast::Public, + span: sp + }); + + return main; +} + fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<ast::ViewItem>) { // Link to test crate let view_items = vec!(mk_std(cx)); @@ -417,13 +493,7 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<ast::ViewItem>) { // The synthesized main function which will call the console test runner // with our list of tests - let mainfn = (quote_item!(&mut cx.ext_cx, - pub fn main() { - #![main] - use std::slice::AsSlice; - test::test_main_static(::std::os::args().as_slice(), TESTS); - } - )).unwrap(); + let mainfn = mk_main(cx); let testmod = ast::Mod { inner: DUMMY_SP, @@ -433,19 +503,13 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<ast::ViewItem>) { let item_ = ast::ItemMod(testmod); let mod_ident = token::gensym_ident("__test"); - let allow_unstable = { - let unstable = P(nospan(ast::MetaWord(InternedString::new("unstable")))); - let allow = P(nospan(ast::MetaList(InternedString::new("allow"), - vec![unstable]))); - attr::mk_attr_inner(attr::mk_attr_id(), allow) - }; let item = ast::Item { ident: mod_ident, id: ast::DUMMY_NODE_ID, node: item_, vis: ast::Public, span: DUMMY_SP, - attrs: vec![allow_unstable], + attrs: vec![], }; let reexport = cx.reexport_test_harness_main.as_ref().map(|s| { // building `use <ident> = __test::main` @@ -538,7 +602,7 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> { // __test_reexports, causing it to be reinterned, losing the // gensym information. - let span = test.span; + let span = ignored_span(cx, test.span); let path = test.path.clone(); let ecx = &cx.ext_cx; let self_id = ecx.ident_of("self"); |
