1#![doc(
2 html_root_url = "https://doc.rust-lang.org/nightly/",
3 html_playground_url = "https://play.rust-lang.org/"
4)]
5#![feature(rustc_private)]
6#![feature(assert_matches)]
7#![feature(box_patterns)]
8#![feature(debug_closure_helpers)]
9#![feature(file_buffered)]
10#![feature(format_args_nl)]
11#![feature(if_let_guard)]
12#![feature(impl_trait_in_assoc_type)]
13#![feature(iter_intersperse)]
14#![feature(let_chains)]
15#![feature(never_type)]
16#![feature(round_char_boundary)]
17#![feature(test)]
18#![feature(type_alias_impl_trait)]
19#![feature(type_ascription)]
20#![recursion_limit = "256"]
21#![warn(rustc::internal)]
22#![allow(clippy::collapsible_if, clippy::collapsible_else_if)]
23#![allow(rustc::diagnostic_outside_of_impl)]
24#![allow(rustc::untranslatable_diagnostic)]
25
26extern crate thin_vec;
27
28extern crate pulldown_cmark;
37extern crate rustc_abi;
38extern crate rustc_ast;
39extern crate rustc_ast_pretty;
40extern crate rustc_attr_parsing;
41extern crate rustc_data_structures;
42extern crate rustc_driver;
43extern crate rustc_errors;
44extern crate rustc_expand;
45extern crate rustc_feature;
46extern crate rustc_hir;
47extern crate rustc_hir_analysis;
48extern crate rustc_hir_pretty;
49extern crate rustc_index;
50extern crate rustc_infer;
51extern crate rustc_interface;
52extern crate rustc_lexer;
53extern crate rustc_lint;
54extern crate rustc_lint_defs;
55extern crate rustc_log;
56extern crate rustc_macros;
57extern crate rustc_metadata;
58extern crate rustc_middle;
59extern crate rustc_parse;
60extern crate rustc_passes;
61extern crate rustc_resolve;
62extern crate rustc_serialize;
63extern crate rustc_session;
64extern crate rustc_span;
65extern crate rustc_target;
66extern crate rustc_trait_selection;
67extern crate test;
68
69#[cfg(feature = "jemalloc")]
72extern crate tikv_jemalloc_sys as jemalloc_sys;
73
74use std::env::{self, VarError};
75use std::io::{self, IsTerminal};
76use std::process;
77
78use rustc_errors::DiagCtxtHandle;
79use rustc_interface::interface;
80use rustc_middle::ty::TyCtxt;
81use rustc_session::config::{ErrorOutputType, RustcOptGroup, make_crate_type_option};
82use rustc_session::{EarlyDiagCtxt, getopts};
83use tracing::info;
84
85use crate::clean::utils::DOC_RUST_LANG_ORG_VERSION;
86
87macro_rules! map {
98 ($( $key: expr => $val: expr ),* $(,)*) => {{
99 let mut map = ::rustc_data_structures::fx::FxIndexMap::default();
100 $( map.insert($key, $val); )*
101 map
102 }}
103}
104
105mod clean;
106mod config;
107mod core;
108mod display;
109mod docfs;
110mod doctest;
111mod error;
112mod externalfiles;
113mod fold;
114mod formats;
115pub mod html;
117mod json;
118pub(crate) mod lint;
119mod markdown;
120mod passes;
121mod scrape_examples;
122mod theme;
123mod visit;
124mod visit_ast;
125mod visit_lib;
126
127pub fn main() {
128 #[cfg(feature = "jemalloc")]
131 {
132 use std::os::raw::{c_int, c_void};
133
134 #[used]
135 static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc;
136 #[used]
137 static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int =
138 jemalloc_sys::posix_memalign;
139 #[used]
140 static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc;
141 #[used]
142 static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc;
143 #[used]
144 static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc;
145 #[used]
146 static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free;
147
148 #[cfg(target_os = "macos")]
149 {
150 unsafe extern "C" {
151 fn _rjem_je_zone_register();
152 }
153
154 #[used]
155 static _F7: unsafe extern "C" fn() = _rjem_je_zone_register;
156 }
157 }
158
159 let mut early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());
160
161 rustc_driver::install_ice_hook(
162 "https://github.com/rust-lang/rust/issues/new\
163 ?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md",
164 |_| (),
165 );
166
167 init_logging(&early_dcx);
178 rustc_driver::init_logger(&early_dcx, rustc_log::LoggerConfig::from_env("RUSTDOC_LOG"));
179
180 let exit_code = rustc_driver::catch_with_exit_code(|| {
181 let at_args = rustc_driver::args::raw_args(&early_dcx);
182 main_args(&mut early_dcx, &at_args);
183 });
184 process::exit(exit_code);
185}
186
187fn init_logging(early_dcx: &EarlyDiagCtxt) {
188 let color_logs = match env::var("RUSTDOC_LOG_COLOR").as_deref() {
189 Ok("always") => true,
190 Ok("never") => false,
191 Ok("auto") | Err(VarError::NotPresent) => io::stdout().is_terminal(),
192 Ok(value) => early_dcx.early_fatal(format!(
193 "invalid log color value '{value}': expected one of always, never, or auto",
194 )),
195 Err(VarError::NotUnicode(value)) => early_dcx.early_fatal(format!(
196 "invalid log color value '{}': expected one of always, never, or auto",
197 value.to_string_lossy()
198 )),
199 };
200 let filter = tracing_subscriber::EnvFilter::from_env("RUSTDOC_LOG");
201 let layer = tracing_tree::HierarchicalLayer::default()
202 .with_writer(io::stderr)
203 .with_ansi(color_logs)
204 .with_targets(true)
205 .with_wraparound(10)
206 .with_verbose_exit(true)
207 .with_verbose_entry(true)
208 .with_indent_amount(2);
209 #[cfg(debug_assertions)]
210 let layer = layer.with_thread_ids(true).with_thread_names(true);
211
212 use tracing_subscriber::layer::SubscriberExt;
213 let subscriber = tracing_subscriber::Registry::default().with(filter).with(layer);
214 tracing::subscriber::set_global_default(subscriber).unwrap();
215}
216
217fn opts() -> Vec<RustcOptGroup> {
218 use rustc_session::config::OptionKind::{Flag, FlagMulti, Multi, Opt};
219 use rustc_session::config::OptionStability::{Stable, Unstable};
220 use rustc_session::config::make_opt as opt;
221
222 vec![
223 opt(Stable, FlagMulti, "h", "help", "show this help message", ""),
224 opt(Stable, FlagMulti, "V", "version", "print rustdoc's version", ""),
225 opt(Stable, FlagMulti, "v", "verbose", "use verbose output", ""),
226 opt(Stable, Opt, "w", "output-format", "the output type to write", "[html]"),
227 opt(
228 Stable,
229 Opt,
230 "",
231 "output",
232 "Which directory to place the output. This option is deprecated, use --out-dir instead.",
233 "PATH",
234 ),
235 opt(Stable, Opt, "o", "out-dir", "which directory to place the output", "PATH"),
236 opt(Stable, Opt, "", "crate-name", "specify the name of this crate", "NAME"),
237 make_crate_type_option(),
238 opt(Stable, Multi, "L", "library-path", "directory to add to crate search path", "DIR"),
239 opt(Stable, Multi, "", "cfg", "pass a --cfg to rustc", ""),
240 opt(Stable, Multi, "", "check-cfg", "pass a --check-cfg to rustc", ""),
241 opt(Stable, Multi, "", "extern", "pass an --extern to rustc", "NAME[=PATH]"),
242 opt(
243 Unstable,
244 Multi,
245 "",
246 "extern-html-root-url",
247 "base URL to use for dependencies; for example, \
248 \"std=/doc\" links std::vec::Vec to /doc/std/vec/struct.Vec.html",
249 "NAME=URL",
250 ),
251 opt(
252 Unstable,
253 FlagMulti,
254 "",
255 "extern-html-root-takes-precedence",
256 "give precedence to `--extern-html-root-url`, not `html_root_url`",
257 "",
258 ),
259 opt(Stable, Multi, "C", "codegen", "pass a codegen option to rustc", "OPT[=VALUE]"),
260 opt(Stable, FlagMulti, "", "document-private-items", "document private items", ""),
261 opt(
262 Unstable,
263 FlagMulti,
264 "",
265 "document-hidden-items",
266 "document items that have doc(hidden)",
267 "",
268 ),
269 opt(Stable, FlagMulti, "", "test", "run code examples as tests", ""),
270 opt(Stable, Multi, "", "test-args", "arguments to pass to the test runner", "ARGS"),
271 opt(
272 Stable,
273 Opt,
274 "",
275 "test-run-directory",
276 "The working directory in which to run tests",
277 "PATH",
278 ),
279 opt(Stable, Opt, "", "target", "target triple to document", "TRIPLE"),
280 opt(
281 Stable,
282 Multi,
283 "",
284 "markdown-css",
285 "CSS files to include via <link> in a rendered Markdown file",
286 "FILES",
287 ),
288 opt(
289 Stable,
290 Multi,
291 "",
292 "html-in-header",
293 "files to include inline in the <head> section of a rendered Markdown file \
294 or generated documentation",
295 "FILES",
296 ),
297 opt(
298 Stable,
299 Multi,
300 "",
301 "html-before-content",
302 "files to include inline between <body> and the content of a rendered \
303 Markdown file or generated documentation",
304 "FILES",
305 ),
306 opt(
307 Stable,
308 Multi,
309 "",
310 "html-after-content",
311 "files to include inline between the content and </body> of a rendered \
312 Markdown file or generated documentation",
313 "FILES",
314 ),
315 opt(
316 Unstable,
317 Multi,
318 "",
319 "markdown-before-content",
320 "files to include inline between <body> and the content of a rendered \
321 Markdown file or generated documentation",
322 "FILES",
323 ),
324 opt(
325 Unstable,
326 Multi,
327 "",
328 "markdown-after-content",
329 "files to include inline between the content and </body> of a rendered \
330 Markdown file or generated documentation",
331 "FILES",
332 ),
333 opt(Stable, Opt, "", "markdown-playground-url", "URL to send code snippets to", "URL"),
334 opt(Stable, FlagMulti, "", "markdown-no-toc", "don't include table of contents", ""),
335 opt(
336 Stable,
337 Opt,
338 "e",
339 "extend-css",
340 "To add some CSS rules with a given file to generate doc with your own theme. \
341 However, your theme might break if the rustdoc's generated HTML changes, so be careful!",
342 "PATH",
343 ),
344 opt(
345 Unstable,
346 Multi,
347 "Z",
348 "",
349 "unstable / perma-unstable options (only on nightly build)",
350 "FLAG",
351 ),
352 opt(Stable, Opt, "", "sysroot", "Override the system root", "PATH"),
353 opt(
354 Unstable,
355 Opt,
356 "",
357 "playground-url",
358 "URL to send code snippets to, may be reset by --markdown-playground-url \
359 or `#![doc(html_playground_url=...)]`",
360 "URL",
361 ),
362 opt(
363 Unstable,
364 FlagMulti,
365 "",
366 "display-doctest-warnings",
367 "show warnings that originate in doctests",
368 "",
369 ),
370 opt(
371 Stable,
372 Opt,
373 "",
374 "crate-version",
375 "crate version to print into documentation",
376 "VERSION",
377 ),
378 opt(
379 Unstable,
380 FlagMulti,
381 "",
382 "sort-modules-by-appearance",
383 "sort modules by where they appear in the program, rather than alphabetically",
384 "",
385 ),
386 opt(
387 Stable,
388 Opt,
389 "",
390 "default-theme",
391 "Set the default theme. THEME should be the theme name, generally lowercase. \
392 If an unknown default theme is specified, the builtin default is used. \
393 The set of themes, and the rustdoc built-in default, are not stable.",
394 "THEME",
395 ),
396 opt(
397 Unstable,
398 Multi,
399 "",
400 "default-setting",
401 "Default value for a rustdoc setting (used when \"rustdoc-SETTING\" is absent \
402 from web browser Local Storage). If VALUE is not supplied, \"true\" is used. \
403 Supported SETTINGs and VALUEs are not documented and not stable.",
404 "SETTING[=VALUE]",
405 ),
406 opt(
407 Stable,
408 Multi,
409 "",
410 "theme",
411 "additional themes which will be added to the generated docs",
412 "FILES",
413 ),
414 opt(Stable, Multi, "", "check-theme", "check if given theme is valid", "FILES"),
415 opt(
416 Unstable,
417 Opt,
418 "",
419 "resource-suffix",
420 "suffix to add to CSS and JavaScript files, \
421 e.g., \"search-index.js\" will become \"search-index-suffix.js\"",
422 "PATH",
423 ),
424 opt(
425 Stable,
426 Opt,
427 "",
428 "edition",
429 "edition to use when compiling rust code (default: 2015)",
430 "EDITION",
431 ),
432 opt(
433 Stable,
434 Opt,
435 "",
436 "color",
437 "Configure coloring of output:
438 auto = colorize, if output goes to a tty (default);
439 always = always colorize output;
440 never = never colorize output",
441 "auto|always|never",
442 ),
443 opt(
444 Stable,
445 Opt,
446 "",
447 "error-format",
448 "How errors and other messages are produced",
449 "human|json|short",
450 ),
451 opt(
452 Stable,
453 Opt,
454 "",
455 "diagnostic-width",
456 "Provide width of the output for truncated error messages",
457 "WIDTH",
458 ),
459 opt(Stable, Opt, "", "json", "Configure the structure of JSON diagnostics", "CONFIG"),
460 opt(Stable, Multi, "A", "allow", "Set lint allowed", "LINT"),
461 opt(Stable, Multi, "W", "warn", "Set lint warnings", "LINT"),
462 opt(Stable, Multi, "", "force-warn", "Set lint force-warn", "LINT"),
463 opt(Stable, Multi, "D", "deny", "Set lint denied", "LINT"),
464 opt(Stable, Multi, "F", "forbid", "Set lint forbidden", "LINT"),
465 opt(
466 Stable,
467 Multi,
468 "",
469 "cap-lints",
470 "Set the most restrictive lint level. \
471 More restrictive lints are capped at this level. \
472 By default, it is at `forbid` level.",
473 "LEVEL",
474 ),
475 opt(Unstable, Opt, "", "index-page", "Markdown file to be used as index page", "PATH"),
476 opt(
477 Unstable,
478 FlagMulti,
479 "",
480 "enable-index-page",
481 "To enable generation of the index page",
482 "",
483 ),
484 opt(
485 Unstable,
486 Opt,
487 "",
488 "static-root-path",
489 "Path string to force loading static files from in output pages. \
490 If not set, uses combinations of '../' to reach the documentation root.",
491 "PATH",
492 ),
493 opt(
494 Unstable,
495 Opt,
496 "",
497 "persist-doctests",
498 "Directory to persist doctest executables into",
499 "PATH",
500 ),
501 opt(
502 Unstable,
503 FlagMulti,
504 "",
505 "show-coverage",
506 "calculate percentage of public items with documentation",
507 "",
508 ),
509 opt(
510 Unstable,
511 FlagMulti,
512 "",
513 "enable-per-target-ignores",
514 "parse ignore-foo for ignoring doctests on a per-target basis",
515 "",
516 ),
517 opt(
518 Unstable,
519 Opt,
520 "",
521 "runtool",
522 "",
523 "The tool to run tests with when building for a different target than host",
524 ),
525 opt(
526 Unstable,
527 Multi,
528 "",
529 "runtool-arg",
530 "",
531 "One (of possibly many) arguments to pass to the runtool",
532 ),
533 opt(
534 Unstable,
535 Opt,
536 "",
537 "test-builder",
538 "The rustc-like binary to use as the test builder",
539 "PATH",
540 ),
541 opt(
542 Unstable,
543 Multi,
544 "",
545 "test-builder-wrapper",
546 "Wrapper program to pass test-builder and arguments",
547 "PATH",
548 ),
549 opt(Unstable, FlagMulti, "", "check", "Run rustdoc checks", ""),
550 opt(
551 Unstable,
552 FlagMulti,
553 "",
554 "generate-redirect-map",
555 "Generate JSON file at the top level instead of generating HTML redirection files",
556 "",
557 ),
558 opt(
559 Unstable,
560 Multi,
561 "",
562 "emit",
563 "Comma separated list of types of output for rustdoc to emit",
564 "[unversioned-shared-resources,toolchain-shared-resources,invocation-specific,dep-info]",
565 ),
566 opt(Unstable, FlagMulti, "", "no-run", "Compile doctests without running them", ""),
567 opt(
568 Unstable,
569 Multi,
570 "",
571 "remap-path-prefix",
572 "Remap source names in compiler messages",
573 "FROM=TO",
574 ),
575 opt(
576 Unstable,
577 FlagMulti,
578 "",
579 "show-type-layout",
580 "Include the memory layout of types in the docs",
581 "",
582 ),
583 opt(Unstable, Flag, "", "nocapture", "Don't capture stdout and stderr of tests", ""),
584 opt(
585 Unstable,
586 Flag,
587 "",
588 "generate-link-to-definition",
589 "Make the identifiers in the HTML source code pages navigable",
590 "",
591 ),
592 opt(
593 Unstable,
594 Opt,
595 "",
596 "scrape-examples-output-path",
597 "",
598 "collect function call information and output at the given path",
599 ),
600 opt(
601 Unstable,
602 Multi,
603 "",
604 "scrape-examples-target-crate",
605 "",
606 "collect function call information for functions from the target crate",
607 ),
608 opt(Unstable, Flag, "", "scrape-tests", "Include test code when scraping examples", ""),
609 opt(
610 Unstable,
611 Multi,
612 "",
613 "with-examples",
614 "",
615 "path to function call information (for displaying examples in the documentation)",
616 ),
617 opt(
618 Unstable,
619 Opt,
620 "",
621 "merge",
622 "Controls how rustdoc handles files from previously documented crates in the doc root\n\
623 none = Do not write cross-crate information to the --out-dir\n\
624 shared = Append current crate's info to files found in the --out-dir\n\
625 finalize = Write current crate's info and --include-parts-dir info to the --out-dir, overwriting conflicting files",
626 "none|shared|finalize",
627 ),
628 opt(
629 Unstable,
630 Opt,
631 "",
632 "parts-out-dir",
633 "Writes trait implementations and other info for the current crate to provided path. Only use with --merge=none",
634 "path/to/doc.parts/<crate-name>",
635 ),
636 opt(
637 Unstable,
638 Multi,
639 "",
640 "include-parts-dir",
641 "Includes trait implementations and other crate info from provided path. Only use with --merge=finalize",
642 "path/to/doc.parts/<crate-name>",
643 ),
644 opt(Unstable, Flag, "", "html-no-source", "Disable HTML source code pages generation", ""),
645 opt(
646 Unstable,
647 Multi,
648 "",
649 "doctest-compilation-args",
650 "",
651 "add arguments to be used when compiling doctests",
652 ),
653 opt(
654 Unstable,
655 FlagMulti,
656 "",
657 "disable-minification",
658 "disable the minification of CSS/JS files (perma-unstable, do not use with cached files)",
659 "",
660 ),
661 opt(
663 Stable,
664 Multi,
665 "",
666 "plugin-path",
667 "removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information",
668 "DIR",
669 ),
670 opt(
671 Stable,
672 Multi,
673 "",
674 "passes",
675 "removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information",
676 "PASSES",
677 ),
678 opt(
679 Stable,
680 Multi,
681 "",
682 "plugins",
683 "removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information",
684 "PLUGINS",
685 ),
686 opt(
687 Stable,
688 FlagMulti,
689 "",
690 "no-defaults",
691 "removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information",
692 "",
693 ),
694 opt(
695 Stable,
696 Opt,
697 "r",
698 "input-format",
699 "removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information",
700 "[rust]",
701 ),
702 ]
703}
704
705fn usage(argv0: &str) {
706 let mut options = getopts::Options::new();
707 for option in opts() {
708 option.apply(&mut options);
709 }
710 println!("{}", options.usage(&format!("{argv0} [options] <input>")));
711 println!(" @path Read newline separated options from `path`\n");
712 println!(
713 "More information available at {DOC_RUST_LANG_ORG_VERSION}/rustdoc/what-is-rustdoc.html",
714 );
715}
716
717pub(crate) fn wrap_return(dcx: DiagCtxtHandle<'_>, res: Result<(), String>) {
718 match res {
719 Ok(()) => dcx.abort_if_errors(),
720 Err(err) => dcx.fatal(err),
721 }
722}
723
724fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>(
725 krate: clean::Crate,
726 renderopts: config::RenderOptions,
727 cache: formats::cache::Cache,
728 tcx: TyCtxt<'tcx>,
729) {
730 match formats::run_format::<T>(krate, renderopts, cache, tcx) {
731 Ok(_) => tcx.dcx().abort_if_errors(),
732 Err(e) => {
733 let mut msg =
734 tcx.dcx().struct_fatal(format!("couldn't generate documentation: {}", e.error));
735 let file = e.file.display().to_string();
736 if !file.is_empty() {
737 msg.note(format!("failed to create or modify \"{file}\""));
738 }
739 msg.emit();
740 }
741 }
742}
743
744fn run_merge_finalize(opt: config::RenderOptions) -> Result<(), error::Error> {
748 assert!(
749 opt.should_merge.write_rendered_cci,
750 "config.rs only allows us to return InputMode::NoInputMergeFinalize if --merge=finalize"
751 );
752 assert!(
753 !opt.should_merge.read_rendered_cci,
754 "config.rs only allows us to return InputMode::NoInputMergeFinalize if --merge=finalize"
755 );
756 let crates = html::render::CrateInfo::read_many(&opt.include_parts_dir)?;
757 let include_sources = !opt.html_no_source;
758 html::render::write_not_crate_specific(
759 &crates,
760 &opt.output,
761 &opt,
762 &opt.themes,
763 opt.extension_css.as_deref(),
764 &opt.resource_suffix,
765 include_sources,
766 )?;
767 Ok(())
768}
769
770fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
771 let at_args = at_args.get(1..).unwrap_or_default();
780
781 let args = rustc_driver::args::arg_expand_all(early_dcx, at_args);
782
783 let mut options = getopts::Options::new();
784 for option in opts() {
785 option.apply(&mut options);
786 }
787 let matches = match options.parse(&args) {
788 Ok(m) => m,
789 Err(err) => {
790 early_dcx.early_fatal(err.to_string());
791 }
792 };
793
794 let (input, options, render_options) =
797 match config::Options::from_matches(early_dcx, &matches, args) {
798 Some(opts) => opts,
799 None => return,
800 };
801
802 let dcx =
803 core::new_dcx(options.error_format, None, options.diagnostic_width, &options.unstable_opts);
804 let dcx = dcx.handle();
805
806 let input = match input {
807 config::InputMode::HasFile(input) => input,
808 config::InputMode::NoInputMergeFinalize => {
809 return wrap_return(
810 dcx,
811 run_merge_finalize(render_options)
812 .map_err(|e| format!("could not write merged cross-crate info: {e}")),
813 );
814 }
815 };
816
817 let output_format = options.output_format;
818
819 match (
820 options.should_test || output_format == config::OutputFormat::Doctest,
821 config::markdown_input(&input),
822 ) {
823 (true, Some(_)) => return wrap_return(dcx, doctest::test_markdown(&input, options)),
824 (true, None) => return doctest::run(dcx, input, options),
825 (false, Some(md_input)) => {
826 let md_input = md_input.to_owned();
827 let edition = options.edition;
828 let config = core::create_config(input, options, &render_options);
829
830 return wrap_return(
834 dcx,
835 interface::run_compiler(config, |_compiler| {
836 markdown::render_and_write(&md_input, render_options, edition)
837 }),
838 );
839 }
840 (false, None) => {}
841 }
842
843 let show_coverage = options.show_coverage;
846 let run_check = options.run_check;
847
848 info!("starting to run rustc");
850
851 let crate_version = options.crate_version.clone();
856
857 let scrape_examples_options = options.scrape_examples_options.clone();
858 let bin_crate = options.bin_crate;
859
860 let config = core::create_config(input, options, &render_options);
861
862 let registered_lints = config.register_lints.is_some();
863
864 interface::run_compiler(config, |compiler| {
865 let sess = &compiler.sess;
866
867 if sess.opts.describe_lints {
868 rustc_driver::describe_lints(sess, registered_lints);
869 return;
870 }
871
872 let krate = rustc_interface::passes::parse(sess);
873 rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| {
874 if sess.dcx().has_errors().is_some() {
875 sess.dcx().fatal("Compilation failed, aborting rustdoc");
876 }
877
878 let (krate, render_opts, mut cache) = sess.time("run_global_ctxt", || {
879 core::run_global_ctxt(tcx, show_coverage, render_options, output_format)
880 });
881 info!("finished with rustc");
882
883 if let Some(options) = scrape_examples_options {
884 return scrape_examples::run(krate, render_opts, cache, tcx, options, bin_crate);
885 }
886
887 cache.crate_version = crate_version;
888
889 if show_coverage {
890 return;
893 }
894
895 if render_opts.dep_info().is_some() {
896 rustc_interface::passes::write_dep_info(tcx);
897 }
898
899 if run_check {
900 return;
902 }
903
904 info!("going to format");
905 match output_format {
906 config::OutputFormat::Html => sess.time("render_html", || {
907 run_renderer::<html::render::Context<'_>>(krate, render_opts, cache, tcx)
908 }),
909 config::OutputFormat::Json => sess.time("render_json", || {
910 run_renderer::<json::JsonRenderer<'_>>(krate, render_opts, cache, tcx)
911 }),
912 config::OutputFormat::Doctest => unreachable!(),
914 }
915 })
916 })
917}