diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index e8ff8930bdd7d..e70030912db0e 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -35,6 +35,7 @@ use std::fmt::{self, Write};
 use std::slice;
 use std::str;
 use syntax::feature_gate::UnstableFeatures;
+use syntax::codemap::Span;
 
 use html::render::derive_id;
 use html::toc::TocBuilder;
@@ -429,7 +430,7 @@ pub fn render(w: &mut fmt::Formatter,
     }
 }
 
-pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, start_line: usize) {
+pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Span) {
     extern fn block(_ob: *mut hoedown_buffer,
                     text: *const hoedown_buffer,
                     lang: *const hoedown_buffer,
@@ -454,11 +455,12 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, start_line:
             });
             let text = lines.collect::<Vec<&str>>().join("\n");
             let line = tests.get_line() + line;
+            let filename = tests.get_filename();
             tests.add_test(text.to_owned(),
                            block_info.should_panic, block_info.no_run,
                            block_info.ignore, block_info.test_harness,
                            block_info.compile_fail, block_info.error_codes,
-                           line);
+                           line, filename);
         }
     }
 
@@ -479,7 +481,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, start_line:
         }
     }
 
-    tests.set_line(start_line);
+    tests.set_position(position);
     unsafe {
         let ob = hoedown_buffer_new(DEF_OUNIT);
         let renderer = hoedown_html_renderer_new(0, 0);
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index 49497957be980..70ef7c597e4d7 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -18,6 +18,7 @@ use getopts;
 use testing;
 use rustc::session::search_paths::SearchPaths;
 use rustc::session::config::Externs;
+use syntax::codemap::DUMMY_SP;
 
 use externalfiles::{ExternalHtml, LoadStringError, load_string};
 
@@ -154,9 +155,8 @@ pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
     let mut opts = TestOptions::default();
     opts.no_crate_inject = true;
     let mut collector = Collector::new(input.to_string(), cfgs, libs, externs,
-                                       true, opts, maybe_sysroot, "input".to_string(),
-                                       None);
-    find_testable_code(&input_str, &mut collector, 0);
+                                       true, opts, maybe_sysroot, None);
+    find_testable_code(&input_str, &mut collector, DUMMY_SP);
     test_args.insert(0, "rustdoctest".to_string());
     testing::test_main(&test_args, collector.tests);
     0
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 6f38da4f24b0d..930cf401e7450 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -37,7 +37,7 @@ use rustc_trans::back::link;
 use syntax::ast;
 use syntax::codemap::CodeMap;
 use syntax::feature_gate::UnstableFeatures;
-use syntax_pos::{BytePos, DUMMY_SP, Pos};
+use syntax_pos::{BytePos, DUMMY_SP, Pos, Span};
 use errors;
 use errors::emitter::ColorConfig;
 
@@ -97,7 +97,6 @@ pub fn run(input: &str,
         link::find_crate_name(None, &hir_forest.krate().attrs, &input)
     });
     let opts = scrape_test_config(hir_forest.krate());
