Skip to content

Commit ce4b75f

Browse files
committed
Auto merge of #30726 - GuillaumeGomez:compile-fail, r=brson
r? @brson cc @alexcrichton I still need to add error code explanation test with this, but I can't figure out a way to generate the `.md` files in order to test example source codes. Will fix #27328.
2 parents 0c4d81f + eb7664b commit ce4b75f

File tree

16 files changed

+1072
-560
lines changed

16 files changed

+1072
-560
lines changed

mk/docs.mk

+8-1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ RUSTBOOK = $(RPATH_VAR2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $(RUSTBOOK_EXE)
6262
# The error-index-generator executable...
6363
ERR_IDX_GEN_EXE = $(HBIN2_H_$(CFG_BUILD))/error-index-generator$(X_$(CFG_BUILD))
6464
ERR_IDX_GEN = $(RPATH_VAR2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $(ERR_IDX_GEN_EXE)
65+
ERR_IDX_GEN_MD = $(RPATH_VAR2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $(ERR_IDX_GEN_EXE) markdown
6566

6667
D := $(S)src/doc
6768

@@ -217,6 +218,12 @@ doc/style/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/style/*.md) | doc/
217218

218219
error-index: doc/error-index.html
219220

220-
doc/error-index.html: $(ERR_IDX_GEN_EXE) | doc/
221+
# Metadata used to generate the index is created as a side effect of
222+
# the build so this depends on every crate being up to date.
223+
doc/error-index.html: $(ERR_IDX_GEN_EXE) $(CSREQ$(2)_T_$(CFG_BUILD)_H_$(CFG_BUILD)) | doc/
221224
$(Q)$(call E, error-index-generator: $@)
222225
$(Q)$(ERR_IDX_GEN)
226+
227+
doc/error-index.md: $(ERR_IDX_GEN_EXE) $(CSREQ$(2)_T_$(CFG_BUILD)_H_$(CFG_BUILD)) | doc/
228+
$(Q)$(call E, error-index-generator: $@)
229+
$(Q)$(ERR_IDX_GEN_MD)

mk/tests.mk

+33-10
Original file line numberDiff line numberDiff line change
@@ -298,14 +298,14 @@ check-stage$(1)-T-$(2)-H-$(3)-exec: \
298298
check-stage$(1)-T-$(2)-H-$(3)-rfail-exec \
299299
check-stage$(1)-T-$(2)-H-$(3)-cfail-exec \
300300
check-stage$(1)-T-$(2)-H-$(3)-pfail-exec \
301-
check-stage$(1)-T-$(2)-H-$(3)-rpass-valgrind-exec \
302-
check-stage$(1)-T-$(2)-H-$(3)-rpass-full-exec \
303-
check-stage$(1)-T-$(2)-H-$(3)-rfail-full-exec \
301+
check-stage$(1)-T-$(2)-H-$(3)-rpass-valgrind-exec \
302+
check-stage$(1)-T-$(2)-H-$(3)-rpass-full-exec \
303+
check-stage$(1)-T-$(2)-H-$(3)-rfail-full-exec \
304304
check-stage$(1)-T-$(2)-H-$(3)-cfail-full-exec \
305305
check-stage$(1)-T-$(2)-H-$(3)-rmake-exec \
306306
check-stage$(1)-T-$(2)-H-$(3)-rustdocck-exec \
307-
check-stage$(1)-T-$(2)-H-$(3)-crates-exec \
308-
check-stage$(1)-T-$(2)-H-$(3)-doc-crates-exec \
307+
check-stage$(1)-T-$(2)-H-$(3)-crates-exec \
308+
check-stage$(1)-T-$(2)-H-$(3)-doc-crates-exec \
309309
check-stage$(1)-T-$(2)-H-$(3)-debuginfo-gdb-exec \
310310
check-stage$(1)-T-$(2)-H-$(3)-debuginfo-lldb-exec \
311311
check-stage$(1)-T-$(2)-H-$(3)-codegen-exec \
@@ -673,8 +673,8 @@ CTEST_DEPS_debuginfo-lldb_$(1)-T-$(2)-H-$(3) = $$(DEBUGINFO_LLDB_TESTS) \
673673
CTEST_DEPS_codegen_$(1)-T-$(2)-H-$(3) = $$(CODEGEN_TESTS)
674674
CTEST_DEPS_codegen-units_$(1)-T-$(2)-H-$(3) = $$(CODEGEN_UNITS_TESTS)
675675
CTEST_DEPS_rustdocck_$(1)-T-$(2)-H-$(3) = $$(RUSTDOCCK_TESTS) \
676-
$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \
677-
$(S)src/etc/htmldocck.py
676+
$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \
677+
$(S)src/etc/htmldocck.py
678678

679679
endef
680680

@@ -892,6 +892,28 @@ $(foreach host,$(CFG_HOST), \
892892
$(foreach crate,$(TEST_DOC_CRATES), \
893893
$(eval $(call DEF_CRATE_DOC_TEST,$(stage),$(target),$(host),$(crate)))))))
894894

895+
define DEF_DOC_TEST_ERROR_INDEX
896+
897+
check-stage$(1)-T-$(2)-H-$(3)-doc-error-index-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),doc-error-index)
898+
899+
ifeq ($(2),$$(CFG_BUILD))
900+
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-error-index): \
901+
$$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \
902+
doc/error-index.md
903+
$$(Q)touch $$@.start_time
904+
$$(RUSTDOC_$(1)_T_$(2)_H_$(3)) --test doc/error-index.md
905+
$$(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
906+
else
907+
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-error-index):
908+
$$(Q)touch $$@
909+
endif
910+
endef
911+
912+
$(foreach host,$(CFG_HOST), \
913+
$(foreach target,$(CFG_TARGET), \
914+
$(foreach stage,$(STAGES), \
915+
$(eval $(call DEF_DOC_TEST_ERROR_INDEX,$(stage),$(target),$(host))))))
916+
895917
######################################################################
896918
# Shortcut rules
897919
######################################################################
@@ -901,7 +923,7 @@ TEST_GROUPS = \
901923
$(foreach crate,$(TEST_CRATES),$(crate)) \
902924
$(foreach crate,$(TEST_DOC_CRATES),doc-crate-$(crate)) \
903925
rpass \
904-
rpass-valgrind \
926+
rpass-valgrind \
905927
rpass-full \
906928
rfail-full \
907929
cfail-full \
@@ -918,7 +940,7 @@ TEST_GROUPS = \
918940
$(foreach docname,$(DOC_NAMES),doc-$(docname)) \
919941
pretty \
920942
pretty-rpass \
921-
pretty-rpass-valgrind \
943+
pretty-rpass-valgrind \
922944
pretty-rpass-full \
923945
pretty-rfail-full \
924946
pretty-rfail \
@@ -987,7 +1009,8 @@ define DEF_CHECK_DOC_FOR_STAGE
9871009
check-stage$(1)-docs: $$(foreach docname,$$(DOC_NAMES), \
9881010
check-stage$(1)-T-$$(CFG_BUILD)-H-$$(CFG_BUILD)-doc-$$(docname)) \
9891011
$$(foreach crate,$$(TEST_DOC_CRATES), \
990-
check-stage$(1)-T-$$(CFG_BUILD)-H-$$(CFG_BUILD)-doc-crate-$$(crate))
1012+
check-stage$(1)-T-$$(CFG_BUILD)-H-$$(CFG_BUILD)-doc-crate-$$(crate)) \
1013+
check-stage$(1)-T-$$(CFG_BUILD)-H-$$(CFG_BUILD)-doc-error-index-exec
9911014
endef
9921015

9931016
$(foreach stage,$(STAGES), \

src/error-index-generator/main.rs

+120-34
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.md"),
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
}

0 commit comments

Comments
 (0)