]> git.proxmox.com Git - rustc.git/blame - src/librustdoc/lib.rs
New upstream version 1.50.0+dfsg1
[rustc.git] / src / librustdoc / lib.rs
CommitLineData
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]
23extern crate lazy_static;
1b1a35ee
XL
24#[macro_use]
25extern 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
34extern crate rustc_ast;
35extern crate rustc_ast_pretty;
36extern crate rustc_attr;
9e0c209e 37extern crate rustc_data_structures;
1a4d82fc 38extern crate rustc_driver;
dfeec247
XL
39extern crate rustc_errors;
40extern crate rustc_expand;
60c5eb7d 41extern crate rustc_feature;
dfeec247 42extern crate rustc_hir;
ba9703b0 43extern crate rustc_hir_pretty;
60c5eb7d 44extern crate rustc_index;
74b04a01 45extern crate rustc_infer;
532ac7d7 46extern crate rustc_interface;
60c5eb7d
XL
47extern crate rustc_lexer;
48extern crate rustc_lint;
92a42be0 49extern crate rustc_metadata;
ba9703b0 50extern crate rustc_middle;
dfeec247 51extern crate rustc_mir;
60c5eb7d
XL
52extern crate rustc_parse;
53extern crate rustc_resolve;
dfeec247
XL
54extern crate rustc_session;
55extern crate rustc_span as rustc_span;
83c7162d 56extern crate rustc_target;
ba9703b0 57extern crate rustc_trait_selection;
7cac9316 58extern crate rustc_typeck;
c34b1796 59extern crate test as testing;
1a4d82fc 60
9cc50fc6 61use std::default::Default;
85aaf69f 62use std::env;
62682a34 63use std::process;
c34b1796 64
fc512014 65use rustc_driver::abort_on_err;
3dfed10e 66use rustc_errors::ErrorReported;
fc512014
XL
67use rustc_interface::interface;
68use rustc_middle::ty;
ba9703b0
XL
69use rustc_session::config::{make_crate_type_option, ErrorOutputType, RustcOptGroup};
70use rustc_session::getopts;
71use rustc_session::{early_error, early_warn};
1a4d82fc
JJ
72
73#[macro_use]
8faf50e0 74mod externalfiles;
1a4d82fc 75
8faf50e0 76mod clean;
a1dfa0c6 77mod config;
8faf50e0 78mod core;
dc9dc135 79mod docfs;
8faf50e0 80mod doctree;
3dfed10e
XL
81#[macro_use]
82mod error;
1b1a35ee 83mod doctest;
8faf50e0 84mod fold;
3dfed10e
XL
85crate mod formats;
86pub mod html;
87mod json;
8faf50e0
XL
88mod markdown;
89mod passes;
8faf50e0 90mod theme;
60c5eb7d
XL
91mod visit_ast;
92mod visit_lib;
1a4d82fc 93
1a4d82fc 94pub 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 105fn 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 121fn 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 424fn 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()`.
434type MainResult = Result<(), ErrorReported>;
435
436fn 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 462fn 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 472fn 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 495fn 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}