]>
Commit | Line | Data |
---|---|---|
60c5eb7d XL |
1 | #![doc( |
2 | html_root_url = "https://doc.rust-lang.org/nightly/", | |
3 | html_playground_url = "https://play.rust-lang.org/" | |
4 | )] | |
3b2f2976 | 5 | #![feature(rustc_private)] |
29967ef6 | 6 | #![feature(array_methods)] |
85aaf69f | 7 | #![feature(box_patterns)] |
1a4d82fc | 8 | #![feature(box_syntax)] |
532ac7d7 | 9 | #![feature(in_band_lifetimes)] |
0bf4aa26 | 10 | #![feature(nll)] |
ba9703b0 | 11 | #![feature(or_patterns)] |
29967ef6 | 12 | #![feature(peekable_next_if)] |
85aaf69f | 13 | #![feature(test)] |
8faf50e0 | 14 | #![feature(crate_visibility_modifier)] |
532ac7d7 | 15 | #![feature(never_type)] |
3dfed10e | 16 | #![feature(once_cell)] |
fc512014 XL |
17 | #![feature(type_ascription)] |
18 | #![feature(split_inclusive)] | |
19 | #![feature(str_split_once)] | |
60c5eb7d | 20 | #![recursion_limit = "256"] |
94b46f34 | 21 | |
3dfed10e XL |
22 | #[macro_use] |
23 | extern crate lazy_static; | |
1b1a35ee XL |
24 | #[macro_use] |
25 | extern crate tracing; | |
26 | ||
27 | // N.B. these need `extern crate` even in 2018 edition | |
28 | // because they're loaded implicitly from the sysroot. | |
29 | // The reason they're loaded from the sysroot is because | |
30 | // the rustdoc artifacts aren't stored in rustc's cargo target directory. | |
31 | // So if `rustc` was specified in Cargo.toml, this would spuriously rebuild crates. | |
32 | // | |
33 | // Dependencies listed in Cargo.toml do not need `extern crate`. | |
74b04a01 XL |
34 | extern crate rustc_ast; |
35 | extern crate rustc_ast_pretty; | |
36 | extern crate rustc_attr; | |
9e0c209e | 37 | extern crate rustc_data_structures; |
1a4d82fc | 38 | extern crate rustc_driver; |
dfeec247 XL |
39 | extern crate rustc_errors; |
40 | extern crate rustc_expand; | |
60c5eb7d | 41 | extern crate rustc_feature; |
dfeec247 | 42 | extern crate rustc_hir; |
ba9703b0 | 43 | extern crate rustc_hir_pretty; |
60c5eb7d | 44 | extern crate rustc_index; |
74b04a01 | 45 | extern crate rustc_infer; |
532ac7d7 | 46 | extern crate rustc_interface; |
60c5eb7d XL |
47 | extern crate rustc_lexer; |
48 | extern crate rustc_lint; | |
92a42be0 | 49 | extern crate rustc_metadata; |
ba9703b0 | 50 | extern crate rustc_middle; |
dfeec247 | 51 | extern crate rustc_mir; |
60c5eb7d XL |
52 | extern crate rustc_parse; |
53 | extern crate rustc_resolve; | |
dfeec247 XL |
54 | extern crate rustc_session; |
55 | extern crate rustc_span as rustc_span; | |
83c7162d | 56 | extern crate rustc_target; |
ba9703b0 | 57 | extern crate rustc_trait_selection; |
7cac9316 | 58 | extern crate rustc_typeck; |
c34b1796 | 59 | extern crate test as testing; |
1a4d82fc | 60 | |
9cc50fc6 | 61 | use std::default::Default; |
85aaf69f | 62 | use std::env; |
62682a34 | 63 | use std::process; |
c34b1796 | 64 | |
fc512014 | 65 | use rustc_driver::abort_on_err; |
3dfed10e | 66 | use rustc_errors::ErrorReported; |
fc512014 XL |
67 | use rustc_interface::interface; |
68 | use rustc_middle::ty; | |
ba9703b0 XL |
69 | use rustc_session::config::{make_crate_type_option, ErrorOutputType, RustcOptGroup}; |
70 | use rustc_session::getopts; | |
71 | use rustc_session::{early_error, early_warn}; | |
1a4d82fc JJ |
72 | |
73 | #[macro_use] | |
8faf50e0 | 74 | mod externalfiles; |
1a4d82fc | 75 | |
8faf50e0 | 76 | mod clean; |
a1dfa0c6 | 77 | mod config; |
8faf50e0 | 78 | mod core; |
dc9dc135 | 79 | mod docfs; |
8faf50e0 | 80 | mod doctree; |
3dfed10e XL |
81 | #[macro_use] |
82 | mod error; | |
1b1a35ee | 83 | mod doctest; |
8faf50e0 | 84 | mod fold; |
3dfed10e XL |
85 | crate mod formats; |
86 | pub mod html; | |
87 | mod json; | |
8faf50e0 XL |
88 | mod markdown; |
89 | mod passes; | |
8faf50e0 | 90 | mod theme; |
60c5eb7d XL |
91 | mod visit_ast; |
92 | mod visit_lib; | |
1a4d82fc | 93 | |
1a4d82fc | 94 | pub fn main() { |
83c7162d | 95 | rustc_driver::set_sigpipe_handler(); |
3dfed10e XL |
96 | rustc_driver::install_ice_hook(); |
97 | rustc_driver::init_env_logger("RUSTDOC_LOG"); | |
98 | let exit_code = rustc_driver::catch_with_exit_code(|| match get_args() { | |
99 | Some(args) => main_args(&args), | |
100 | _ => Err(ErrorReported), | |
101 | }); | |
102 | process::exit(exit_code); | |
1a4d82fc JJ |
103 | } |
104 | ||
7cac9316 | 105 | fn get_args() -> Option<Vec<String>> { |
60c5eb7d XL |
106 | env::args_os() |
107 | .enumerate() | |
108 | .map(|(i, arg)| { | |
109 | arg.into_string() | |
110 | .map_err(|arg| { | |
111 | early_warn( | |
112 | ErrorOutputType::default(), | |
113 | &format!("Argument {} is not valid Unicode: {:?}", i, arg), | |
114 | ); | |
115 | }) | |
116 | .ok() | |
117 | }) | |
7cac9316 XL |
118 | .collect() |
119 | } | |
120 | ||
8faf50e0 | 121 | fn opts() -> Vec<RustcOptGroup> { |
fc512014 XL |
122 | let stable: fn(_, fn(&mut getopts::Options) -> &mut _) -> _ = RustcOptGroup::stable; |
123 | let unstable: fn(_, fn(&mut getopts::Options) -> &mut _) -> _ = RustcOptGroup::unstable; | |
c30ab7b3 | 124 | vec![ |
041b39d2 XL |
125 | stable("h", |o| o.optflag("h", "help", "show this help message")), |
126 | stable("V", |o| o.optflag("V", "version", "print rustdoc's version")), | |
127 | stable("v", |o| o.optflag("v", "verbose", "use verbose output")), | |
128 | stable("r", |o| { | |
60c5eb7d | 129 | o.optopt("r", "input-format", "the input type of the specified file", "[rust]") |
041b39d2 | 130 | }), |
60c5eb7d | 131 | stable("w", |o| o.optopt("w", "output-format", "the output type to write", "[html]")), |
041b39d2 XL |
132 | stable("o", |o| o.optopt("o", "output", "where to place the output", "PATH")), |
133 | stable("crate-name", |o| { | |
134 | o.optopt("", "crate-name", "specify the name of this crate", "NAME") | |
135 | }), | |
e1599b0c | 136 | make_crate_type_option(), |
041b39d2 | 137 | stable("L", |o| { |
60c5eb7d | 138 | o.optmulti("L", "library-path", "directory to add to crate search path", "DIR") |
041b39d2 XL |
139 | }), |
140 | stable("cfg", |o| o.optmulti("", "cfg", "pass a --cfg to rustc", "")), | |
60c5eb7d | 141 | stable("extern", |o| o.optmulti("", "extern", "pass an --extern to rustc", "NAME[=PATH]")), |
b7449926 | 142 | unstable("extern-html-root-url", |o| { |
60c5eb7d | 143 | o.optmulti("", "extern-html-root-url", "base URL to use for dependencies", "NAME=URL") |
041b39d2 | 144 | }), |
60c5eb7d | 145 | stable("plugin-path", |o| o.optmulti("", "plugin-path", "removed", "DIR")), |
83c7162d XL |
146 | stable("C", |o| { |
147 | o.optmulti("C", "codegen", "pass a codegen option to rustc", "OPT[=VALUE]") | |
148 | }), | |
041b39d2 | 149 | stable("passes", |o| { |
60c5eb7d XL |
150 | o.optmulti( |
151 | "", | |
152 | "passes", | |
f035d41b | 153 | "list of passes to also run, you might want to pass it multiple times; a value of \ |
1b1a35ee | 154 | `list` will print available passes", |
60c5eb7d XL |
155 | "PASSES", |
156 | ) | |
041b39d2 | 157 | }), |
60c5eb7d XL |
158 | stable("plugins", |o| o.optmulti("", "plugins", "removed", "PLUGINS")), |
159 | stable("no-default", |o| o.optflag("", "no-defaults", "don't run the default passes")), | |
abe05a73 XL |
160 | stable("document-private-items", |o| { |
161 | o.optflag("", "document-private-items", "document private items") | |
162 | }), | |
60c5eb7d XL |
163 | unstable("document-hidden-items", |o| { |
164 | o.optflag("", "document-hidden-items", "document items that have doc(hidden)") | |
165 | }), | |
041b39d2 XL |
166 | stable("test", |o| o.optflag("", "test", "run code examples as tests")), |
167 | stable("test-args", |o| { | |
60c5eb7d | 168 | o.optmulti("", "test-args", "arguments to pass to the test runner", "ARGS") |
041b39d2 XL |
169 | }), |
170 | stable("target", |o| o.optopt("", "target", "target triple to document", "TRIPLE")), | |
171 | stable("markdown-css", |o| { | |
60c5eb7d XL |
172 | o.optmulti( |
173 | "", | |
174 | "markdown-css", | |
175 | "CSS files to include via <link> in a rendered Markdown file", | |
176 | "FILES", | |
177 | ) | |
041b39d2 | 178 | }), |
60c5eb7d XL |
179 | stable("html-in-header", |o| { |
180 | o.optmulti( | |
181 | "", | |
182 | "html-in-header", | |
183 | "files to include inline in the <head> section of a rendered Markdown file \ | |
1b1a35ee | 184 | or generated documentation", |
60c5eb7d XL |
185 | "FILES", |
186 | ) | |
041b39d2 XL |
187 | }), |
188 | stable("html-before-content", |o| { | |
60c5eb7d XL |
189 | o.optmulti( |
190 | "", | |
191 | "html-before-content", | |
192 | "files to include inline between <body> and the content of a rendered \ | |
1b1a35ee | 193 | Markdown file or generated documentation", |
60c5eb7d XL |
194 | "FILES", |
195 | ) | |
041b39d2 XL |
196 | }), |
197 | stable("html-after-content", |o| { | |
60c5eb7d XL |
198 | o.optmulti( |
199 | "", | |
200 | "html-after-content", | |
201 | "files to include inline between the content and </body> of a rendered \ | |
1b1a35ee | 202 | Markdown file or generated documentation", |
60c5eb7d XL |
203 | "FILES", |
204 | ) | |
041b39d2 XL |
205 | }), |
206 | unstable("markdown-before-content", |o| { | |
60c5eb7d XL |
207 | o.optmulti( |
208 | "", | |
209 | "markdown-before-content", | |
210 | "files to include inline between <body> and the content of a rendered \ | |
1b1a35ee | 211 | Markdown file or generated documentation", |
60c5eb7d XL |
212 | "FILES", |
213 | ) | |
041b39d2 XL |
214 | }), |
215 | unstable("markdown-after-content", |o| { | |
60c5eb7d XL |
216 | o.optmulti( |
217 | "", | |
218 | "markdown-after-content", | |
219 | "files to include inline between the content and </body> of a rendered \ | |
1b1a35ee | 220 | Markdown file or generated documentation", |
60c5eb7d XL |
221 | "FILES", |
222 | ) | |
041b39d2 XL |
223 | }), |
224 | stable("markdown-playground-url", |o| { | |
60c5eb7d | 225 | o.optopt("", "markdown-playground-url", "URL to send code snippets to", "URL") |
041b39d2 XL |
226 | }), |
227 | stable("markdown-no-toc", |o| { | |
228 | o.optflag("", "markdown-no-toc", "don't include table of contents") | |
229 | }), | |
230 | stable("e", |o| { | |
60c5eb7d XL |
231 | o.optopt( |
232 | "e", | |
233 | "extend-css", | |
234 | "To add some CSS rules with a given file to generate doc with your \ | |
1b1a35ee XL |
235 | own theme. However, your theme might break if the rustdoc's generated HTML \ |
236 | changes, so be careful!", | |
60c5eb7d XL |
237 | "PATH", |
238 | ) | |
041b39d2 XL |
239 | }), |
240 | unstable("Z", |o| { | |
60c5eb7d | 241 | o.optmulti("Z", "", "internal and debugging options (only on nightly build)", "FLAG") |
041b39d2 | 242 | }), |
60c5eb7d | 243 | stable("sysroot", |o| o.optopt("", "sysroot", "Override the system root", "PATH")), |
041b39d2 | 244 | unstable("playground-url", |o| { |
60c5eb7d XL |
245 | o.optopt( |
246 | "", | |
247 | "playground-url", | |
248 | "URL to send code snippets to, may be reset by --markdown-playground-url \ | |
1b1a35ee | 249 | or `#![doc(html_playground_url=...)]`", |
60c5eb7d XL |
250 | "URL", |
251 | ) | |
041b39d2 | 252 | }), |
041b39d2 XL |
253 | unstable("display-warnings", |o| { |
254 | o.optflag("", "display-warnings", "to print code warnings when testing doc") | |
255 | }), | |
ba9703b0 | 256 | stable("crate-version", |o| { |
abe05a73 XL |
257 | o.optopt("", "crate-version", "crate version to print into documentation", "VERSION") |
258 | }), | |
ff7c6d11 | 259 | unstable("sort-modules-by-appearance", |o| { |
60c5eb7d XL |
260 | o.optflag( |
261 | "", | |
262 | "sort-modules-by-appearance", | |
f035d41b | 263 | "sort modules by where they appear in the program, rather than alphabetically", |
60c5eb7d | 264 | ) |
ff7c6d11 | 265 | }), |
29967ef6 XL |
266 | unstable("default-theme", |o| { |
267 | o.optopt( | |
268 | "", | |
269 | "default-theme", | |
270 | "Set the default theme. THEME should be the theme name, generally lowercase. \ | |
271 | If an unknown default theme is specified, the builtin default is used. \ | |
272 | The set of themes, and the rustdoc built-in default is not stable.", | |
273 | "THEME", | |
274 | ) | |
275 | }), | |
276 | unstable("default-setting", |o| { | |
277 | o.optmulti( | |
278 | "", | |
279 | "default-setting", | |
280 | "Default value for a rustdoc setting (used when \"rustdoc-SETTING\" is absent \ | |
281 | from web browser Local Storage). If VALUE is not supplied, \"true\" is used. \ | |
282 | Supported SETTINGs and VALUEs are not documented and not stable.", | |
283 | "SETTING[=VALUE]", | |
284 | ) | |
285 | }), | |
60c5eb7d XL |
286 | stable("theme", |o| { |
287 | o.optmulti( | |
288 | "", | |
289 | "theme", | |
290 | "additional themes which will be added to the generated docs", | |
291 | "FILES", | |
292 | ) | |
2c00a5a8 | 293 | }), |
60c5eb7d XL |
294 | stable("check-theme", |o| { |
295 | o.optmulti("", "check-theme", "check if given theme is valid", "FILES") | |
2c00a5a8 | 296 | }), |
0531ce1d | 297 | unstable("resource-suffix", |o| { |
60c5eb7d XL |
298 | o.optopt( |
299 | "", | |
300 | "resource-suffix", | |
301 | "suffix to add to CSS and JavaScript files, e.g., \"light.css\" will become \ | |
1b1a35ee | 302 | \"light-suffix.css\"", |
60c5eb7d XL |
303 | "PATH", |
304 | ) | |
0531ce1d | 305 | }), |
0bf4aa26 | 306 | stable("edition", |o| { |
60c5eb7d XL |
307 | o.optopt( |
308 | "", | |
309 | "edition", | |
310 | "edition to use when compiling rust code (default: 2015)", | |
311 | "EDITION", | |
312 | ) | |
0531ce1d | 313 | }), |
b7449926 | 314 | stable("color", |o| { |
60c5eb7d XL |
315 | o.optopt( |
316 | "", | |
317 | "color", | |
318 | "Configure coloring of output: | |
83c7162d XL |
319 | auto = colorize, if output goes to a tty (default); |
320 | always = always colorize output; | |
321 | never = never colorize output", | |
60c5eb7d XL |
322 | "auto|always|never", |
323 | ) | |
83c7162d | 324 | }), |
b7449926 | 325 | stable("error-format", |o| { |
60c5eb7d XL |
326 | o.optopt( |
327 | "", | |
328 | "error-format", | |
329 | "How errors and other messages are produced", | |
330 | "human|json|short", | |
331 | ) | |
83c7162d | 332 | }), |
416331ca | 333 | stable("json", |o| { |
60c5eb7d | 334 | o.optopt("", "json", "Configure the structure of JSON diagnostics", "CONFIG") |
416331ca | 335 | }), |
94b46f34 | 336 | unstable("disable-minification", |o| { |
60c5eb7d | 337 | o.optflag("", "disable-minification", "Disable minification applied on JS files") |
8faf50e0 | 338 | }), |
60c5eb7d XL |
339 | stable("warn", |o| o.optmulti("W", "warn", "Set lint warnings", "OPT")), |
340 | stable("allow", |o| o.optmulti("A", "allow", "Set lint allowed", "OPT")), | |
341 | stable("deny", |o| o.optmulti("D", "deny", "Set lint denied", "OPT")), | |
342 | stable("forbid", |o| o.optmulti("F", "forbid", "Set lint forbidden", "OPT")), | |
8faf50e0 XL |
343 | stable("cap-lints", |o| { |
344 | o.optmulti( | |
345 | "", | |
346 | "cap-lints", | |
347 | "Set the most restrictive lint level. \ | |
348 | More restrictive lints are capped at this \ | |
349 | level. By default, it is at `forbid` level.", | |
350 | "LEVEL", | |
351 | ) | |
352 | }), | |
a1dfa0c6 | 353 | unstable("index-page", |o| { |
60c5eb7d | 354 | o.optopt("", "index-page", "Markdown file to be used as index page", "PATH") |
a1dfa0c6 XL |
355 | }), |
356 | unstable("enable-index-page", |o| { | |
60c5eb7d | 357 | o.optflag("", "enable-index-page", "To enable generation of the index page") |
a1dfa0c6 | 358 | }), |
0731742a | 359 | unstable("static-root-path", |o| { |
60c5eb7d XL |
360 | o.optopt( |
361 | "", | |
362 | "static-root-path", | |
363 | "Path string to force loading static files from in output pages. \ | |
1b1a35ee | 364 | If not set, uses combinations of '../' to reach the documentation root.", |
60c5eb7d XL |
365 | "PATH", |
366 | ) | |
0731742a XL |
367 | }), |
368 | unstable("disable-per-crate-search", |o| { | |
60c5eb7d XL |
369 | o.optflag( |
370 | "", | |
371 | "disable-per-crate-search", | |
372 | "disables generating the crate selector on the search box", | |
373 | ) | |
0731742a | 374 | }), |
9fa01778 | 375 | unstable("persist-doctests", |o| { |
60c5eb7d XL |
376 | o.optopt( |
377 | "", | |
378 | "persist-doctests", | |
379 | "Directory to persist doctest executables into", | |
380 | "PATH", | |
381 | ) | |
9fa01778 | 382 | }), |
532ac7d7 | 383 | unstable("show-coverage", |o| { |
60c5eb7d XL |
384 | o.optflag( |
385 | "", | |
386 | "show-coverage", | |
387 | "calculate percentage of public items with documentation", | |
388 | ) | |
532ac7d7 | 389 | }), |
e1599b0c | 390 | unstable("enable-per-target-ignores", |o| { |
60c5eb7d XL |
391 | o.optflag( |
392 | "", | |
393 | "enable-per-target-ignores", | |
394 | "parse ignore-foo for ignoring doctests on a per-target basis", | |
395 | ) | |
e1599b0c XL |
396 | }), |
397 | unstable("runtool", |o| { | |
60c5eb7d XL |
398 | o.optopt( |
399 | "", | |
400 | "runtool", | |
401 | "", | |
402 | "The tool to run tests with when building for a different target than host", | |
403 | ) | |
e1599b0c XL |
404 | }), |
405 | unstable("runtool-arg", |o| { | |
60c5eb7d XL |
406 | o.optmulti( |
407 | "", | |
408 | "runtool-arg", | |
409 | "", | |
410 | "One (of possibly many) arguments to pass to the runtool", | |
411 | ) | |
e1599b0c XL |
412 | }), |
413 | unstable("test-builder", |o| { | |
60c5eb7d XL |
414 | o.optflag( |
415 | "", | |
416 | "test-builder", | |
417 | "specified the rustc-like binary to use as the test builder", | |
418 | ) | |
e1599b0c | 419 | }), |
fc512014 | 420 | unstable("check", |o| o.optflag("", "check", "Run rustdoc checks")), |
c30ab7b3 | 421 | ] |
1a4d82fc JJ |
422 | } |
423 | ||
8faf50e0 | 424 | fn usage(argv0: &str) { |
041b39d2 XL |
425 | let mut options = getopts::Options::new(); |
426 | for option in opts() { | |
427 | (option.apply)(&mut options); | |
428 | } | |
429 | println!("{}", options.usage(&format!("{} [options] <input>", argv0))); | |
29967ef6 | 430 | println!("More information available at https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html") |
1a4d82fc JJ |
431 | } |
432 | ||
3dfed10e XL |
433 | /// A result type used by several functions under `main()`. |
434 | type MainResult = Result<(), ErrorReported>; | |
435 | ||
436 | fn main_args(args: &[String]) -> MainResult { | |
041b39d2 XL |
437 | let mut options = getopts::Options::new(); |
438 | for option in opts() { | |
439 | (option.apply)(&mut options); | |
440 | } | |
441 | let matches = match options.parse(&args[1..]) { | |
1a4d82fc JJ |
442 | Ok(m) => m, |
443 | Err(err) => { | |
94b46f34 | 444 | early_error(ErrorOutputType::default(), &err.to_string()); |
1a4d82fc JJ |
445 | } |
446 | }; | |
3dfed10e XL |
447 | |
448 | // Note that we discard any distinction between different non-zero exit | |
449 | // codes from `from_matches` here. | |
a1dfa0c6 XL |
450 | let options = match config::Options::from_matches(&matches) { |
451 | Ok(opts) => opts, | |
3dfed10e | 452 | Err(code) => return if code == 0 { Ok(()) } else { Err(ErrorReported) }, |
b7449926 | 453 | }; |
3dfed10e | 454 | rustc_interface::util::setup_callbacks_and_run_in_thread_pool_with_globals( |
f035d41b | 455 | options.edition, |
3dfed10e XL |
456 | 1, // this runs single-threaded, even in a parallel compiler |
457 | &None, | |
f035d41b XL |
458 | move || main_options(options), |
459 | ) | |
dc9dc135 | 460 | } |
1a4d82fc | 461 | |
3dfed10e | 462 | fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> MainResult { |
f9f354fc | 463 | match res { |
3dfed10e | 464 | Ok(()) => Ok(()), |
f9f354fc | 465 | Err(err) => { |
3dfed10e XL |
466 | diag.struct_err(&err).emit(); |
467 | Err(ErrorReported) | |
468 | } | |
469 | } | |
470 | } | |
471 | ||
fc512014 | 472 | fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>( |
3dfed10e XL |
473 | krate: clean::Crate, |
474 | renderopts: config::RenderOptions, | |
475 | render_info: config::RenderInfo, | |
476 | diag: &rustc_errors::Handler, | |
477 | edition: rustc_span::edition::Edition, | |
fc512014 | 478 | tcx: ty::TyCtxt<'tcx>, |
3dfed10e | 479 | ) -> MainResult { |
fc512014 | 480 | match formats::run_format::<T>(krate, renderopts, render_info, &diag, edition, tcx) { |
3dfed10e XL |
481 | Ok(_) => Ok(()), |
482 | Err(e) => { | |
483 | let mut msg = diag.struct_err(&format!("couldn't generate documentation: {}", e.error)); | |
484 | let file = e.file.display().to_string(); | |
485 | if file.is_empty() { | |
486 | msg.emit() | |
487 | } else { | |
488 | msg.note(&format!("failed to create or modify \"{}\"", file)).emit() | |
f9f354fc | 489 | } |
3dfed10e | 490 | Err(ErrorReported) |
f9f354fc XL |
491 | } |
492 | } | |
493 | } | |
494 | ||
3dfed10e | 495 | fn main_options(options: config::Options) -> MainResult { |
1b1a35ee | 496 | let diag = core::new_handler(options.error_format, None, &options.debugging_opts); |
1a4d82fc | 497 | |
a1dfa0c6 | 498 | match (options.should_test, options.markdown_input()) { |
f9f354fc | 499 | (true, true) => return wrap_return(&diag, markdown::test(options)), |
1b1a35ee | 500 | (true, false) => return doctest::run(options), |
60c5eb7d | 501 | (false, true) => { |
f9f354fc XL |
502 | return wrap_return( |
503 | &diag, | |
504 | markdown::render(&options.input, options.render_options, options.edition), | |
505 | ); | |
60c5eb7d | 506 | } |
1a4d82fc JJ |
507 | (false, false) => {} |
508 | } | |
476ff2be | 509 | |
a1dfa0c6 | 510 | // need to move these items separately because we lose them by the time the closure is called, |
fc512014 | 511 | // but we can't create the Handler ahead of time because it's not Send |
1b1a35ee | 512 | let diag_opts = (options.error_format, options.edition, options.debugging_opts.clone()); |
532ac7d7 | 513 | let show_coverage = options.show_coverage; |
fc512014 | 514 | let run_check = options.run_check; |
f035d41b XL |
515 | |
516 | // First, parse the crate and extract all relevant information. | |
517 | info!("starting to run rustc"); | |
518 | ||
519 | // Interpret the input file as a rust source file, passing it through the | |
520 | // compiler all the way through the analysis passes. The rustdoc output is | |
521 | // then generated from the cleaned AST of the crate. This runs all the | |
522 | // plug/cleaning passes. | |
3dfed10e | 523 | let crate_version = options.crate_version.clone(); |
fc512014 XL |
524 | |
525 | let default_passes = options.default_passes; | |
3dfed10e | 526 | let output_format = options.output_format; |
fc512014 XL |
527 | // FIXME: fix this clone (especially render_options) |
528 | let externs = options.externs.clone(); | |
529 | let manual_passes = options.manual_passes.clone(); | |
530 | let render_options = options.render_options.clone(); | |
531 | let config = core::create_config(options); | |
f035d41b | 532 | |
fc512014 XL |
533 | interface::create_compiler_and_run(config, |compiler| { |
534 | compiler.enter(|queries| { | |
535 | let sess = compiler.session(); | |
f035d41b | 536 | |
fc512014 XL |
537 | // We need to hold on to the complete resolver, so we cause everything to be |
538 | // cloned for the analysis passes to use. Suboptimal, but necessary in the | |
539 | // current architecture. | |
540 | let resolver = core::create_resolver(externs, queries, &sess); | |
f035d41b | 541 | |
fc512014 XL |
542 | if sess.has_errors() { |
543 | sess.fatal("Compilation failed, aborting rustdoc"); | |
544 | } | |
f035d41b | 545 | |
fc512014 | 546 | let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess).take(); |
8faf50e0 | 547 | |
fc512014 XL |
548 | global_ctxt.enter(|tcx| { |
549 | let (mut krate, render_info, render_opts) = sess.time("run_global_ctxt", || { | |
550 | core::run_global_ctxt( | |
551 | tcx, | |
552 | resolver, | |
553 | default_passes, | |
554 | manual_passes, | |
555 | render_options, | |
556 | output_format, | |
557 | ) | |
558 | }); | |
559 | info!("finished with rustc"); | |
560 | ||
561 | krate.version = crate_version; | |
562 | ||
563 | if show_coverage { | |
564 | // if we ran coverage, bail early, we don't need to also generate docs at this point | |
565 | // (also we didn't load in any of the useful passes) | |
566 | return Ok(()); | |
567 | } else if run_check { | |
568 | // Since we're in "check" mode, no need to generate anything beyond this point. | |
569 | return Ok(()); | |
570 | } | |
571 | ||
572 | info!("going to format"); | |
573 | let (error_format, edition, debugging_options) = diag_opts; | |
574 | let diag = core::new_handler(error_format, None, &debugging_options); | |
575 | match output_format { | |
576 | None | Some(config::OutputFormat::Html) => sess.time("render_html", || { | |
577 | run_renderer::<html::render::Context<'_>>( | |
578 | krate, | |
579 | render_opts, | |
580 | render_info, | |
581 | &diag, | |
582 | edition, | |
583 | tcx, | |
584 | ) | |
585 | }), | |
586 | Some(config::OutputFormat::Json) => sess.time("render_json", || { | |
587 | run_renderer::<json::JsonRenderer<'_>>( | |
588 | krate, | |
589 | render_opts, | |
590 | render_info, | |
591 | &diag, | |
592 | edition, | |
593 | tcx, | |
594 | ) | |
595 | }), | |
596 | } | |
597 | }) | |
598 | }) | |
599 | }) | |
1a4d82fc | 600 | } |