]> git.lizzy.rs Git - rust.git/commitdiff
Reexport tests without polluting namespaces
authorJohn Renner <john@jrenner.net>
Wed, 25 Jul 2018 00:51:37 +0000 (17:51 -0700)
committerJohn Renner <john@jrenner.net>
Tue, 31 Jul 2018 02:23:24 +0000 (19:23 -0700)
src/libsyntax/ext/expand.rs
src/test/run-pass/issue-52557.rs [new file with mode: 0644]

index b84046d10505125f1ca9a7ad9024f23b6154f3db..4b17ca87d8775ed628493d168753d4c2dd3a7561 100644 (file)
@@ -15,6 +15,7 @@
 use config::{is_test_or_bench, StripUnconfigured};
 use errors::{Applicability, FatalError};
 use ext::base::*;
+use ext::build::AstBuilder;
 use ext::derive::{add_derived_markers, collect_derives};
 use ext::hygiene::{self, Mark, SyntaxContext};
 use ext::placeholders::{placeholder, PlaceholderExpander};
@@ -1354,12 +1355,29 @@ fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
             // Ensure that test functions are accessible from the test harness.
             ast::ItemKind::Fn(..) if self.cx.ecfg.should_test => {
                 if item.attrs.iter().any(|attr| is_test_or_bench(attr)) {
+                    let orig_vis = item.vis.clone();
+
+                    // Publicize the item under gensymed name to avoid pollution
                     item = item.map(|mut item| {
                         item.vis = respan(item.vis.span, ast::VisibilityKind::Public);
+                        item.ident = Ident::from_interned_str(
+                                                item.ident.as_interned_str()).gensym();
                         item
                     });
+
+                    // Use the gensymed name under the item's original visibility
+                    let use_item = self.cx.item_use_simple_(
+                        item.ident.span,
+                        orig_vis,
+                        Some(Ident::from_interned_str(item.ident.as_interned_str())),
+                        self.cx.path(item.ident.span, vec![item.ident]));
+
+                    SmallVector::many(
+                        noop_fold_item(item, self).into_iter()
+                            .chain(noop_fold_item(use_item, self)))
+                } else {
+                    noop_fold_item(item, self)
                 }
-                noop_fold_item(item, self)
             }
             _ => noop_fold_item(item, self),
         }
diff --git a/src/test/run-pass/issue-52557.rs b/src/test/run-pass/issue-52557.rs
new file mode 100644 (file)
index 0000000..d6d272b
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2015 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.
+
+// This test checks for namespace pollution by private tests.
+// Tests used to marked as public causing name conflicts with normal
+// functions only in test builds.
+
+// compile-flags: --test
+
+mod a {
+    pub fn foo() -> bool {
+        true
+    }
+}
+
+mod b {
+    #[test]
+    fn foo() {}
+}
+
+use a::*;
+use b::*;
+
+fn conflict() {
+    let _: bool = foo();
+}
\ No newline at end of file