-    let filename = input_path.to_str().unwrap_or("").to_owned();
     let mut collector = Collector::new(crate_name,
                                        cfgs,
                                        libs,
@@ -105,7 +104,6 @@ pub fn run(input: &str,
                                        false,
                                        opts,
                                        maybe_sysroot,
-                                       filename,
                                        Some(codemap));
 
     {
@@ -391,15 +389,14 @@ pub struct Collector {
     cratename: String,
     opts: TestOptions,
     maybe_sysroot: Option<PathBuf>,
-    filename: String,
-    start_line: usize,
+    position: Span,
     codemap: Option<Rc<CodeMap>>,
 }
 
 impl Collector {
     pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
                use_headers: bool, opts: TestOptions, maybe_sysroot: Option<PathBuf>,
-               filename: String, codemap: Option<Rc<CodeMap>>) -> Collector {
+               codemap: Option<Rc<CodeMap>>) -> Collector {
         Collector {
             tests: Vec::new(),
             names: Vec::new(),
@@ -412,8 +409,7 @@ impl Collector {
             cratename: cratename,
             opts: opts,
             maybe_sysroot: maybe_sysroot,
-            filename: filename,
-            start_line: 0,
+            position: DUMMY_SP,
             codemap: codemap,
         }
     }
@@ -421,8 +417,8 @@ impl Collector {
     pub fn add_test(&mut self, test: String,
                     should_panic: bool, no_run: bool, should_ignore: bool,
                     as_test_harness: bool, compile_fail: bool, error_codes: Vec<String>,
-                    line: usize) {
-        let name = format!("{} - line {}", self.filename, line);
+                    line: usize, filename: String) {
+        let name = format!("{} - line {}", filename, line);
         self.cnt += 1;
         let cfgs = self.cfgs.clone();
         let libs = self.libs.clone();
@@ -467,16 +463,25 @@ impl Collector {
     }
 
     pub fn get_line(&self) -> usize {
-        if let Some(ref codemap) = self.codemap{
-            let line = codemap.lookup_char_pos(BytePos(self.start_line as u32)).line;
+        if let Some(ref codemap) = self.codemap {
+            let line = self.position.lo.to_usize();
+            let line = codemap.lookup_char_pos(BytePos(line as u32)).line;
             if line > 0 { line - 1 } else { line }
         } else {
-            self.start_line
+            0
         }
     }
 
-    pub fn set_line(&mut self, start_line: usize) {
-        self.start_line = start_line;
+    pub fn set_position(&mut self, position: Span) {
+        self.position = position;
+    }
+
+    pub fn get_filename(&self) -> String {
+        if let Some(ref codemap) = self.codemap {
+            codemap.span_to_filename(self.position)
+        } else {
+            "<input>".to_owned()
+        }
     }
 
     pub fn register_header(&mut self, name: &str, level: u32) {
@@ -520,7 +525,7 @@ impl<'a, 'hir> HirCollector<'a, 'hir> {
         if let Some(doc) = attrs.doc_value() {
             self.collector.cnt = 0;
             markdown::find_testable_code(doc, self.collector,
-                                         attrs.span.unwrap_or(DUMMY_SP).lo.to_usize());
+                                         attrs.span.unwrap_or(DUMMY_SP));
         }
 
         nested(self);
diff --git a/src/test/rustdoc/test_option_check/bar.rs b/src/test/rustdoc/test_option_check/bar.rs
new file mode 100644
index 0000000000000..51daa80752622
--- /dev/null
+++ b/src/test/rustdoc/test_option_check/bar.rs
@@ -0,0 +1,19 @@
+// Copyright 2017 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
+// check-test-line-numbers-match
+
+/// This looks like another awesome test!
+///
+/// ```
+/// println!("foo?");
+/// ```
+pub fn foooo() {}
diff --git a/src/test/rustdoc/test_option_check/test.rs b/src/test/rustdoc/test_option_check/test.rs
index b2afe43204d41..a9578c5f434a2 100644
--- a/src/test/rustdoc/test_option_check/test.rs
+++ b/src/test/rustdoc/test_option_check/test.rs
@@ -11,6 +11,8 @@
 // compile-flags: --test
 // check-test-line-numbers-match
 
+pub mod bar;
+
 /// This is a Foo;
 ///
 /// ```
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index a8c46722e163b..4e527661df72e 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -30,6 +30,7 @@ use std::io::{self, BufReader};
 use std::path::{Path, PathBuf};
 use std::process::{Command, Output, ExitStatus};
 use std::str;
+use std::collections::HashMap;
 
 use extract_gdb_version;
 
@@ -1902,17 +1903,28 @@ actual:\n\
         }
     }
 
-    fn check_rustdoc_test_option(&self, res: ProcRes) {
-        let mut file = fs::File::open(&self.testpaths.file)
+    fn get_lines<P: AsRef<Path>>(&self, path: &P,
+                                 mut other_files: Option<&mut Vec<String>>) -> Vec<usize> {
+        let mut file = fs::File::open(path)
                                 .expect("markdown_test_output_check_entry File::open failed");
         let mut content = String::new();
         file.read_to_string(&mut content)
             .expect("markdown_test_output_check_entry read_to_string failed");
         let mut ignore = false;
-        let mut v: Vec<usize> =
-            content.lines()
-                   .enumerate()
-                   .filter_map(|(line_nb, line)| {
+        content.lines()
+               .enumerate()
+               .filter_map(|(line_nb, line)| {
+                   if (line.trim_left().starts_with("pub mod ") ||
+                       line.trim_left().starts_with("mod ")) &&
+                      line.ends_with(";") {
+                       if let Some(ref mut other_files) = other_files {
+                           other_files.push(line.rsplit("mod ")
+                                      .next()
+                                      .unwrap()
+                                      .replace(";", ""));
+                       }
+                       None
+                   } else {
                        let sline = line.split("///").last().unwrap_or("");
                        let line = sline.trim_left();
                        if line.starts_with("```") {
@@ -1926,8 +1938,21 @@ actual:\n\
                        } else {
                            None
                        }
-                   })
-                   .collect();
+                   }
+               })
+               .collect()
+    }
+
+    fn check_rustdoc_test_option(&self, res: ProcRes) {
+        let mut other_files = Vec::new();
+        let mut files: HashMap<String, Vec<usize>> = HashMap::new();
+        files.insert(self.testpaths.file.to_str().unwrap().to_owned(),
+                     self.get_lines(&self.testpaths.file, Some(&mut other_files)));
+        for other_file in other_files {
+            let mut path = self.testpaths.file.clone();
+            path.set_file_name(&format!("{}.rs", other_file));
+            files.insert(path.to_str().unwrap().to_owned(), self.get_lines(&path, None));
+        }
 
         let mut tested = 0;
         for _ in res.stdout.split("\n")
@@ -1935,27 +1960,35 @@ actual:\n\
                            .inspect(|s| {
                                let tmp: Vec<&str> = s.split(" - line ").collect();
                                if tmp.len() == 2 {
-                                   tested += 1;
-                                   let line = tmp[1].split(" ...")
-                                                    .next()
-                                                    .unwrap_or("0")
-                                                    .parse()
-                                                    .unwrap_or(0);
-                                   if let Ok(pos) = v.binary_search(&line) {
-                                       v.remove(pos);
-                                   } else {
-                                       self.fatal_proc_rec(
-                                           &format!("Not found doc test: \"{}\" in {:?}", s, v),
-                                           &res);
+                                   let path = tmp[0].rsplit("test ").next().unwrap();
+                                   if let Some(ref mut v) = files.get_mut(path) {
+                                       tested += 1;
+                                       let line = tmp[1].split(" ...")
+                                                        .next()
+                                                        .unwrap_or("0")
+                                                        .parse()
+                                                        .unwrap_or(0);
+                                       if let Ok(pos) = v.binary_search(&line) {
+                                           v.remove(pos);
+                                       } else {
+                                           self.fatal_proc_rec(
+                                               &format!("Not found doc test: \"{}\" in \"{}\":{:?}",
+                                                        s, path, v),
+                                               &res);
+                                       }
                                    }
                                }
                            }) {}
         if tested == 0 {
-            self.fatal_proc_rec("No test has been found", &res);
-        } else if v.len() != 0 {
-            self.fatal_proc_rec(&format!("Not found test at line{} {:?}",
-                                         if v.len() > 1 { "s" } else { "" }, v),
-                                &res);
+            self.fatal_proc_rec(&format!("No test has been found... {:?}", files), &res);
+        } else {
+            for (entry, v) in &files {
+                if v.len() != 0 {
+                    self.fatal_proc_rec(&format!("Not found test at line{} \"{}\":{:?}",
+                                                 if v.len() > 1 { "s" } else { "" }, entry, v),
+                                        &res);
+                }
+            }
         }
     }