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 Stable,
511 Opt,
512 "",
513 "test-runtool",
514 "",
515 "The tool to run tests with when building for a different target than host",
516 ),
517 opt(
518 Stable,
519 Multi,
520 "",
521 "test-runtool-arg",
522 "",
523 "One argument (of possibly many) to pass to the runtool",
524 ),
525 opt(
526 Unstable,
527 Opt,
528 "",
529 "test-builder",
530 "The rustc-like binary to use as the test builder",
531 "PATH",
532 ),
533 opt(
534 Unstable,
535 Multi,
536 "",
537 "test-builder-wrapper",
538 "Wrapper program to pass test-builder and arguments",
539 "PATH",
540 ),
541 opt(Unstable, FlagMulti, "", "check", "Run rustdoc checks", ""),
542 opt(
543 Unstable,
544 FlagMulti,
545 "",
546 "generate-redirect-map",
547 "Generate JSON file at the top level instead of generating HTML redirection files",
548 "",
549 ),
550 opt(
551 Unstable,
552 Multi,
553 "",
554 "emit",
555 "Comma separated list of types of output for rustdoc to emit",
556 "[unversioned-shared-resources,toolchain-shared-resources,invocation-specific,dep-info]",
557 ),
558 opt(Unstable, FlagMulti, "", "no-run", "Compile doctests without running them", ""),
559 opt(
560 Unstable,
561 Multi,
562 "",
563 "remap-path-prefix",
564 "Remap source names in compiler messages",
565 "FROM=TO",
566 ),
567 opt(
568 Unstable,
569 FlagMulti,
570 "",
571 "show-type-layout",
572 "Include the memory layout of types in the docs",
573 "",
574 ),
575 opt(Unstable, Flag, "", "nocapture", "Don't capture stdout and stderr of tests", ""),
576 opt(
577 Unstable,
578 Flag,
579 "",
580 "generate-link-to-definition",
581 "Make the identifiers in the HTML source code pages navigable",
582 "",
583 ),
584 opt(
585 Unstable,
586 Opt,
587 "",
588 "scrape-examples-output-path",
589 "",
590 "collect function call information and output at the given path",
591 ),
592 opt(
593 Unstable,
594 Multi,
595 "",
596 "scrape-examples-target-crate",
597 "",
598 "collect function call information for functions from the target crate",
599 ),
600 opt(Unstable, Flag, "", "scrape-tests", "Include test code when scraping examples", ""),
601 opt(
602 Unstable,
603 Multi,
604 "",
605 "with-examples",
606 "",
607 "path to function call information (for displaying examples in the documentation)",
608 ),
609 opt(
610 Unstable,
611 Opt,
612 "",
613 "merge",
614 "Controls how rustdoc handles files from previously documented crates in the doc root\n\
615 none = Do not write cross-crate information to the --out-dir\n\
616 shared = Append current crate's info to files found in the --out-dir\n\
617 finalize = Write current crate's info and --include-parts-dir info to the --out-dir, overwriting conflicting files",
618 "none|shared|finalize",
619 ),
620 opt(
621 Unstable,
622 Opt,
623 "",
624 "parts-out-dir",
625 "Writes trait implementations and other info for the current crate to provided path. Only use with --merge=none",
626 "path/to/doc.parts/<crate-name>",
627 ),
628 opt(
629 Unstable,
630 Multi,
631 "",
632 "include-parts-dir",
633 "Includes trait implementations and other crate info from provided path. Only use with --merge=finalize",
634 "path/to/doc.parts/<crate-name>",
635 ),
636 opt(Unstable, Flag, "", "html-no-source", "Disable HTML source code pages generation", ""),
637 opt(
638 Unstable,
639 Multi,
640 "",
641 "doctest-compilation-args",
642 "",
643 "add arguments to be used when compiling doctests",
644 ),
645 opt(
646 Unstable,
647 FlagMulti,
648 "",
649 "disable-minification",
650 "disable the minification of CSS/JS files (perma-unstable, do not use with cached files)",
651 "",
652 ),
653 opt(
655 Stable,
656 Multi,
657 "",
658 "plugin-path",
659 "removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information",
660 "DIR",
661 ),
662 opt(
663 Stable,
664 Multi,
665 "",
666 "passes",
667 "removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information",
668 "PASSES",
669 ),
670 opt(
671 Stable,
672 Multi,
673 "",
674 "plugins",
675 "removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information",
676 "PLUGINS",
677 ),
678 opt(
679 Stable,
680 FlagMulti,
681 "",
682 "no-defaults",
683 "removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information",
684 "",
685 ),
686 opt(
687 Stable,
688 Opt,
689 "r",
690 "input-format",
691 "removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information",
692 "[rust]",
693 ),
694 ]
695}
696
697fn usage(argv0: &str) {
698 let mut options = getopts::Options::new();
699 for option in opts() {
700 option.apply(&mut options);
701 }
702 println!("{}", options.usage(&format!("{argv0} [options] <input>")));
703 println!(" @path Read newline separated options from `path`\n");
704 println!(
705 "More information available at {DOC_RUST_LANG_ORG_VERSION}/rustdoc/what-is-rustdoc.html",
706 );
707}
708
709pub(crate) fn wrap_return(dcx: DiagCtxtHandle<'_>, res: Result<(), String>) {
710 match res {
711 Ok(()) => dcx.abort_if_errors(),
712 Err(err) => dcx.fatal(err),
713 }
714}
715
716fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>(
717 krate: clean::Crate,
718 renderopts: config::RenderOptions,
719 cache: formats::cache::Cache,
720 tcx: TyCtxt<'tcx>,
721) {
722 match formats::run_format::<T>(krate, renderopts, cache, tcx) {
723 Ok(_) => tcx.dcx().abort_if_errors(),
724 Err(e) => {
725 let mut msg =
726 tcx.dcx().struct_fatal(format!("couldn't generate documentation: {}", e.error));
727 let file = e.file.display().to_string();
728 if !file.is_empty() {
729 msg.note(format!("failed to create or modify \"{file}\""));
730 }
731 msg.emit();
732 }
733 }
734}
735
736fn run_merge_finalize(opt: config::RenderOptions) -> Result<(), error::Error> {
740 assert!(
741 opt.should_merge.write_rendered_cci,
742 "config.rs only allows us to return InputMode::NoInputMergeFinalize if --merge=finalize"
743 );
744 assert!(
745 !opt.should_merge.read_rendered_cci,
746 "config.rs only allows us to return InputMode::NoInputMergeFinalize if --merge=finalize"
747 );
748 let crates = html::render::CrateInfo::read_many(&opt.include_parts_dir)?;
749 let include_sources = !opt.html_no_source;
750 html::render::write_not_crate_specific(
751 &crates,
752 &opt.output,
753 &opt,
754 &opt.themes,
755 opt.extension_css.as_deref(),
756 &opt.resource_suffix,
757 include_sources,
758 )?;
759 Ok(())
760}
761
762fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
763 let at_args = at_args.get(1..).unwrap_or_default();
772
773 let args = rustc_driver::args::arg_expand_all(early_dcx, at_args);
774
775 let mut options = getopts::Options::new();
776 for option in opts() {
777 option.apply(&mut options);
778 }
779 let matches = match options.parse(&args) {
780 Ok(m) => m,
781 Err(err) => {
782 early_dcx.early_fatal(err.to_string());
783 }
784 };
785
786 let (input, options, render_options) =
789 match config::Options::from_matches(early_dcx, &matches, args) {
790 Some(opts) => opts,
791 None => return,
792 };
793
794 let dcx =
795 core::new_dcx(options.error_format, None, options.diagnostic_width, &options.unstable_opts);
796 let dcx = dcx.handle();
797
798 let input = match input {
799 config::InputMode::HasFile(input) => input,
800 config::InputMode::NoInputMergeFinalize => {
801 return wrap_return(
802 dcx,
803 run_merge_finalize(render_options)
804 .map_err(|e| format!("could not write merged cross-crate info: {e}")),
805 );
806 }
807 };
808
809 let output_format = options.output_format;
810
811 match (
812 options.should_test || output_format == config::OutputFormat::Doctest,
813 config::markdown_input(&input),
814 ) {
815 (true, Some(_)) => return wrap_return(dcx, doctest::test_markdown(&input, options)),
816 (true, None) => return doctest::run(dcx, input, options),
817 (false, Some(md_input)) => {
818 let md_input = md_input.to_owned();
819 let edition = options.edition;
820 let config = core::create_config(input, options, &render_options);
821
822 return wrap_return(
826 dcx,
827 interface::run_compiler(config, |_compiler| {
828 markdown::render_and_write(&md_input, render_options, edition)
829 }),
830 );
831 }
832 (false, None) => {}
833 }
834
835 let show_coverage = options.show_coverage;
838 let run_check = options.run_check;
839
840 info!("starting to run rustc");
842
843 let crate_version = options.crate_version.clone();
848
849 let scrape_examples_options = options.scrape_examples_options.clone();
850 let bin_crate = options.bin_crate;
851
852 let config = core::create_config(input, options, &render_options);
853
854 let registered_lints = config.register_lints.is_some();
855
856 interface::run_compiler(config, |compiler| {
857 let sess = &compiler.sess;
858
859 if sess.opts.describe_lints {
860 rustc_driver::describe_lints(sess, registered_lints);
861 return;
862 }
863
864 let krate = rustc_interface::passes::parse(sess);
865 rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| {
866 if sess.dcx().has_errors().is_some() {
867 sess.dcx().fatal("Compilation failed, aborting rustdoc");
868 }
869
870 let (krate, render_opts, mut cache) = sess.time("run_global_ctxt", || {
871 core::run_global_ctxt(tcx, show_coverage, render_options, output_format)
872 });
873 info!("finished with rustc");
874
875 if let Some(options) = scrape_examples_options {
876 return scrape_examples::run(krate, render_opts, cache, tcx, options, bin_crate);
877 }
878
879 cache.crate_version = crate_version;
880
881 if show_coverage {
882 return;
885 }
886
887 if render_opts.dep_info().is_some() {
888 rustc_interface::passes::write_dep_info(tcx);
889 }
890
891 if run_check {
892 return;
894 }
895
896 info!("going to format");
897 match output_format {
898 config::OutputFormat::Html => sess.time("render_html", || {
899 run_renderer::<html::render::Context<'_>>(krate, render_opts, cache, tcx)
900 }),
901 config::OutputFormat::Json => sess.time("render_json", || {
902 run_renderer::<json::JsonRenderer<'_>>(krate, render_opts, cache, tcx)
903 }),
904 config::OutputFormat::Doctest => unreachable!(),
906 }
907 })
908 })
909}