Skip to content

gensym each test re-export module individually #16892

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 3, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 32 additions & 13 deletions src/librustc/front/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,12 @@ struct TestCtxt<'a> {
path: Vec<ast::Ident>,
ext_cx: ExtCtxt<'a>,
testfns: Vec<Test>,
reexport_mod_ident: ast::Ident,
reexport_test_harness_main: Option<InternedString>,
is_test_crate: bool,
config: ast::CrateConfig,

// top-level re-export submodule, filled out after folding is finished
toplevel_reexport: Option<ast::Ident>,
}

// Traverse the crate, collecting all the test functions, eliding any
Expand Down Expand Up @@ -83,7 +85,9 @@ pub fn modify_for_testing(sess: &Session,
struct TestHarnessGenerator<'a> {
cx: TestCtxt<'a>,
tests: Vec<ast::Ident>,
tested_submods: Vec<ast::Ident>,

// submodule name, gensym'd identifier for re-exports
tested_submods: Vec<(ast::Ident, ast::Ident)>,
}

impl<'a> fold::Folder for TestHarnessGenerator<'a> {
Expand Down Expand Up @@ -168,10 +172,14 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
*i = nomain(*i);
}
if !tests.is_empty() || !tested_submods.is_empty() {
mod_folded.items.push(mk_reexport_mod(&mut self.cx, tests,
tested_submods));
let (it, sym) = mk_reexport_mod(&mut self.cx, tests, tested_submods);
mod_folded.items.push(it);

if !self.cx.path.is_empty() {
self.tested_submods.push(self.cx.path[self.cx.path.len()-1]);
self.tested_submods.push((self.cx.path[self.cx.path.len()-1], sym));
} else {
debug!("pushing nothing, sym: {}", sym);
self.cx.toplevel_reexport = Some(sym);
}
}

Expand All @@ -180,16 +188,16 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
}

fn mk_reexport_mod(cx: &mut TestCtxt, tests: Vec<ast::Ident>,
tested_submods: Vec<ast::Ident>) -> Gc<ast::Item> {
tested_submods: Vec<(ast::Ident, ast::Ident)>) -> (Gc<ast::Item>, ast::Ident) {
let mut view_items = Vec::new();
let super_ = token::str_to_ident("super");

view_items.extend(tests.move_iter().map(|r| {
cx.ext_cx.view_use_simple(DUMMY_SP, ast::Public,
cx.ext_cx.path(DUMMY_SP, vec![super_, r]))
}));
view_items.extend(tested_submods.move_iter().map(|r| {
let path = cx.ext_cx.path(DUMMY_SP, vec![super_, r, cx.reexport_mod_ident]);
view_items.extend(tested_submods.move_iter().map(|(r, sym)| {
let path = cx.ext_cx.path(DUMMY_SP, vec![super_, r, sym]);
cx.ext_cx.view_use_simple_(DUMMY_SP, ast::Public, r, path)
}));

Expand All @@ -198,14 +206,18 @@ fn mk_reexport_mod(cx: &mut TestCtxt, tests: Vec<ast::Ident>,
view_items: view_items,
items: Vec::new(),
};
box(GC) ast::Item {
ident: cx.reexport_mod_ident.clone(),

let sym = token::gensym_ident("__test_reexports");
let it = box(GC) ast::Item {
ident: sym.clone(),
attrs: Vec::new(),
id: ast::DUMMY_NODE_ID,
node: ast::ItemMod(reexport_mod),
vis: ast::Public,
span: DUMMY_SP,
}
};

(it, sym)
}

fn generate_test_harness(sess: &Session,
Expand All @@ -220,10 +232,10 @@ fn generate_test_harness(sess: &Session,
}),
path: Vec::new(),
testfns: Vec::new(),
reexport_mod_ident: token::gensym_ident("__test_reexports"),
reexport_test_harness_main: reexport_test_harness_main,
is_test_crate: is_test_crate(&krate),
config: krate.config.clone(),
toplevel_reexport: None,
};

cx.ext_cx.bt_push(ExpnInfo {
Expand Down Expand Up @@ -530,7 +542,14 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> Gc<ast::Expr> {
field("should_fail", fail_expr)]);


let mut visible_path = vec![cx.reexport_mod_ident.clone()];
let mut visible_path = match cx.toplevel_reexport {
Some(id) => vec![id],
None => {
cx.sess.bug(
"expected to find top-level re-export name, but found None"
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this just uses a dummy span, it should call bug instead of span_bug. It also looks like some of this module is conditionally executed, so could this bug possibly be triggered on something like an empty file?

}
};
visible_path.extend(path.move_iter());

let fn_expr = ecx.expr_path(ecx.path_global(span, visible_path));
Expand Down
14 changes: 14 additions & 0 deletions src/test/run-pass/issue-16597-empty.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags:--test

// This verifies that the test generation doesn't crash when we have
// no tests - for more information, see PR #16892.
21 changes: 21 additions & 0 deletions src/test/run-pass/issue-16597.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags:--test
// ignore-pretty turns out the pretty-printer doesn't handle gensym'd things...

#![feature(globs)]

mod test {
use super::*;

#[test]
fn test(){}
}