From 97721fa719882731fd7cce96225c140e094c61b5 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 27 Jul 2014 12:02:19 -0700 Subject: [PATCH] Make test expansion induce less reachability We previously reexported entire modules, which caused private things to become reachable and trip the dead code and private items in public API lints. Closes #15912 --- src/librustc/front/test.rs | 49 ++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index 08907f6c0ed..0fce75c8369 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -48,7 +48,6 @@ struct Test { struct TestCtxt<'a> { sess: &'a Session, path: Vec, - reexports: Vec>, ext_cx: ExtCtxt<'a>, testfns: Vec, reexport_mod_ident: ast::Ident, @@ -74,6 +73,8 @@ pub fn modify_for_testing(sess: &Session, struct TestHarnessGenerator<'a> { cx: TestCtxt<'a>, + tests: Vec, + tested_submods: Vec, } impl<'a> fold::Folder for TestHarnessGenerator<'a> { @@ -111,7 +112,7 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { should_fail: should_fail(i) }; self.cx.testfns.push(test); - self.cx.reexports.push(self.cx.path.clone()); + self.tests.push(i.ident); // debug!("have {} test/bench functions", // cx.testfns.len()); } @@ -129,9 +130,11 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { } fn fold_mod(&mut self, m: &ast::Mod) -> ast::Mod { - let reexports = mem::replace(&mut self.cx.reexports, Vec::new()); + let tests = mem::replace(&mut self.tests, Vec::new()); + let tested_submods = mem::replace(&mut self.tested_submods, Vec::new()); let mut mod_folded = fold::noop_fold_mod(m, self); - let reexports = mem::replace(&mut self.cx.reexports, reexports); + let tests = mem::replace(&mut self.tests, tests); + let tested_submods = mem::replace(&mut self.tested_submods, tested_submods); // Remove any #[main] from the AST so it doesn't clash with // the one we're going to add. Only if compiling an executable. @@ -152,20 +155,32 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { for i in mod_folded.items.mut_iter() { *i = nomain(*i); } - if !reexports.is_empty() { - mod_folded.items.push(mk_reexport_mod(&mut self.cx, reexports)); - self.cx.reexports.push(self.cx.path.clone()); + if !tests.is_empty() || !tested_submods.is_empty() { + mod_folded.items.push(mk_reexport_mod(&mut self.cx, tests, + tested_submods)); + if !self.cx.path.is_empty() { + self.tested_submods.push(self.cx.path[self.cx.path.len()-1]); + } } mod_folded } } -fn mk_reexport_mod(cx: &mut TestCtxt, reexports: Vec>) - -> Gc { - let view_items = reexports.move_iter().map(|r| { - cx.ext_cx.view_use_simple(DUMMY_SP, ast::Public, cx.ext_cx.path(DUMMY_SP, r)) - }).collect(); +fn mk_reexport_mod(cx: &mut TestCtxt, tests: Vec, + tested_submods: Vec) -> Gc { + 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]); + cx.ext_cx.view_use_simple_(DUMMY_SP, ast::Public, r, path) + })); + let reexport_mod = ast::Mod { inner: DUMMY_SP, view_items: view_items, @@ -190,7 +205,6 @@ fn generate_test_harness(sess: &Session, krate: ast::Crate) -> ast::Crate { crate_name: "test".to_string(), }), path: Vec::new(), - reexports: Vec::new(), testfns: Vec::new(), reexport_mod_ident: token::str_to_ident("__test_reexports"), is_test_crate: is_test_crate(&krate), @@ -208,6 +222,8 @@ fn generate_test_harness(sess: &Session, krate: ast::Crate) -> ast::Crate { let mut fold = TestHarnessGenerator { cx: cx, + tests: Vec::new(), + tested_submods: Vec::new(), }; let res = fold.fold_crate(krate); fold.cx.ext_cx.bt_pop(); @@ -448,11 +464,8 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> Gc { span: span }; - let mut visible_path = Vec::new(); - for ident in path.move_iter() { - visible_path.push(cx.reexport_mod_ident.clone()); - visible_path.push(ident); - } + let mut visible_path = vec![cx.reexport_mod_ident.clone()]; + visible_path.extend(path.move_iter()); let fn_path = cx.ext_cx.path_global(DUMMY_SP, visible_path); let fn_expr = box(GC) ast::Expr {