提交 d8d3ab96 编写于 作者: B bors

Auto merge of #80090 - jyn514:tcx-in-render, r=GuillaumeGomez

Pass a `TyCtxt` through to `FormatRender`

This is the next step after https://github.com/rust-lang/rust/pull/79957 for https://github.com/rust-lang/rust/issues/76382. Eventually I plan to use this to remove `stability`, `const_stability`, and `deprecation` from `Item`, but that needs more extensive changes (in particular, https://github.com/rust-lang/rust/pull/75355 or something like it).

This has no actual changes to behavior, it's just moving types around.

ccc https://github.com/rust-lang/rust/pull/80014#issuecomment-746810284
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
intravisit::{self, NestedVisitorMap, Visitor}, intravisit::{self, NestedVisitorMap, Visitor},
Path, Path,
}; };
use rustc_interface::interface; use rustc_interface::{interface, Queries};
use rustc_middle::hir::map::Map; use rustc_middle::hir::map::Map;
use rustc_middle::middle::privacy::AccessLevels; use rustc_middle::middle::privacy::AccessLevels;
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
...@@ -273,12 +273,9 @@ pub(crate) fn init_lints<F>( ...@@ -273,12 +273,9 @@ pub(crate) fn init_lints<F>(
(lint_opts, lint_caps) (lint_opts, lint_caps)
} }
crate fn run_core( /// Parse, resolve, and typecheck the given crate.
options: RustdocOptions, crate fn create_config(
) -> (clean::Crate, RenderInfo, RenderOptions, Lrc<Session>) { RustdocOptions {
// Parse, resolve, and typecheck the given crate.
let RustdocOptions {
input, input,
crate_name, crate_name,
proc_macro_crate, proc_macro_crate,
...@@ -294,21 +291,10 @@ pub(crate) fn init_lints<F>( ...@@ -294,21 +291,10 @@ pub(crate) fn init_lints<F>(
lint_opts, lint_opts,
describe_lints, describe_lints,
lint_cap, lint_cap,
default_passes,
manual_passes,
display_warnings, display_warnings,
render_options,
output_format,
.. ..
} = options; }: RustdocOptions,
) -> rustc_interface::Config {
let extern_names: Vec<String> = externs
.iter()
.filter(|(_, entry)| entry.add_prelude)
.map(|(name, _)| name)
.cloned()
.collect();
// Add the doc cfg into the doc build. // Add the doc cfg into the doc build.
cfgs.push("doc".to_string()); cfgs.push("doc".to_string());
...@@ -374,7 +360,7 @@ pub(crate) fn init_lints<F>( ...@@ -374,7 +360,7 @@ pub(crate) fn init_lints<F>(
..Options::default() ..Options::default()
}; };
let config = interface::Config { interface::Config {
opts: sessopts, opts: sessopts,
crate_cfg: interface::parse_cfgspecs(cfgs), crate_cfg: interface::parse_cfgspecs(cfgs),
input, input,
...@@ -417,68 +403,50 @@ pub(crate) fn init_lints<F>( ...@@ -417,68 +403,50 @@ pub(crate) fn init_lints<F>(
}), }),
make_codegen_backend: None, make_codegen_backend: None,
registry: rustc_driver::diagnostics_registry(), registry: rustc_driver::diagnostics_registry(),
}; }
}
interface::create_compiler_and_run(config, |compiler| {
compiler.enter(|queries| {
let sess = compiler.session();
// We need to hold on to the complete resolver, so we cause everything to be
// cloned for the analysis passes to use. Suboptimal, but necessary in the
// current architecture.
let resolver = {
let parts = abort_on_err(queries.expansion(), sess).peek();
let resolver = parts.1.borrow();
// Before we actually clone it, let's force all the extern'd crates to
// actually be loaded, just in case they're only referred to inside
// intra-doc-links
resolver.borrow_mut().access(|resolver| {
sess.time("load_extern_crates", || {
for extern_name in &extern_names {
debug!("loading extern crate {}", extern_name);
resolver
.resolve_str_path_error(
DUMMY_SP,
extern_name,
TypeNS,
LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id(),
)
.unwrap_or_else(|()| {
panic!("Unable to resolve external crate {}", extern_name)
});
}
});
});
// Now we're good to clone the resolver because everything should be loaded crate fn create_resolver<'a>(
resolver.clone() externs: config::Externs,
}; queries: &Queries<'a>,
sess: &Session,
) -> Rc<RefCell<interface::BoxedResolver>> {
let extern_names: Vec<String> = externs
.iter()
.filter(|(_, entry)| entry.add_prelude)
.map(|(name, _)| name)
.cloned()
.collect();
if sess.has_errors() { let parts = abort_on_err(queries.expansion(), sess).peek();
sess.fatal("Compilation failed, aborting rustdoc"); let resolver = parts.1.borrow();
// Before we actually clone it, let's force all the extern'd crates to
// actually be loaded, just in case they're only referred to inside
// intra-doc-links
resolver.borrow_mut().access(|resolver| {
sess.time("load_extern_crates", || {
for extern_name in &extern_names {
debug!("loading extern crate {}", extern_name);
resolver
.resolve_str_path_error(
DUMMY_SP,
extern_name,
TypeNS,
LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id(),
)
.unwrap_or_else(|()| {
panic!("Unable to resolve external crate {}", extern_name)
});
} }
});
});
let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess).take(); // Now we're good to clone the resolver because everything should be loaded
resolver.clone()
let (krate, render_info, opts) = sess.time("run_global_ctxt", || {
global_ctxt.enter(|tcx| {
run_global_ctxt(
tcx,
resolver,
default_passes,
manual_passes,
render_options,
output_format,
)
})
});
(krate, render_info, opts, Lrc::clone(sess))
})
})
} }
fn run_global_ctxt( crate fn run_global_ctxt(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
resolver: Rc<RefCell<interface::BoxedResolver>>, resolver: Rc<RefCell<interface::BoxedResolver>>,
mut default_passes: passes::DefaultPassOption, mut default_passes: passes::DefaultPassOption,
......
use std::sync::Arc; use std::sync::Arc;
use rustc_data_structures::sync::Lrc; use rustc_middle::ty;
use rustc_session::Session;
use rustc_span::edition::Edition; use rustc_span::edition::Edition;
use crate::clean; use crate::clean;
...@@ -12,7 +11,7 @@ ...@@ -12,7 +11,7 @@
/// Allows for different backends to rustdoc to be used with the `run_format()` function. Each /// Allows for different backends to rustdoc to be used with the `run_format()` function. Each
/// backend renderer has hooks for initialization, documenting an item, entering and exiting a /// backend renderer has hooks for initialization, documenting an item, entering and exiting a
/// module, and cleanup/finalizing output. /// module, and cleanup/finalizing output.
crate trait FormatRenderer: Clone { crate trait FormatRenderer<'tcx>: Clone {
/// Sets up any state required for the renderer. When this is called the cache has already been /// Sets up any state required for the renderer. When this is called the cache has already been
/// populated. /// populated.
fn init( fn init(
...@@ -21,7 +20,7 @@ fn init( ...@@ -21,7 +20,7 @@ fn init(
render_info: RenderInfo, render_info: RenderInfo,
edition: Edition, edition: Edition,
cache: &mut Cache, cache: &mut Cache,
sess: Lrc<Session>, tcx: ty::TyCtxt<'tcx>,
) -> Result<(Self, clean::Crate), Error>; ) -> Result<(Self, clean::Crate), Error>;
/// Renders a single non-module item. This means no recursive sub-item rendering is required. /// Renders a single non-module item. This means no recursive sub-item rendering is required.
...@@ -46,13 +45,13 @@ fn mod_item_in( ...@@ -46,13 +45,13 @@ fn mod_item_in(
} }
/// Main method for rendering a crate. /// Main method for rendering a crate.
crate fn run_format<T: FormatRenderer>( crate fn run_format<'tcx, T: FormatRenderer<'tcx>>(
krate: clean::Crate, krate: clean::Crate,
options: RenderOptions, options: RenderOptions,
render_info: RenderInfo, render_info: RenderInfo,
diag: &rustc_errors::Handler, diag: &rustc_errors::Handler,
edition: Edition, edition: Edition,
sess: Lrc<Session>, tcx: ty::TyCtxt<'tcx>,
) -> Result<(), Error> { ) -> Result<(), Error> {
let (krate, mut cache) = Cache::from_krate( let (krate, mut cache) = Cache::from_krate(
render_info.clone(), render_info.clone(),
...@@ -63,7 +62,7 @@ fn mod_item_in( ...@@ -63,7 +62,7 @@ fn mod_item_in(
); );
let (mut format_renderer, mut krate) = let (mut format_renderer, mut krate) =
T::init(krate, options, render_info, edition, &mut cache, sess)?; T::init(krate, options, render_info, edition, &mut cache, tcx)?;
let cache = Arc::new(cache); let cache = Arc::new(cache);
// Freeze the cache now that the index has been built. Put an Arc into TLS for future // Freeze the cache now that the index has been built. Put an Arc into TLS for future
......
...@@ -52,11 +52,12 @@ ...@@ -52,11 +52,12 @@
use rustc_attr::{Deprecation, StabilityLevel}; use rustc_attr::{Deprecation, StabilityLevel};
use rustc_data_structures::flock; use rustc_data_structures::flock;
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::Lrc;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::Mutability; use rustc_hir::Mutability;
use rustc_middle::middle::stability; use rustc_middle::middle::stability;
use rustc_middle::ty;
use rustc_middle::ty::TyCtxt;
use rustc_session::Session; use rustc_session::Session;
use rustc_span::edition::Edition; use rustc_span::edition::Edition;
use rustc_span::hygiene::MacroKind; use rustc_span::hygiene::MacroKind;
...@@ -102,7 +103,7 @@ ...@@ -102,7 +103,7 @@
/// easily cloned because it is cloned per work-job (about once per item in the /// easily cloned because it is cloned per work-job (about once per item in the
/// rustdoc tree). /// rustdoc tree).
#[derive(Clone)] #[derive(Clone)]
crate struct Context { crate struct Context<'tcx> {
/// Current hierarchy of components leading down to what's currently being /// Current hierarchy of components leading down to what's currently being
/// rendered /// rendered
crate current: Vec<String>, crate current: Vec<String>,
...@@ -115,15 +116,15 @@ ...@@ -115,15 +116,15 @@
crate render_redirect_pages: bool, crate render_redirect_pages: bool,
/// The map used to ensure all generated 'id=' attributes are unique. /// The map used to ensure all generated 'id=' attributes are unique.
id_map: Rc<RefCell<IdMap>>, id_map: Rc<RefCell<IdMap>>,
crate shared: Arc<SharedContext>, crate shared: Arc<SharedContext<'tcx>>,
all: Rc<RefCell<AllTypes>>, all: Rc<RefCell<AllTypes>>,
/// Storage for the errors produced while generating documentation so they /// Storage for the errors produced while generating documentation so they
/// can be printed together at the end. /// can be printed together at the end.
crate errors: Rc<Receiver<String>>, crate errors: Rc<Receiver<String>>,
} }
crate struct SharedContext { crate struct SharedContext<'tcx> {
crate sess: Lrc<Session>, crate tcx: TyCtxt<'tcx>,
/// The path to the crate root source minus the file name. /// The path to the crate root source minus the file name.
/// Used for simplifying paths to the highlighted source code files. /// Used for simplifying paths to the highlighted source code files.
crate src_root: PathBuf, crate src_root: PathBuf,
...@@ -163,7 +164,7 @@ ...@@ -163,7 +164,7 @@
playground: Option<markdown::Playground>, playground: Option<markdown::Playground>,
} }
impl Context { impl Context<'_> {
fn path(&self, filename: &str) -> PathBuf { fn path(&self, filename: &str) -> PathBuf {
// We use splitn vs Path::extension here because we might get a filename // We use splitn vs Path::extension here because we might get a filename
// like `style.min.css` and we want to process that into // like `style.min.css` and we want to process that into
...@@ -176,11 +177,11 @@ fn path(&self, filename: &str) -> PathBuf { ...@@ -176,11 +177,11 @@ fn path(&self, filename: &str) -> PathBuf {
} }
fn sess(&self) -> &Session { fn sess(&self) -> &Session {
&self.shared.sess &self.shared.tcx.sess
} }
} }
impl SharedContext { impl SharedContext<'_> {
crate fn ensure_dir(&self, dst: &Path) -> Result<(), Error> { crate fn ensure_dir(&self, dst: &Path) -> Result<(), Error> {
let mut dirs = self.created_dirs.borrow_mut(); let mut dirs = self.created_dirs.borrow_mut();
if !dirs.contains(dst) { if !dirs.contains(dst) {
...@@ -381,15 +382,15 @@ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> ...@@ -381,15 +382,15 @@ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
} }
/// Generates the documentation for `crate` into the directory `dst` /// Generates the documentation for `crate` into the directory `dst`
impl FormatRenderer for Context { impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
fn init( fn init(
mut krate: clean::Crate, mut krate: clean::Crate,
options: RenderOptions, options: RenderOptions,
_render_info: RenderInfo, _render_info: RenderInfo,
edition: Edition, edition: Edition,
cache: &mut Cache, cache: &mut Cache,
sess: Lrc<Session>, tcx: ty::TyCtxt<'tcx>,
) -> Result<(Context, clean::Crate), Error> { ) -> Result<(Self, clean::Crate), Error> {
// need to save a copy of the options for rendering the index page // need to save a copy of the options for rendering the index page
let md_opts = options.clone(); let md_opts = options.clone();
let RenderOptions { let RenderOptions {
...@@ -462,7 +463,7 @@ fn init( ...@@ -462,7 +463,7 @@ fn init(
} }
let (sender, receiver) = channel(); let (sender, receiver) = channel();
let mut scx = SharedContext { let mut scx = SharedContext {
sess, tcx,
collapsed: krate.collapsed, collapsed: krate.collapsed,
src_root, src_root,
include_sources, include_sources,
...@@ -688,7 +689,7 @@ fn item(&mut self, item: clean::Item, cache: &Cache) -> Result<(), Error> { ...@@ -688,7 +689,7 @@ fn item(&mut self, item: clean::Item, cache: &Cache) -> Result<(), Error> {
} }
fn write_shared( fn write_shared(
cx: &Context, cx: &Context<'_>,
krate: &clean::Crate, krate: &clean::Crate,
search_index: String, search_index: String,
options: &RenderOptions, options: &RenderOptions,
...@@ -1205,7 +1206,7 @@ fn write_minify( ...@@ -1205,7 +1206,7 @@ fn write_minify(
} }
} }
fn write_srclink(cx: &Context, item: &clean::Item, buf: &mut Buffer, cache: &Cache) { fn write_srclink(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer, cache: &Cache) {
if let Some(l) = cx.src_href(item, cache) { if let Some(l) = cx.src_href(item, cache) {
write!( write!(
buf, buf,
...@@ -1516,7 +1517,7 @@ fn settings(root_path: &str, suffix: &str, themes: &[StylePath]) -> Result<Strin ...@@ -1516,7 +1517,7 @@ fn settings(root_path: &str, suffix: &str, themes: &[StylePath]) -> Result<Strin
)) ))
} }
impl Context { impl Context<'_> {
fn derive_id(&self, id: String) -> String { fn derive_id(&self, id: String) -> String {
let mut map = self.id_map.borrow_mut(); let mut map = self.id_map.borrow_mut();
map.derive(id) map.derive(id)
...@@ -1701,7 +1702,7 @@ fn wrap_into_docblock<F>(w: &mut Buffer, f: F) ...@@ -1701,7 +1702,7 @@ fn wrap_into_docblock<F>(w: &mut Buffer, f: F)
write!(w, "</div>") write!(w, "</div>")
} }
fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer, cache: &Cache) { fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer, cache: &Cache) {
debug_assert!(!item.is_stripped()); debug_assert!(!item.is_stripped());
// Write the breadcrumb trail header for the top // Write the breadcrumb trail header for the top
write!(buf, "<h1 class=\"fqn\"><span class=\"out-of-band\">"); write!(buf, "<h1 class=\"fqn\"><span class=\"out-of-band\">");
...@@ -1816,14 +1817,14 @@ fn item_path(ty: ItemType, name: &str) -> String { ...@@ -1816,14 +1817,14 @@ fn item_path(ty: ItemType, name: &str) -> String {
} }
} }
fn full_path(cx: &Context, item: &clean::Item) -> String { fn full_path(cx: &Context<'_>, item: &clean::Item) -> String {
let mut s = cx.current.join("::"); let mut s = cx.current.join("::");
s.push_str("::"); s.push_str("::");
s.push_str(&item.name.unwrap().as_str()); s.push_str(&item.name.unwrap().as_str());
s s
} }
fn document(w: &mut Buffer, cx: &Context, item: &clean::Item, parent: Option<&clean::Item>) { fn document(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, parent: Option<&clean::Item>) {
if let Some(ref name) = item.name { if let Some(ref name) = item.name {
info!("Documenting {}", name); info!("Documenting {}", name);
} }
...@@ -1834,7 +1835,7 @@ fn document(w: &mut Buffer, cx: &Context, item: &clean::Item, parent: Option<&cl ...@@ -1834,7 +1835,7 @@ fn document(w: &mut Buffer, cx: &Context, item: &clean::Item, parent: Option<&cl
/// Render md_text as markdown. /// Render md_text as markdown.
fn render_markdown( fn render_markdown(
w: &mut Buffer, w: &mut Buffer,
cx: &Context, cx: &Context<'_>,
md_text: &str, md_text: &str,
links: Vec<RenderedLink>, links: Vec<RenderedLink>,
prefix: &str, prefix: &str,
...@@ -1863,7 +1864,7 @@ fn render_markdown( ...@@ -1863,7 +1864,7 @@ fn render_markdown(
fn document_short( fn document_short(
w: &mut Buffer, w: &mut Buffer,
item: &clean::Item, item: &clean::Item,
cx: &Context, cx: &Context<'_>,
link: AssocItemLink<'_>, link: AssocItemLink<'_>,
prefix: &str, prefix: &str,
is_hidden: bool, is_hidden: bool,
...@@ -1904,7 +1905,13 @@ fn document_short( ...@@ -1904,7 +1905,13 @@ fn document_short(
} }
} }
fn document_full(w: &mut Buffer, item: &clean::Item, cx: &Context, prefix: &str, is_hidden: bool) { fn document_full(
w: &mut Buffer,
item: &clean::Item,
cx: &Context<'_>,
prefix: &str,
is_hidden: bool,
) {
if let Some(s) = cx.shared.maybe_collapsed_doc_value(item) { if let Some(s) = cx.shared.maybe_collapsed_doc_value(item) {
debug!("Doc block: =====\n{}\n=====", s); debug!("Doc block: =====\n{}\n=====", s);
render_markdown(w, cx, &*s, item.links(), prefix, is_hidden); render_markdown(w, cx, &*s, item.links(), prefix, is_hidden);
...@@ -1925,7 +1932,7 @@ fn document_full(w: &mut Buffer, item: &clean::Item, cx: &Context, prefix: &str, ...@@ -1925,7 +1932,7 @@ fn document_full(w: &mut Buffer, item: &clean::Item, cx: &Context, prefix: &str,
/// * Required features (through the `doc_cfg` feature) /// * Required features (through the `doc_cfg` feature)
fn document_item_info( fn document_item_info(
w: &mut Buffer, w: &mut Buffer,
cx: &Context, cx: &Context<'_>,
item: &clean::Item, item: &clean::Item,
is_hidden: bool, is_hidden: bool,
parent: Option<&clean::Item>, parent: Option<&clean::Item>,
...@@ -2029,7 +2036,7 @@ fn take_parts<'a>(s: &mut &'a str) -> (&'a str, &'a str) { ...@@ -2029,7 +2036,7 @@ fn take_parts<'a>(s: &mut &'a str) -> (&'a str, &'a str) {
Ordering::Equal Ordering::Equal
} }
fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean::Item]) { fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) {
document(w, cx, item, None); document(w, cx, item, None);
let mut indices = (0..items.len()).filter(|i| !items[*i].is_stripped()).collect::<Vec<usize>>(); let mut indices = (0..items.len()).filter(|i| !items[*i].is_stripped()).collect::<Vec<usize>>();
...@@ -2271,7 +2278,11 @@ fn portability(item: &clean::Item, parent: Option<&clean::Item>) -> Option<Strin ...@@ -2271,7 +2278,11 @@ fn portability(item: &clean::Item, parent: Option<&clean::Item>) -> Option<Strin
/// Render the stability, deprecation and portability information that is displayed at the top of /// Render the stability, deprecation and portability information that is displayed at the top of
/// the item's documentation. /// the item's documentation.
fn short_item_info(item: &clean::Item, cx: &Context, parent: Option<&clean::Item>) -> Vec<String> { fn short_item_info(
item: &clean::Item,
cx: &Context<'_>,
parent: Option<&clean::Item>,
) -> Vec<String> {
let mut extra_info = vec![]; let mut extra_info = vec![];
let error_codes = cx.shared.codes; let error_codes = cx.shared.codes;
...@@ -2361,7 +2372,7 @@ fn short_item_info(item: &clean::Item, cx: &Context, parent: Option<&clean::Item ...@@ -2361,7 +2372,7 @@ fn short_item_info(item: &clean::Item, cx: &Context, parent: Option<&clean::Item
extra_info extra_info
} }
fn item_constant(w: &mut Buffer, cx: &Context, it: &clean::Item, c: &clean::Constant) { fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::Constant) {
write!(w, "<pre class=\"rust const\">"); write!(w, "<pre class=\"rust const\">");
render_attributes(w, it, false); render_attributes(w, it, false);
...@@ -2396,7 +2407,7 @@ fn item_constant(w: &mut Buffer, cx: &Context, it: &clean::Item, c: &clean::Cons ...@@ -2396,7 +2407,7 @@ fn item_constant(w: &mut Buffer, cx: &Context, it: &clean::Item, c: &clean::Cons
document(w, cx, it, None) document(w, cx, it, None)
} }
fn item_static(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Static) { fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Static) {
write!(w, "<pre class=\"rust static\">"); write!(w, "<pre class=\"rust static\">");
render_attributes(w, it, false); render_attributes(w, it, false);
write!( write!(
...@@ -2410,7 +2421,7 @@ fn item_static(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Static ...@@ -2410,7 +2421,7 @@ fn item_static(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Static
document(w, cx, it, None) document(w, cx, it, None)
} }
fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Function) { fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::Function) {
let header_len = format!( let header_len = format!(
"{}{}{}{}{:#}fn {}{:#}", "{}{}{}{}{:#}fn {}{:#}",
it.visibility.print_with_space(), it.visibility.print_with_space(),
...@@ -2444,7 +2455,7 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func ...@@ -2444,7 +2455,7 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func
} }
fn render_implementor( fn render_implementor(
cx: &Context, cx: &Context<'_>,
implementor: &Impl, implementor: &Impl,
parent: &clean::Item, parent: &clean::Item,
w: &mut Buffer, w: &mut Buffer,
...@@ -2481,7 +2492,7 @@ fn render_implementor( ...@@ -2481,7 +2492,7 @@ fn render_implementor(
} }
fn render_impls( fn render_impls(
cx: &Context, cx: &Context<'_>,
w: &mut Buffer, w: &mut Buffer,
traits: &[&&Impl], traits: &[&&Impl],
containing_item: &clean::Item, containing_item: &clean::Item,
...@@ -2540,7 +2551,7 @@ fn compare_impl<'a, 'b>(lhs: &'a &&Impl, rhs: &'b &&Impl) -> Ordering { ...@@ -2540,7 +2551,7 @@ fn compare_impl<'a, 'b>(lhs: &'a &&Impl, rhs: &'b &&Impl) -> Ordering {
compare_names(&lhs, &rhs) compare_names(&lhs, &rhs)
} }
fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait, cache: &Cache) { fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Trait, cache: &Cache) {
let bounds = bounds(&t.bounds, false); let bounds = bounds(&t.bounds, false);
let types = t.items.iter().filter(|m| m.is_associated_type()).collect::<Vec<_>>(); let types = t.items.iter().filter(|m| m.is_associated_type()).collect::<Vec<_>>();
let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::<Vec<_>>(); let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::<Vec<_>>();
...@@ -2636,7 +2647,13 @@ fn write_loading_content(w: &mut Buffer, extra_content: &str) { ...@@ -2636,7 +2647,13 @@ fn write_loading_content(w: &mut Buffer, extra_content: &str) {
write!(w, "{}<span class=\"loading-content\">Loading content...</span>", extra_content) write!(w, "{}<span class=\"loading-content\">Loading content...</span>", extra_content)
} }
fn trait_item(w: &mut Buffer, cx: &Context, m: &clean::Item, t: &clean::Item, cache: &Cache) { fn trait_item(
w: &mut Buffer,
cx: &Context<'_>,
m: &clean::Item,
t: &clean::Item,
cache: &Cache,
) {
let name = m.name.as_ref().unwrap(); let name = m.name.as_ref().unwrap();
info!("Documenting {} on {:?}", name, t.name); info!("Documenting {} on {:?}", name, t.name);
let item_type = m.type_(); let item_type = m.type_();
...@@ -3039,7 +3056,13 @@ fn method( ...@@ -3039,7 +3056,13 @@ fn method(
} }
} }
fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct, cache: &Cache) { fn item_struct(
w: &mut Buffer,
cx: &Context<'_>,
it: &clean::Item,
s: &clean::Struct,
cache: &Cache,
) {
wrap_into_docblock(w, |w| { wrap_into_docblock(w, |w| {
write!(w, "<pre class=\"rust struct\">"); write!(w, "<pre class=\"rust struct\">");
render_attributes(w, it, true); render_attributes(w, it, true);
...@@ -3089,7 +3112,7 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct ...@@ -3089,7 +3112,7 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct
render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache) render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
} }
fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union, cache: &Cache) { fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Union, cache: &Cache) {
wrap_into_docblock(w, |w| { wrap_into_docblock(w, |w| {
write!(w, "<pre class=\"rust union\">"); write!(w, "<pre class=\"rust union\">");
render_attributes(w, it, true); render_attributes(w, it, true);
...@@ -3135,7 +3158,7 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union, ...@@ -3135,7 +3158,7 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union,
render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache) render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
} }
fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, cache: &Cache) { fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum, cache: &Cache) {
wrap_into_docblock(w, |w| { wrap_into_docblock(w, |w| {
write!(w, "<pre class=\"rust enum\">"); write!(w, "<pre class=\"rust enum\">");
render_attributes(w, it, true); render_attributes(w, it, true);
...@@ -3443,7 +3466,7 @@ fn anchor(&self, id: &'a String) -> Self { ...@@ -3443,7 +3466,7 @@ fn anchor(&self, id: &'a String) -> Self {
fn render_assoc_items( fn render_assoc_items(
w: &mut Buffer, w: &mut Buffer,
cx: &Context, cx: &Context<'_>,
containing_item: &clean::Item, containing_item: &clean::Item,
it: DefId, it: DefId,
what: AssocItemRender<'_>, what: AssocItemRender<'_>,
...@@ -3559,7 +3582,7 @@ fn render_assoc_items( ...@@ -3559,7 +3582,7 @@ fn render_assoc_items(
fn render_deref_methods( fn render_deref_methods(
w: &mut Buffer, w: &mut Buffer,
cx: &Context, cx: &Context<'_>,
impl_: &Impl, impl_: &Impl,
container_item: &clean::Item, container_item: &clean::Item,
deref_mut: bool, deref_mut: bool,
...@@ -3675,7 +3698,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String { ...@@ -3675,7 +3698,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String {
fn render_impl( fn render_impl(
w: &mut Buffer, w: &mut Buffer,
cx: &Context, cx: &Context<'_>,
i: &Impl, i: &Impl,
parent: &clean::Item, parent: &clean::Item,
link: AssocItemLink<'_>, link: AssocItemLink<'_>,
...@@ -3769,7 +3792,7 @@ fn render_impl( ...@@ -3769,7 +3792,7 @@ fn render_impl(
fn doc_impl_item( fn doc_impl_item(
w: &mut Buffer, w: &mut Buffer,
cx: &Context, cx: &Context<'_>,
item: &clean::Item, item: &clean::Item,
parent: &clean::Item, parent: &clean::Item,
link: AssocItemLink<'_>, link: AssocItemLink<'_>,
...@@ -3906,7 +3929,7 @@ fn doc_impl_item( ...@@ -3906,7 +3929,7 @@ fn doc_impl_item(
fn render_default_items( fn render_default_items(
w: &mut Buffer, w: &mut Buffer,
cx: &Context, cx: &Context<'_>,
t: &clean::Trait, t: &clean::Trait,
i: &clean::Impl, i: &clean::Impl,
parent: &clean::Item, parent: &clean::Item,
...@@ -3966,7 +3989,7 @@ fn render_default_items( ...@@ -3966,7 +3989,7 @@ fn render_default_items(
fn item_opaque_ty( fn item_opaque_ty(
w: &mut Buffer, w: &mut Buffer,
cx: &Context, cx: &Context<'_>,
it: &clean::Item, it: &clean::Item,
t: &clean::OpaqueTy, t: &clean::OpaqueTy,
cache: &Cache, cache: &Cache,
...@@ -3993,7 +4016,7 @@ fn item_opaque_ty( ...@@ -3993,7 +4016,7 @@ fn item_opaque_ty(
fn item_trait_alias( fn item_trait_alias(
w: &mut Buffer, w: &mut Buffer,
cx: &Context, cx: &Context<'_>,
it: &clean::Item, it: &clean::Item,
t: &clean::TraitAlias, t: &clean::TraitAlias,
cache: &Cache, cache: &Cache,
...@@ -4018,7 +4041,13 @@ fn item_trait_alias( ...@@ -4018,7 +4041,13 @@ fn item_trait_alias(
render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache) render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
} }
fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typedef, cache: &Cache) { fn item_typedef(
w: &mut Buffer,
cx: &Context<'_>,
it: &clean::Item,
t: &clean::Typedef,
cache: &Cache,
) {
write!(w, "<pre class=\"rust typedef\">"); write!(w, "<pre class=\"rust typedef\">");
render_attributes(w, it, false); render_attributes(w, it, false);
write!( write!(
...@@ -4039,7 +4068,7 @@ fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typed ...@@ -4039,7 +4068,7 @@ fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typed
render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache) render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
} }
fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item, cache: &Cache) { fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, cache: &Cache) {
writeln!(w, "<pre class=\"rust foreigntype\">extern {{"); writeln!(w, "<pre class=\"rust foreigntype\">extern {{");
render_attributes(w, it, false); render_attributes(w, it, false);
write!( write!(
...@@ -4054,7 +4083,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item, cache: &Cac ...@@ -4054,7 +4083,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item, cache: &Cac
render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache) render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
} }
fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer, cache: &Cache) { fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer, cache: &Cache) {
let parentlen = cx.current.len() - if it.is_mod() { 1 } else { 0 }; let parentlen = cx.current.len() - if it.is_mod() { 1 } else { 0 };
if it.is_struct() if it.is_struct()
...@@ -4685,7 +4714,7 @@ fn sidebar_foreign_type(buf: &mut Buffer, it: &clean::Item) { ...@@ -4685,7 +4714,7 @@ fn sidebar_foreign_type(buf: &mut Buffer, it: &clean::Item) {
} }
} }
fn item_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Macro) { fn item_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) {
wrap_into_docblock(w, |w| { wrap_into_docblock(w, |w| {
w.write_str(&highlight::render_with_highlighting( w.write_str(&highlight::render_with_highlighting(
t.source.clone(), t.source.clone(),
...@@ -4697,7 +4726,7 @@ fn item_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Macro) ...@@ -4697,7 +4726,7 @@ fn item_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Macro)
document(w, cx, it, None) document(w, cx, it, None)
} }
fn item_proc_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, m: &clean::ProcMacro) { fn item_proc_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, m: &clean::ProcMacro) {
let name = it.name.as_ref().expect("proc-macros always have names"); let name = it.name.as_ref().expect("proc-macros always have names");
match m.kind { match m.kind {
MacroKind::Bang => { MacroKind::Bang => {
...@@ -4727,12 +4756,12 @@ fn item_proc_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, m: &clean::Pr ...@@ -4727,12 +4756,12 @@ fn item_proc_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, m: &clean::Pr
document(w, cx, it, None) document(w, cx, it, None)
} }
fn item_primitive(w: &mut Buffer, cx: &Context, it: &clean::Item, cache: &Cache) { fn item_primitive(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, cache: &Cache) {
document(w, cx, it, None); document(w, cx, it, None);
render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache) render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
} }
fn item_keyword(w: &mut Buffer, cx: &Context, it: &clean::Item) { fn item_keyword(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
document(w, cx, it, None) document(w, cx, it, None)
} }
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
crate fn render( crate fn render(
dst: &Path, dst: &Path,
scx: &mut SharedContext, scx: &mut SharedContext<'_>,
krate: clean::Crate, krate: clean::Crate,
) -> Result<clean::Crate, Error> { ) -> Result<clean::Crate, Error> {
info!("emitting source files"); info!("emitting source files");
...@@ -26,14 +26,14 @@ ...@@ -26,14 +26,14 @@
} }
/// Helper struct to render all source code to HTML pages /// Helper struct to render all source code to HTML pages
struct SourceCollector<'a> { struct SourceCollector<'a, 'tcx> {
scx: &'a mut SharedContext, scx: &'a mut SharedContext<'tcx>,
/// Root destination to place all HTML output into /// Root destination to place all HTML output into
dst: PathBuf, dst: PathBuf,
} }
impl<'a> DocFolder for SourceCollector<'a> { impl DocFolder for SourceCollector<'_, '_> {
fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> { fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
// If we're not rendering sources, there's nothing to do. // If we're not rendering sources, there's nothing to do.
// If we're including source files, and we haven't seen this file yet, // If we're including source files, and we haven't seen this file yet,
...@@ -69,9 +69,9 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> { ...@@ -69,9 +69,9 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
} }
} }
impl<'a> SourceCollector<'a> { impl SourceCollector<'_, '_> {
fn sess(&self) -> &Session { fn sess(&self) -> &Session {
&self.scx.sess &self.scx.tcx.sess
} }
/// Renders the given filename into its corresponding HTML source file. /// Renders the given filename into its corresponding HTML source file.
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
use crate::json::types::*; use crate::json::types::*;
use crate::json::JsonRenderer; use crate::json::JsonRenderer;
impl JsonRenderer { impl JsonRenderer<'_> {
pub(super) fn convert_item(&self, item: clean::Item) -> Option<Item> { pub(super) fn convert_item(&self, item: clean::Item) -> Option<Item> {
let item_type = ItemType::from(&item); let item_type = ItemType::from(&item);
let clean::Item { let clean::Item {
...@@ -57,10 +57,10 @@ pub(super) fn convert_item(&self, item: clean::Item) -> Option<Item> { ...@@ -57,10 +57,10 @@ pub(super) fn convert_item(&self, item: clean::Item) -> Option<Item> {
} }
fn convert_span(&self, span: clean::Span) -> Option<Span> { fn convert_span(&self, span: clean::Span) -> Option<Span> {
match span.filename(&self.sess) { match span.filename(self.sess()) {
rustc_span::FileName::Real(name) => { rustc_span::FileName::Real(name) => {
let hi = span.hi(&self.sess); let hi = span.hi(self.sess());
let lo = span.lo(&self.sess); let lo = span.lo(self.sess());
Some(Span { Some(Span {
filename: match name { filename: match name {
rustc_span::RealFileName::Named(path) => path, rustc_span::RealFileName::Named(path) => path,
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
use std::rc::Rc; use std::rc::Rc;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lrc; use rustc_middle::ty;
use rustc_session::Session; use rustc_session::Session;
use rustc_span::edition::Edition; use rustc_span::edition::Edition;
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
use crate::html::render::cache::ExternalLocation; use crate::html::render::cache::ExternalLocation;
#[derive(Clone)] #[derive(Clone)]
crate struct JsonRenderer { crate struct JsonRenderer<'tcx> {
sess: Lrc<Session>, tcx: ty::TyCtxt<'tcx>,
/// A mapping of IDs that contains all local items for this crate which gets output as a top /// A mapping of IDs that contains all local items for this crate which gets output as a top
/// level field of the JSON blob. /// level field of the JSON blob.
index: Rc<RefCell<FxHashMap<types::Id, types::Item>>>, index: Rc<RefCell<FxHashMap<types::Id, types::Item>>>,
...@@ -34,7 +34,11 @@ ...@@ -34,7 +34,11 @@
out_path: PathBuf, out_path: PathBuf,
} }
impl JsonRenderer { impl JsonRenderer<'_> {
fn sess(&self) -> &Session {
self.tcx.sess
}
fn get_trait_implementors( fn get_trait_implementors(
&mut self, &mut self,
id: rustc_span::def_id::DefId, id: rustc_span::def_id::DefId,
...@@ -120,19 +124,19 @@ fn get_trait_items(&mut self, cache: &Cache) -> Vec<(types::Id, types::Item)> { ...@@ -120,19 +124,19 @@ fn get_trait_items(&mut self, cache: &Cache) -> Vec<(types::Id, types::Item)> {
} }
} }
impl FormatRenderer for JsonRenderer { impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
fn init( fn init(
krate: clean::Crate, krate: clean::Crate,
options: RenderOptions, options: RenderOptions,
_render_info: RenderInfo, _render_info: RenderInfo,
_edition: Edition, _edition: Edition,
_cache: &mut Cache, _cache: &mut Cache,
sess: Lrc<Session>, tcx: ty::TyCtxt<'tcx>,
) -> Result<(Self, clean::Crate), Error> { ) -> Result<(Self, clean::Crate), Error> {
debug!("Initializing json renderer"); debug!("Initializing json renderer");
Ok(( Ok((
JsonRenderer { JsonRenderer {
sess, tcx,
index: Rc::new(RefCell::new(FxHashMap::default())), index: Rc::new(RefCell::new(FxHashMap::default())),
out_path: options.output, out_path: options.output,
}, },
......
...@@ -62,11 +62,12 @@ ...@@ -62,11 +62,12 @@
use std::env; use std::env;
use std::process; use std::process;
use rustc_data_structures::sync::Lrc; use rustc_driver::abort_on_err;
use rustc_errors::ErrorReported; use rustc_errors::ErrorReported;
use rustc_interface::interface;
use rustc_middle::ty;
use rustc_session::config::{make_crate_type_option, ErrorOutputType, RustcOptGroup}; use rustc_session::config::{make_crate_type_option, ErrorOutputType, RustcOptGroup};
use rustc_session::getopts; use rustc_session::getopts;
use rustc_session::Session;
use rustc_session::{early_error, early_warn}; use rustc_session::{early_error, early_warn};
#[macro_use] #[macro_use]
...@@ -468,15 +469,15 @@ fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> MainRes ...@@ -468,15 +469,15 @@ fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> MainRes
} }
} }
fn run_renderer<T: formats::FormatRenderer>( fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>(
krate: clean::Crate, krate: clean::Crate,
renderopts: config::RenderOptions, renderopts: config::RenderOptions,
render_info: config::RenderInfo, render_info: config::RenderInfo,
diag: &rustc_errors::Handler, diag: &rustc_errors::Handler,
edition: rustc_span::edition::Edition, edition: rustc_span::edition::Edition,
sess: Lrc<Session>, tcx: ty::TyCtxt<'tcx>,
) -> MainResult { ) -> MainResult {
match formats::run_format::<T>(krate, renderopts, render_info, &diag, edition, sess) { match formats::run_format::<T>(krate, renderopts, render_info, &diag, edition, tcx) {
Ok(_) => Ok(()), Ok(_) => Ok(()),
Err(e) => { Err(e) => {
let mut msg = diag.struct_err(&format!("couldn't generate documentation: {}", e.error)); let mut msg = diag.struct_err(&format!("couldn't generate documentation: {}", e.error));
...@@ -520,34 +521,80 @@ fn main_options(options: config::Options) -> MainResult { ...@@ -520,34 +521,80 @@ fn main_options(options: config::Options) -> MainResult {
// then generated from the cleaned AST of the crate. This runs all the // then generated from the cleaned AST of the crate. This runs all the
// plug/cleaning passes. // plug/cleaning passes.
let crate_version = options.crate_version.clone(); let crate_version = options.crate_version.clone();
let default_passes = options.default_passes;
let output_format = options.output_format; let output_format = options.output_format;
let (mut krate, renderinfo, renderopts, sess) = core::run_core(options); // FIXME: fix this clone (especially render_options)
let externs = options.externs.clone();
let manual_passes = options.manual_passes.clone();
let render_options = options.render_options.clone();
let config = core::create_config(options);
info!("finished with rustc"); interface::create_compiler_and_run(config, |compiler| {
compiler.enter(|queries| {
let sess = compiler.session();
krate.version = crate_version; // We need to hold on to the complete resolver, so we cause everything to be
// cloned for the analysis passes to use. Suboptimal, but necessary in the
// current architecture.
let resolver = core::create_resolver(externs, queries, &sess);
if show_coverage { if sess.has_errors() {
// if we ran coverage, bail early, we don't need to also generate docs at this point sess.fatal("Compilation failed, aborting rustdoc");
// (also we didn't load in any of the useful passes) }
return Ok(());
} else if run_check {
// Since we're in "check" mode, no need to generate anything beyond this point.
return Ok(());
}
info!("going to format"); let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess).take();
let (error_format, edition, debugging_options) = diag_opts;
let diag = core::new_handler(error_format, None, &debugging_options); global_ctxt.enter(|tcx| {
let sess_time = sess.clone(); let (mut krate, render_info, render_opts) = sess.time("run_global_ctxt", || {
match output_format { core::run_global_ctxt(
None | Some(config::OutputFormat::Html) => sess_time.time("render_html", || { tcx,
run_renderer::<html::render::Context>( resolver,
krate, renderopts, renderinfo, &diag, edition, sess, default_passes,
) manual_passes,
}), render_options,
Some(config::OutputFormat::Json) => sess_time.time("render_json", || { output_format,
run_renderer::<json::JsonRenderer>(krate, renderopts, renderinfo, &diag, edition, sess) )
}), });
} info!("finished with rustc");
krate.version = crate_version;
if show_coverage {
// if we ran coverage, bail early, we don't need to also generate docs at this point
// (also we didn't load in any of the useful passes)
return Ok(());
} else if run_check {
// Since we're in "check" mode, no need to generate anything beyond this point.
return Ok(());
}
info!("going to format");
let (error_format, edition, debugging_options) = diag_opts;
let diag = core::new_handler(error_format, None, &debugging_options);
match output_format {
None | Some(config::OutputFormat::Html) => sess.time("render_html", || {
run_renderer::<html::render::Context<'_>>(
krate,
render_opts,
render_info,
&diag,
edition,
tcx,
)
}),
Some(config::OutputFormat::Json) => sess.time("render_json", || {
run_renderer::<json::JsonRenderer<'_>>(
krate,
render_opts,
render_info,
&diag,
edition,
tcx,
)
}),
}
})
})
})
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册