diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 3baf22b38ef68..ed08f2f012332 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -408,7 +408,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) { 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.compile_fail, block_info.error_codes); } } @@ -454,6 +454,7 @@ struct LangString { rust: bool, test_harness: bool, compile_fail: bool, + error_codes: Vec, } impl LangString { @@ -465,6 +466,7 @@ impl LangString { rust: true, // NB This used to be `notrust = false` test_harness: false, compile_fail: false, + error_codes: Vec::new(), } } @@ -472,9 +474,14 @@ impl LangString { let mut seen_rust_tags = false; let mut seen_other_tags = false; let mut data = LangString::all_false(); - let allow_compile_fail = match get_unstable_features_setting() { - UnstableFeatures::Allow | UnstableFeatures::Cheat=> true, - _ => false, + let mut allow_compile_fail = false; + let mut allow_error_code_check = false; + match get_unstable_features_setting() { + UnstableFeatures::Allow | UnstableFeatures::Cheat => { + allow_compile_fail = true; + allow_error_code_check = true; + } + _ => {}, }; let tokens = string.split(|c: char| @@ -493,7 +500,15 @@ impl LangString { data.compile_fail = true; seen_rust_tags = true; data.no_run = true; - }, + } + x if allow_error_code_check && x.starts_with("E") && x.len() == 5 => { + if let Ok(_) = x[1..].parse::() { + data.error_codes.push(x.to_owned()); + seen_rust_tags = true; + } else { + seen_other_tags = true; + } + } _ => { seen_other_tags = true } } } @@ -577,7 +592,7 @@ mod tests { fn test_lang_string_parse() { fn t(s: &str, should_panic: bool, no_run: bool, ignore: bool, rust: bool, test_harness: bool, - compile_fail: bool) { + compile_fail: bool, error_codes: Vec) { assert_eq!(LangString::parse(s), LangString { should_panic: should_panic, no_run: no_run, @@ -585,6 +600,7 @@ mod tests { rust: rust, test_harness: test_harness, compile_fail: compile_fail, + error_codes: error_codes, }) } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index f0ca89097f701..cb27da0a75978 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -176,7 +176,7 @@ fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions { fn runtest(test: &str, cratename: &str, cfgs: Vec, libs: SearchPaths, externs: core::Externs, should_panic: bool, no_run: bool, as_test_harness: bool, - compile_fail: bool, opts: &TestOptions) { + compile_fail: bool, mut error_codes: Vec, opts: &TestOptions) { // the test harness wants its own `main` & top level functions, so // never wrap the test in `fn main() { ... }` let test = maketest(test, Some(cratename), as_test_harness, opts); @@ -232,7 +232,7 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec, libs: SearchPaths, None, codemap.clone()); let old = io::set_panic(box Sink(data.clone())); - let _bomb = Bomb(data, old.unwrap_or(box io::stdout())); + let _bomb = Bomb(data.clone(), old.unwrap_or(box io::stdout())); // Compile the code let diagnostic_handler = errors::Handler::with_emitter(true, false, box emitter); @@ -273,13 +273,28 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec, libs: SearchPaths, } else if count == 0 && compile_fail == true { panic!("test compiled while it wasn't supposed to") } + if count > 0 && error_codes.len() > 0 { + let out = String::from_utf8(data.lock().unwrap().to_vec()).unwrap(); + error_codes = error_codes.into_iter().filter(|err| !out.contains(err)).collect(); + } } Ok(()) if compile_fail => panic!("test compiled while it wasn't supposed to"), _ => {} } } - Err(_) if compile_fail == false => panic!("couldn't compile the test"), - _ => {} + Err(_) => { + if compile_fail == false { + panic!("couldn't compile the test"); + } + if error_codes.len() > 0 { + let out = String::from_utf8(data.lock().unwrap().to_vec()).unwrap(); + error_codes.retain(|err| !out.contains(err)); + } + } + } + + if error_codes.len() > 0 { + panic!("Some expected error codes were not found: {:?}", error_codes); } if no_run { return } @@ -411,7 +426,7 @@ 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) { + as_test_harness: bool, compile_fail: bool, error_codes: Vec) { let name = if self.use_headers { let s = self.current_header.as_ref().map(|s| &**s).unwrap_or(""); format!("{}_{}", s, self.cnt) @@ -442,6 +457,7 @@ impl Collector { no_run, as_test_harness, compile_fail, + error_codes, &opts); }) });