Skip to content

Commit eb5b903

Browse files
Add compile-fail test in rustdoc
1 parent d0ef740 commit eb5b903

File tree

7 files changed

+183
-63
lines changed

7 files changed

+183
-63
lines changed

src/error-index-generator/main.rs

Lines changed: 120 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -21,37 +21,41 @@ use std::env;
2121
use std::path::Path;
2222
use std::error::Error;
2323

24-
use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap};
24+
use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap, ErrorMetadata};
2525

2626
use rustdoc::html::markdown::Markdown;
2727
use rustc_serialize::json;
2828

29-
/// Load all the metadata files from `metadata_dir` into an in-memory map.
30-
fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<Error>> {
31-
let mut all_errors = BTreeMap::new();
32-
33-
for entry in try!(read_dir(metadata_dir)) {
34-
let path = try!(entry).path();
35-
36-
let mut metadata_str = String::new();
37-
try!(File::open(&path).and_then(|mut f| f.read_to_string(&mut metadata_str)));
38-
39-
let some_errors: ErrorMetadataMap = try!(json::decode(&metadata_str));
29+
enum OutputFormat {
30+
HTML(HTMLFormatter),
31+
Markdown(MarkdownFormatter),
32+
Unknown(String),
33+
}
4034

41-
for (err_code, info) in some_errors {
42-
all_errors.insert(err_code, info);
35+
impl OutputFormat {
36+
fn from(format: &str) -> OutputFormat {
37+
match &*format.to_lowercase() {
38+
"html" => OutputFormat::HTML(HTMLFormatter),
39+
"markdown" => OutputFormat::Markdown(MarkdownFormatter),
40+
s => OutputFormat::Unknown(s.to_owned()),
4341
}
4442
}
43+
}
4544

46-
Ok(all_errors)
45+
trait Formatter {
46+
fn header(&self, output: &mut Write) -> Result<(), Box<Error>>;
47+
fn title(&self, output: &mut Write) -> Result<(), Box<Error>>;
48+
fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
49+
err_code: &str) -> Result<(), Box<Error>>;
50+
fn footer(&self, output: &mut Write) -> Result<(), Box<Error>>;
4751
}
4852

49-
/// Output an HTML page for the errors in `err_map` to `output_path`.
50-
fn render_error_page(err_map: &ErrorMetadataMap, output_path: &Path) -> Result<(), Box<Error>> {
51-
let mut output_file = try!(File::create(output_path));
53+
struct HTMLFormatter;
54+
struct MarkdownFormatter;
5255

53-
try!(write!(&mut output_file,
54-
r##"<!DOCTYPE html>
56+
impl Formatter for HTMLFormatter {
57+
fn header(&self, output: &mut Write) -> Result<(), Box<Error>> {
58+
try!(write!(output, r##"<!DOCTYPE html>
5559
<html>
5660
<head>
5761
<title>Rust Compiler Error Index</title>
@@ -66,12 +70,17 @@ r##"<!DOCTYPE html>
6670
</style>
6771
</head>
6872
<body>
69-
"##
70-
));
73+
"##));
74+
Ok(())
75+
}
7176

72-
try!(write!(&mut output_file, "<h1>Rust Compiler Error Index</h1>\n"));
77+
fn title(&self, output: &mut Write) -> Result<(), Box<Error>> {
78+
try!(write!(output, "<h1>Rust Compiler Error Index</h1>\n"));
79+
Ok(())
80+
}
7381

74-
for (err_code, info) in err_map {
82+
fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
83+
err_code: &str) -> Result<(), Box<Error>> {
7584
// Enclose each error in a div so they can be shown/hidden en masse.
7685
let desc_desc = match info.description {
7786
Some(_) => "error-described",
@@ -81,37 +90,114 @@ r##"<!DOCTYPE html>
8190
Some(_) => "error-used",
8291
None => "error-unused",
8392
};
84-
try!(write!(&mut output_file, "<div class=\"{} {}\">", desc_desc, use_desc));
93+
try!(write!(output, "<div class=\"{} {}\">", desc_desc, use_desc));
8594

8695
// Error title (with self-link).
87-
try!(write!(&mut output_file,
96+
try!(write!(output,
8897
"<h2 id=\"{0}\" class=\"section-header\"><a href=\"#{0}\">{0}</a></h2>\n",
8998
err_code));
9099

91100
// Description rendered as markdown.
92101
match info.description {
93-
Some(ref desc) => try!(write!(&mut output_file, "{}", Markdown(desc))),
94-
None => try!(write!(&mut output_file, "<p>No description.</p>\n")),
102+
Some(ref desc) => try!(write!(output, "{}", Markdown(desc))),
103+
None => try!(write!(output, "<p>No description.</p>\n")),
95104
}
96105

97-
try!(write!(&mut output_file, "</div>\n"));
106+
try!(write!(output, "</div>\n"));
107+
Ok(())
98108
}
99109

100-
try!(write!(&mut output_file, "</body>\n</html>"));
110+
fn footer(&self, output: &mut Write) -> Result<(), Box<Error>> {
111+
try!(write!(output, "</body>\n</html>"));
112+
Ok(())
113+
}
114+
}
101115

102-
Ok(())
116+
impl Formatter for MarkdownFormatter {
117+
#[allow(unused_variables)]
118+
fn header(&self, output: &mut Write) -> Result<(), Box<Error>> {
119+
Ok(())
120+
}
121+
122+
fn title(&self, output: &mut Write) -> Result<(), Box<Error>> {
123+
try!(write!(output, "# Rust Compiler Error Index\n"));
124+
Ok(())
125+
}
126+
127+
fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
128+
err_code: &str) -> Result<(), Box<Error>> {
129+
Ok(match info.description {
130+
Some(ref desc) => try!(write!(output, "## {}\n{}\n", err_code, desc)),
131+
None => (),
132+
})
133+
}
134+
135+
#[allow(unused_variables)]
136+
fn footer(&self, output: &mut Write) -> Result<(), Box<Error>> {
137+
Ok(())
138+
}
139+
}
140+
141+
/// Load all the metadata files from `metadata_dir` into an in-memory map.
142+
fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<Error>> {
143+
let mut all_errors = BTreeMap::new();
144+
145+
for entry in try!(read_dir(metadata_dir)) {
146+
let path = try!(entry).path();
147+
148+
let mut metadata_str = String::new();
149+
try!(File::open(&path).and_then(|mut f| f.read_to_string(&mut metadata_str)));
150+
151+
let some_errors: ErrorMetadataMap = try!(json::decode(&metadata_str));
152+
153+
for (err_code, info) in some_errors {
154+
all_errors.insert(err_code, info);
155+
}
156+
}
157+
158+
Ok(all_errors)
159+
}
160+
161+
/// Output an HTML page for the errors in `err_map` to `output_path`.
162+
fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Path,
163+
formatter: T) -> Result<(), Box<Error>> {
164+
let mut output_file = try!(File::create(output_path));
165+
166+
try!(formatter.header(&mut output_file));
167+
try!(formatter.title(&mut output_file));
168+
169+
for (err_code, info) in err_map {
170+
try!(formatter.error_code_block(&mut output_file, info, err_code));
171+
}
172+
173+
formatter.footer(&mut output_file)
103174
}
104175

105-
fn main_with_result() -> Result<(), Box<Error>> {
176+
fn main_with_result(format: OutputFormat) -> Result<(), Box<Error>> {
106177
let build_arch = try!(env::var("CFG_BUILD"));
107178
let metadata_dir = get_metadata_dir(&build_arch);
108179
let err_map = try!(load_all_errors(&metadata_dir));
109-
try!(render_error_page(&err_map, Path::new("doc/error-index.html")));
180+
match format {
181+
OutputFormat::Unknown(s) => panic!("Unknown output format: {}", s),
182+
OutputFormat::HTML(h) => try!(render_error_page(&err_map,
183+
Path::new("doc/error-index.html"),
184+
h)),
185+
OutputFormat::Markdown(m) => try!(render_error_page(&err_map,
186+
Path::new("doc/error-index.html"),
187+
m)),
188+
}
110189
Ok(())
111190
}
112191

192+
fn parse_args() -> OutputFormat {
193+
for arg in env::args().skip(1) {
194+
return OutputFormat::from(&arg);
195+
}
196+
OutputFormat::from("html")
197+
}
198+
113199
fn main() {
114-
if let Err(e) = main_with_result() {
200+
if let Err(e) = main_with_result(parse_args()) {
115201
panic!("{}", e.description());
116202
}
117203
}

src/librustc_driver/driver.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ pub fn compile_input(sess: &Session,
6565
outdir: &Option<PathBuf>,
6666
output: &Option<PathBuf>,
6767
addl_plugins: Option<Vec<String>>,
68-
control: CompileController) -> CompileResult {
68+
control: &CompileController) -> CompileResult {
6969
macro_rules! controller_entry_point {
7070
($point: ident, $tsess: expr, $make_state: expr, $phase_result: expr) => {{
7171
let state = $make_state;

src/librustc_driver/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ pub fn run_compiler<'a>(args: &[String],
199199
let plugins = sess.opts.debugging_opts.extra_plugins.clone();
200200
let control = callbacks.build_controller(&sess);
201201
(driver::compile_input(&sess, &cstore, cfg, &input, &odir, &ofile,
202-
Some(plugins), control),
202+
Some(plugins), &control),
203203
Some(sess))
204204
}
205205

src/librustdoc/html/markdown.rs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,8 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
400400
let text = lines.collect::<Vec<&str>>().join("\n");
401401
tests.add_test(text.to_owned(),
402402
block_info.should_panic, block_info.no_run,
403-
block_info.ignore, block_info.test_harness);
403+
block_info.ignore, block_info.test_harness,
404+
block_info.compile_fail);
404405
}
405406
}
406407

@@ -445,6 +446,7 @@ struct LangString {
445446
ignore: bool,
446447
rust: bool,
447448
test_harness: bool,
449+
compile_fail: bool,
448450
}
449451

450452
impl LangString {
@@ -455,6 +457,7 @@ impl LangString {
455457
ignore: false,
456458
rust: true, // NB This used to be `notrust = false`
457459
test_harness: false,
460+
compile_fail: false,
458461
}
459462
}
460463

@@ -474,7 +477,9 @@ impl LangString {
474477
"no_run" => { data.no_run = true; seen_rust_tags = true; },
475478
"ignore" => { data.ignore = true; seen_rust_tags = true; },
476479
"rust" => { data.rust = true; seen_rust_tags = true; },
477-
"test_harness" => { data.test_harness = true; seen_rust_tags = true; }
480+
"test_harness" => { data.test_harness = true; seen_rust_tags = true; },
481+
"compile_fail" => { data.compile_fail = true; seen_rust_tags = true;
482+
data.no_run = true; },
478483
_ => { seen_other_tags = true }
479484
}
480485
}
@@ -557,28 +562,31 @@ mod tests {
557562
#[test]
558563
fn test_lang_string_parse() {
559564
fn t(s: &str,
560-
should_panic: bool, no_run: bool, ignore: bool, rust: bool, test_harness: bool) {
565+
should_panic: bool, no_run: bool, ignore: bool, rust: bool, test_harness: bool,
566+
compile_fail: bool) {
561567
assert_eq!(LangString::parse(s), LangString {
562568
should_panic: should_panic,
563569
no_run: no_run,
564570
ignore: ignore,
565571
rust: rust,
566572
test_harness: test_harness,
573+
compile_fail: compile_fail,
567574
})
568575
}
569576

570-
// marker | should_panic| no_run | ignore | rust | test_harness
571-
t("", false, false, false, true, false);
572-
t("rust", false, false, false, true, false);
573-
t("sh", false, false, false, false, false);
574-
t("ignore", false, false, true, true, false);
575-
t("should_panic", true, false, false, true, false);
576-
t("no_run", false, true, false, true, false);
577-
t("test_harness", false, false, false, true, true);
578-
t("{.no_run .example}", false, true, false, true, false);
579-
t("{.sh .should_panic}", true, false, false, true, false);
580-
t("{.example .rust}", false, false, false, true, false);
581-
t("{.test_harness .rust}", false, false, false, true, true);
577+
// marker | should_panic| no_run| ignore| rust | test_harness| compile_fail
578+
t("", false, false, false, true, false, false);
579+
t("rust", false, false, false, true, false, false);
580+
t("sh", false, false, false, false, false, false);
581+
t("ignore", false, false, true, true, false, false);
582+
t("should_panic", true, false, false, true, false, false);
583+
t("no_run", false, true, false, true, false, false);
584+
t("test_harness", false, false, false, true, true, false);
585+
t("compile_fail", false, false, false, true, false, true);
586+
t("{.no_run .example}", false, true, false, true, false, false);
587+
t("{.sh .should_panic}", true, false, false, true, false, false);
588+
t("{.example .rust}", false, false, false, true, false, false);
589+
t("{.test_harness .rust}", false, false, false, true, true, false);
582590
}
583591

584592
#[test]

src/librustdoc/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@
2222
#![feature(box_syntax)]
2323
#![feature(dynamic_lib)]
2424
#![feature(libc)]
25+
#![feature(recover)]
2526
#![feature(rustc_private)]
2627
#![feature(set_stdio)]
2728
#![feature(slice_patterns)]
2829
#![feature(staged_api)]
30+
#![feature(std_panic)]
2931
#![feature(test)]
3032
#![feature(unicode)]
3133

0 commit comments

Comments
 (0)