about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustdoc/html/markdown.rs2
-rw-r--r--src/librustdoc/markdown.rs2
-rw-r--r--src/librustdoc/test.rs56
3 files changed, 49 insertions, 11 deletions
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 7ea5bd569e1..cdd8457687a 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -230,7 +230,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
                         stripped_filtered_line(l).unwrap_or(l)
                     }).collect::<Vec<&str>>().connect("\n");
                     let krate = krate.as_ref().map(|s| &**s);
-                    let test = test::maketest(&test, krate, false, false);
+                    let test = test::maketest(&test, krate, false, false, true);
                     s.push_str(&format!("<span class='rusttest'>{}</span>", Escape(&test)));
                 });
                 s.push_str(&highlight::highlight(&text,
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index 09b4915222b..f3d7ae19f4d 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -143,7 +143,7 @@ pub fn test(input: &str, libs: SearchPaths, externs: core::Externs,
             mut test_args: Vec<String>) -> int {
     let input_str = load_or_return!(input, 1, 2);
 
-    let mut collector = Collector::new(input.to_string(), libs, externs, true);
+    let mut collector = Collector::new(input.to_string(), libs, externs, true, false);
     find_testable_code(&input_str, &mut collector);
     test_args.insert(0, "rustdoctest".to_string());
     testing::test_main(&test_args, collector.tests);
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 3bd466caf0b..1b596e65a78 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -76,6 +76,8 @@ pub fn run(input: &str,
                                                      "rustdoc-test", None)
         .expect("phase_2_configure_and_expand aborted in rustdoc!");
 
+    let inject_crate = should_inject_crate(&krate);
+
     let ctx = core::DocContext {
         krate: &krate,
         maybe_typed: core::NotTyped(sess),
@@ -100,7 +102,8 @@ pub fn run(input: &str,
     let mut collector = Collector::new(krate.name.to_string(),
                                        libs,
                                        externs,
-                                       false);
+                                       false,
+                                       inject_crate);
     collector.fold_crate(krate);
 
     test_args.insert(0, "rustdoctest".to_string());
@@ -110,13 +113,42 @@ pub fn run(input: &str,
     0
 }
 
+// Look for #![doc(test(no_crate_inject))], used by crates in the std facade
+fn should_inject_crate(krate: &::syntax::ast::Crate) -> bool {
+    use syntax::attr::AttrMetaMethods;
+
+    let mut inject_crate = true;
+
+    for attr in &krate.attrs {
+        if attr.check_name("doc") {
+            for list in attr.meta_item_list().into_iter() {
+                for attr in list {
+                    if attr.check_name("test") {
+                        for list in attr.meta_item_list().into_iter() {
+                            for attr in list {
+                                if attr.check_name("no_crate_inject") {
+                                    inject_crate = false;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return inject_crate;
+}
+
 #[allow(deprecated)]
 fn runtest(test: &str, cratename: &str, libs: SearchPaths,
            externs: core::Externs,
-           should_panic: bool, no_run: bool, as_test_harness: bool) {
+           should_panic: bool, no_run: bool, as_test_harness: bool,
+           inject_crate: bool) {
     // the test harness wants its own `main` & top level functions, so
     // never wrap the test in `fn main() { ... }`
-    let test = maketest(test, Some(cratename), true, as_test_harness);
+    let test = maketest(test, Some(cratename), true, as_test_harness,
+                        inject_crate);
     let input = config::Input::Str(test.to_string());
 
     let sessopts = config::Options {
@@ -218,7 +250,8 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
     }
 }
 
-pub fn maketest(s: &str, cratename: Option<&str>, lints: bool, dont_insert_main: bool) -> String {
+pub fn maketest(s: &str, cratename: Option<&str>, lints: bool,
+                dont_insert_main: bool, inject_crate: bool) -> String {
     let (crate_attrs, everything_else) = partition_source(s);
 
     let mut prog = String::new();
@@ -235,7 +268,7 @@ pub fn maketest(s: &str, cratename: Option<&str>, lints: bool, dont_insert_main:
 
     // Don't inject `extern crate std` because it's already injected by the
     // compiler.
-    if !s.contains("extern crate") && cratename != Some("std") {
+    if !s.contains("extern crate") && cratename != Some("std") && inject_crate {
         match cratename {
             Some(cratename) => {
                 if s.contains(cratename) {
@@ -267,7 +300,7 @@ fn partition_source(s: &str) -> (String, String) {
     let mut after = String::new();
 
     for line in s.lines() {
-        let trimline = StrExt::trim(line);
+        let trimline = line.trim();
         let header = trimline.is_whitespace() ||
             trimline.starts_with("#![feature");
         if !header || after_header {
@@ -292,11 +325,12 @@ pub struct Collector {
     use_headers: bool,
     current_header: Option<String>,
     cratename: String,
+    inject_crate: bool
 }
 
 impl Collector {
     pub fn new(cratename: String, libs: SearchPaths, externs: core::Externs,
-               use_headers: bool) -> Collector {
+               use_headers: bool, inject_crate: bool) -> Collector {
         Collector {
             tests: Vec::new(),
             names: Vec::new(),
@@ -306,11 +340,13 @@ impl Collector {
             use_headers: use_headers,
             current_header: None,
             cratename: cratename,
+            inject_crate: inject_crate
         }
     }
 
     pub fn add_test(&mut self, test: String,
-                    should_panic: bool, no_run: bool, should_ignore: bool, as_test_harness: bool) {
+                    should_panic: bool, no_run: bool, should_ignore: bool,
+                    as_test_harness: bool) {
         let name = if self.use_headers {
             let s = self.current_header.as_ref().map(|s| &**s).unwrap_or("");
             format!("{}_{}", s, self.cnt)
@@ -321,6 +357,7 @@ impl Collector {
         let libs = self.libs.clone();
         let externs = self.externs.clone();
         let cratename = self.cratename.to_string();
+        let inject_crate = self.inject_crate;
         debug!("Creating test {}: {}", name, test);
         self.tests.push(testing::TestDescAndFn {
             desc: testing::TestDesc {
@@ -335,7 +372,8 @@ impl Collector {
                         externs,
                         should_panic,
                         no_run,
-                        as_test_harness);
+                        as_test_harness,
+                        inject_crate);
             }))
         });
     }