diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2025-05-19 23:10:09 +0200 |
|---|---|---|
| committer | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2025-08-23 00:57:29 +0200 |
| commit | f8b8cc4cceda39ec2c0a933fd1ba4b9951401862 (patch) | |
| tree | 2da2dcab650df38c365eb31c5dd85a80e69fcf66 /src/librustdoc | |
| parent | ab000e15e1c6fd571882ebd0852ee39fabe6820d (diff) | |
| download | rust-f8b8cc4cceda39ec2c0a933fd1ba4b9951401862.tar.gz rust-f8b8cc4cceda39ec2c0a933fd1ba4b9951401862.zip | |
Do macro expansion at AST level rather than HIR
Diffstat (limited to 'src/librustdoc')
| -rw-r--r-- | src/librustdoc/core.rs | 13 | ||||
| -rw-r--r-- | src/librustdoc/formats/renderer.rs | 18 | ||||
| -rw-r--r-- | src/librustdoc/html/highlight.rs | 3 | ||||
| -rw-r--r-- | src/librustdoc/html/macro_expansion.rs | 140 | ||||
| -rw-r--r-- | src/librustdoc/html/mod.rs | 1 | ||||
| -rw-r--r-- | src/librustdoc/html/render/context.rs | 29 | ||||
| -rw-r--r-- | src/librustdoc/html/render/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustdoc/html/render/span_map.rs | 135 | ||||
| -rw-r--r-- | src/librustdoc/json/mod.rs | 20 | ||||
| -rw-r--r-- | src/librustdoc/lib.rs | 50 | ||||
| -rw-r--r-- | src/librustdoc/scrape_examples.rs | 4 |
11 files changed, 237 insertions, 178 deletions
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index e89733b2f6d..b8aaafcb517 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -31,6 +31,7 @@ use crate::clean::inline::build_trait; use crate::clean::{self, ItemId}; use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions}; use crate::formats::cache::Cache; +use crate::html::macro_expansion::{ExpandedCode, source_macro_expansion}; use crate::passes; use crate::passes::Condition::*; use crate::passes::collect_intra_doc_links::LinkCollector; @@ -334,11 +335,19 @@ pub(crate) fn run_global_ctxt( show_coverage: bool, render_options: RenderOptions, output_format: OutputFormat, -) -> (clean::Crate, RenderOptions, Cache) { +) -> (clean::Crate, RenderOptions, Cache, FxHashMap<rustc_span::BytePos, Vec<ExpandedCode>>) { // Certain queries assume that some checks were run elsewhere // (see https://github.com/rust-lang/rust/pull/73566#issuecomment-656954425), // so type-check everything other than function bodies in this crate before running lints. + let expanded_macros = { + // We need for these variables to be removed to ensure that the `Crate` won't be "stolen" + // anymore. + let (_resolver, krate) = &*tcx.resolver_for_lowering().borrow(); + + source_macro_expansion(&krate, &render_options, output_format, tcx.sess.source_map()) + }; + // NOTE: this does not call `tcx.analysis()` so that we won't // typeck function bodies or run the default rustc lints. // (see `override_queries` in the `config`) @@ -448,7 +457,7 @@ pub(crate) fn run_global_ctxt( tcx.dcx().abort_if_errors(); - (krate, ctxt.render_options, ctxt.cache) + (krate, ctxt.render_options, ctxt.cache, expanded_macros) } /// Due to <https://github.com/rust-lang/rust/pull/73566>, diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index aa4be4db997..305c8c39ba7 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -31,15 +31,6 @@ pub(crate) trait FormatRenderer<'tcx>: Sized { /// reset the information between each call to `item` by using `restore_module_data`. type ModuleData; - /// Sets up any state required for the renderer. When this is called the cache has already been - /// populated. - fn init( - krate: clean::Crate, - options: RenderOptions, - cache: Cache, - tcx: TyCtxt<'tcx>, - ) -> Result<(Self, clean::Crate), Error>; - /// This method is called right before call [`Self::item`]. This method returns a type /// containing information that needs to be reset after the [`Self::item`] method has been /// called with the [`Self::restore_module_data`] method. @@ -105,18 +96,23 @@ fn run_format_inner<'tcx, T: FormatRenderer<'tcx>>( } /// Main method for rendering a crate. -pub(crate) fn run_format<'tcx, T: FormatRenderer<'tcx>>( +pub(crate) fn run_format< + 'tcx, + T: FormatRenderer<'tcx>, + F: FnOnce(clean::Crate, RenderOptions, Cache, TyCtxt<'tcx>) -> Result<(T, clean::Crate), Error>, +>( krate: clean::Crate, options: RenderOptions, cache: Cache, tcx: TyCtxt<'tcx>, + init: F, ) -> Result<(), Error> { let prof = &tcx.sess.prof; let emit_crate = options.should_emit_crate(); let (mut format_renderer, krate) = prof .verbose_generic_activity_with_arg("create_renderer", T::descr()) - .run(|| T::init(krate, options, cache, tcx))?; + .run(|| init(krate, options, cache, tcx))?; if !emit_crate { return Ok(()); diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 3457ac5b232..5a25d659b0f 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -18,7 +18,8 @@ use rustc_span::{BytePos, DUMMY_SP, Span}; use super::format::{self, write_str}; use crate::clean::PrimitiveType; use crate::html::escape::EscapeBodyText; -use crate::html::render::{Context, ExpandedCode, LinkFromSrc}; +use crate::html::macro_expansion::ExpandedCode; +use crate::html::render::{Context, LinkFromSrc}; /// This type is needed in case we want to render links on items to allow to go to their definition. pub(crate) struct HrefContext<'a, 'tcx> { diff --git a/src/librustdoc/html/macro_expansion.rs b/src/librustdoc/html/macro_expansion.rs new file mode 100644 index 00000000000..7b6758868b7 --- /dev/null +++ b/src/librustdoc/html/macro_expansion.rs @@ -0,0 +1,140 @@ +use rustc_ast::visit::{Visitor, walk_crate, walk_expr, walk_item}; +use rustc_ast::{Crate, Expr, Item}; +use rustc_data_structures::fx::FxHashMap; +use rustc_span::source_map::SourceMap; +use rustc_span::{BytePos, Span}; + +use crate::config::{OutputFormat, RenderOptions}; + +/// It returns the expanded macros correspondence map. +pub(crate) fn source_macro_expansion( + krate: &Crate, + render_options: &RenderOptions, + output_format: OutputFormat, + source_map: &SourceMap, +) -> FxHashMap<BytePos, Vec<ExpandedCode>> { + if output_format == OutputFormat::Html + && !render_options.html_no_source + && render_options.generate_macro_expansion + { + let mut expanded_visitor = ExpandedCodeVisitor { expanded_codes: Vec::new(), source_map }; + walk_crate(&mut expanded_visitor, krate); + expanded_visitor.compute_expanded() + } else { + Default::default() + } +} + +/// Contains information about macro expansion in the source code pages. +#[derive(Debug)] +pub(crate) struct ExpandedCode { + /// The line where the macro expansion starts. + pub(crate) start_line: u32, + /// The line where the macro expansion ends. + pub(crate) end_line: u32, + /// The source code of the expanded macro. + pub(crate) code: String, + /// The span of macro callsite. + pub(crate) span: Span, +} + +/// Contains temporary information of macro expanded code. +/// +/// As we go through the HIR visitor, if any span overlaps with another, they will +/// both be merged. +struct ExpandedCodeInfo { + /// Callsite of the macro. + span: Span, + /// Expanded macro source code. + code: String, + /// Expanded span + expanded_span: Span, +} + +/// HIR visitor which retrieves expanded macro. +/// +/// Once done, the `expanded_codes` will be transformed into a vec of [`ExpandedCode`] +/// which contains more information needed when running the source code highlighter. +pub(crate) struct ExpandedCodeVisitor<'ast> { + expanded_codes: Vec<ExpandedCodeInfo>, + source_map: &'ast SourceMap, +} + +impl<'ast> ExpandedCodeVisitor<'ast> { + fn handle_new_span<F: Fn() -> String>(&mut self, new_span: Span, f: F) { + if new_span.is_dummy() || !new_span.from_expansion() { + return; + } + let callsite_span = new_span.source_callsite(); + if let Some(index) = + self.expanded_codes.iter().position(|info| info.span.overlaps(callsite_span)) + { + let info = &mut self.expanded_codes[index]; + if new_span.contains(info.expanded_span) { + // We replace the item. + info.span = callsite_span; + info.expanded_span = new_span; + info.code = f(); + } else { + // We push the new item after the existing one. + let expanded_code = &mut self.expanded_codes[index]; + expanded_code.code.push('\n'); + expanded_code.code.push_str(&f()); + let lo = BytePos(expanded_code.expanded_span.lo().0.min(new_span.lo().0)); + let hi = BytePos(expanded_code.expanded_span.hi().0.min(new_span.hi().0)); + expanded_code.expanded_span = expanded_code.expanded_span.with_lo(lo).with_hi(hi); + } + } else { + // We add a new item. + self.expanded_codes.push(ExpandedCodeInfo { + span: callsite_span, + code: f(), + expanded_span: new_span, + }); + } + } + + fn compute_expanded(mut self) -> FxHashMap<BytePos, Vec<ExpandedCode>> { + self.expanded_codes.sort_unstable_by(|item1, item2| item1.span.cmp(&item2.span)); + let mut expanded: FxHashMap<BytePos, Vec<ExpandedCode>> = FxHashMap::default(); + for ExpandedCodeInfo { span, code, .. } in self.expanded_codes { + if let Ok(lines) = self.source_map.span_to_lines(span) + && !lines.lines.is_empty() + { + let mut out = String::new(); + super::highlight::write_code(&mut out, &code, None, None, None); + let first = lines.lines.first().unwrap(); + let end = lines.lines.last().unwrap(); + expanded.entry(lines.file.start_pos).or_default().push(ExpandedCode { + start_line: first.line_index as u32 + 1, + end_line: end.line_index as u32 + 1, + code: out, + span, + }); + } + } + expanded + } +} + +// We need to use the AST pretty printing because: +// +// 1. HIR pretty printing doesn't display accurately the code (like `impl Trait`). +// 2. `SourceMap::snippet_opt` might fail if the source is not available. +impl<'ast> Visitor<'ast> for ExpandedCodeVisitor<'ast> { + fn visit_expr(&mut self, expr: &'ast Expr) { + if expr.span.from_expansion() { + self.handle_new_span(expr.span, || rustc_ast_pretty::pprust::expr_to_string(expr)); + } else { + walk_expr(self, expr); + } + } + + fn visit_item(&mut self, item: &'ast Item) { + if item.span.from_expansion() { + self.handle_new_span(item.span, || rustc_ast_pretty::pprust::item_to_string(item)); + } else { + walk_item(self, item); + } + } +} diff --git a/src/librustdoc/html/mod.rs b/src/librustdoc/html/mod.rs index 481ed16c05f..170449fc033 100644 --- a/src/librustdoc/html/mod.rs +++ b/src/librustdoc/html/mod.rs @@ -4,6 +4,7 @@ pub(crate) mod highlight; pub(crate) mod layout; mod length_limit; // used by the error-index generator, so it needs to be public +pub(crate) mod macro_expansion; pub mod markdown; pub(crate) mod render; pub(crate) mod sources; diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index af9af5ba2b3..faaecaf0cbb 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -28,8 +28,8 @@ use crate::formats::FormatRenderer; use crate::formats::cache::Cache; use crate::formats::item_type::ItemType; use crate::html::escape::Escape; +use crate::html::macro_expansion::ExpandedCode; use crate::html::markdown::{self, ErrorCodes, IdMap, plain_text_summary}; -use crate::html::render::ExpandedCode; use crate::html::render::write_shared::write_shared; use crate::html::url_parts_builder::UrlPartsBuilder; use crate::html::{layout, sources, static_files}; @@ -460,20 +460,13 @@ impl<'tcx> Context<'tcx> { } } -/// Generates the documentation for `crate` into the directory `dst` -impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { - fn descr() -> &'static str { - "html" - } - - const RUN_ON_MODULE: bool = true; - type ModuleData = ContextInfo; - - fn init( +impl<'tcx> Context<'tcx> { + pub(crate) fn init( krate: clean::Crate, options: RenderOptions, cache: Cache, tcx: TyCtxt<'tcx>, + expanded_codes: FxHashMap<BytePos, Vec<ExpandedCode>>, ) -> Result<(Self, clean::Crate), Error> { // need to save a copy of the options for rendering the index page let md_opts = options.clone(); @@ -492,7 +485,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { generate_redirect_map, show_type_layout, generate_link_to_definition, - generate_macro_expansion, call_locations, no_emit_shared, html_no_source, @@ -551,13 +543,12 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { } } - let (local_sources, matches, expanded_codes) = collect_spans_and_sources( + let (local_sources, matches) = collect_spans_and_sources( tcx, &krate, &src_root, include_sources, generate_link_to_definition, - generate_macro_expansion, ); let (sender, receiver) = channel(); @@ -609,6 +600,16 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { Ok((cx, krate)) } +} + +/// Generates the documentation for `crate` into the directory `dst` +impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { + fn descr() -> &'static str { + "html" + } + + const RUN_ON_MODULE: bool = true; + type ModuleData = ContextInfo; fn save_module_data(&mut self) -> Self::ModuleData { self.deref_id_map.borrow_mut().clear(); diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 0986b9ca47b..8d7f0577506 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -63,7 +63,7 @@ use serde::{Serialize, Serializer}; use tracing::{debug, info}; pub(crate) use self::context::*; -pub(crate) use self::span_map::{ExpandedCode, LinkFromSrc, collect_spans_and_sources}; +pub(crate) use self::span_map::{LinkFromSrc, collect_spans_and_sources}; pub(crate) use self::write_shared::*; use crate::clean::{self, ItemId, RenderedLink}; use crate::display::{Joined as _, MaybeDisplay as _}; diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index 04071a9e066..8bc2e0bd957 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -30,26 +30,12 @@ pub(crate) enum LinkFromSrc { Doc(DefId), } -/// Contains information about macro expansion in the source code pages. -#[derive(Debug)] -pub(crate) struct ExpandedCode { - /// The line where the macro expansion starts. - pub(crate) start_line: u32, - /// The line where the macro expansion ends. - pub(crate) end_line: u32, - /// The source code of the expanded macro. - pub(crate) code: String, - /// The span of macro callsite. - pub(crate) span: Span, -} - /// This function will do at most two things: /// /// 1. Generate a `span` correspondence map which links an item `span` to its definition `span`. /// 2. Collect the source code files. /// -/// It returns the source code files, the `span` correspondence map and the expanded macros -/// correspondence map. +/// It returns the source code files and the `span` correspondence map. /// /// Note about the `span` correspondence map: the keys are actually `(lo, hi)` of `span`s. We don't /// need the `span` context later on, only their position, so instead of keeping a whole `Span`, we @@ -60,26 +46,17 @@ pub(crate) fn collect_spans_and_sources( src_root: &Path, include_sources: bool, generate_link_to_definition: bool, - generate_macro_expansion: bool, -) -> ( - FxIndexMap<PathBuf, String>, - FxHashMap<Span, LinkFromSrc>, - FxHashMap<BytePos, Vec<ExpandedCode>>, -) { +) -> (FxIndexMap<PathBuf, String>, FxHashMap<Span, LinkFromSrc>) { if include_sources { let mut visitor = SpanMapVisitor { tcx, matches: FxHashMap::default() }; - let mut expanded_visitor = ExpandedCodeVisitor { tcx, expanded_codes: Vec::new() }; - if generate_macro_expansion { - tcx.hir_walk_toplevel_module(&mut expanded_visitor); - } if generate_link_to_definition { tcx.hir_walk_toplevel_module(&mut visitor); } let sources = sources::collect_local_sources(tcx, src_root, krate); - (sources, visitor.matches, expanded_visitor.compute_expanded()) + (sources, visitor.matches) } else { - (Default::default(), Default::default(), Default::default()) + (Default::default(), Default::default()) } } @@ -315,107 +292,3 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> { intravisit::walk_item(self, item); } } - -/// Contains temporary information of macro expanded code. -/// -/// As we go through the HIR visitor, if any span overlaps with another, they will -/// both be merged. -struct ExpandedCodeInfo { - /// Callsite of the macro. - span: Span, - /// Expanded macro source code. - code: String, - /// Expanded span - expanded_span: Span, -} - -/// HIR visitor which retrieves expanded macro. -/// -/// Once done, the `expanded_codes` will be transformed into a vec of [`ExpandedCode`] -/// which contains more information needed when running the source code highlighter. -pub struct ExpandedCodeVisitor<'tcx> { - tcx: TyCtxt<'tcx>, - expanded_codes: Vec<ExpandedCodeInfo>, -} - -impl<'tcx> ExpandedCodeVisitor<'tcx> { - fn handle_new_span<F: Fn(TyCtxt<'_>) -> String>(&mut self, new_span: Span, f: F) { - if new_span.is_dummy() || !new_span.from_expansion() { - return; - } - let callsite_span = new_span.source_callsite(); - if let Some(index) = - self.expanded_codes.iter().position(|info| info.span.overlaps(callsite_span)) - { - let info = &mut self.expanded_codes[index]; - if new_span.contains(info.expanded_span) { - // We replace the item. - info.span = callsite_span; - info.expanded_span = new_span; - info.code = f(self.tcx); - } else { - // We push the new item after the existing one. - let expanded_code = &mut self.expanded_codes[index]; - expanded_code.code.push('\n'); - expanded_code.code.push_str(&f(self.tcx)); - let lo = BytePos(expanded_code.expanded_span.lo().0.min(new_span.lo().0)); - let hi = BytePos(expanded_code.expanded_span.hi().0.min(new_span.hi().0)); - expanded_code.expanded_span = expanded_code.expanded_span.with_lo(lo).with_hi(hi); - } - } else { - // We add a new item. - self.expanded_codes.push(ExpandedCodeInfo { - span: callsite_span, - code: f(self.tcx), - expanded_span: new_span, - }); - } - } - - fn compute_expanded(mut self) -> FxHashMap<BytePos, Vec<ExpandedCode>> { - self.expanded_codes.sort_unstable_by(|item1, item2| item1.span.cmp(&item2.span)); - let source_map = self.tcx.sess.source_map(); - let mut expanded: FxHashMap<BytePos, Vec<ExpandedCode>> = FxHashMap::default(); - for ExpandedCodeInfo { span, code, .. } in self.expanded_codes { - if let Ok(lines) = source_map.span_to_lines(span) - && !lines.lines.is_empty() - { - let mut out = String::new(); - super::highlight::write_code(&mut out, &code, None, None, None); - let first = lines.lines.first().unwrap(); - let end = lines.lines.last().unwrap(); - expanded.entry(lines.file.start_pos).or_default().push(ExpandedCode { - start_line: first.line_index as u32 + 1, - end_line: end.line_index as u32 + 1, - code: out, - span, - }); - } - } - expanded - } -} - -impl<'tcx> Visitor<'tcx> for ExpandedCodeVisitor<'tcx> { - type NestedFilter = nested_filter::All; - - fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { - self.tcx - } - - fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'tcx>) { - if expr.span.from_expansion() { - self.handle_new_span(expr.span, |tcx| rustc_hir_pretty::expr_to_string(&tcx, expr)); - } else { - intravisit::walk_expr(self, expr); - } - } - - fn visit_item(&mut self, item: &'tcx rustc_hir::Item<'tcx>) { - if item.span.from_expansion() { - self.handle_new_span(item.span, |tcx| rustc_hir_pretty::item_to_string(&tcx, item)); - } else { - intravisit::walk_item(self, item); - } - } -} diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 760e48baffa..b724d7e866a 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -175,15 +175,8 @@ fn target(sess: &rustc_session::Session) -> types::Target { } } -impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { - fn descr() -> &'static str { - "json" - } - - const RUN_ON_MODULE: bool = false; - type ModuleData = (); - - fn init( +impl<'tcx> JsonRenderer<'tcx> { + pub(crate) fn init( krate: clean::Crate, options: RenderOptions, cache: Cache, @@ -205,6 +198,15 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { krate, )) } +} + +impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { + fn descr() -> &'static str { + "json" + } + + const RUN_ON_MODULE: bool = false; + type ModuleData = (); fn save_module_data(&mut self) -> Self::ModuleData { unreachable!("RUN_ON_MODULE = false, should never call save_module_data") diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 09e7a42e944..fe56fdb2271 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -80,6 +80,8 @@ use rustc_session::{EarlyDiagCtxt, getopts}; use tracing::info; use crate::clean::utils::DOC_RUST_LANG_ORG_VERSION; +use crate::error::Error; +use crate::formats::cache::Cache; /// A macro to create a FxHashMap. /// @@ -734,13 +736,23 @@ pub(crate) fn wrap_return(dcx: DiagCtxtHandle<'_>, res: Result<(), String>) { } } -fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>( +fn run_renderer< + 'tcx, + T: formats::FormatRenderer<'tcx>, + F: FnOnce( + clean::Crate, + config::RenderOptions, + Cache, + TyCtxt<'tcx>, + ) -> Result<(T, clean::Crate), Error>, +>( krate: clean::Crate, renderopts: config::RenderOptions, cache: formats::cache::Cache, tcx: TyCtxt<'tcx>, + init: F, ) { - match formats::run_format::<T>(krate, renderopts, cache, tcx) { + match formats::run_format::<T, F>(krate, renderopts, cache, tcx, init) { Ok(_) => tcx.dcx().abort_if_errors(), Err(e) => { let mut msg = @@ -870,6 +882,7 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { let scrape_examples_options = options.scrape_examples_options.clone(); let bin_crate = options.bin_crate; + let output_format = options.output_format; let config = core::create_config(input, options, &render_options); let registered_lints = config.register_lints.is_some(); @@ -894,9 +907,10 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { sess.dcx().fatal("Compilation failed, aborting rustdoc"); } - let (krate, render_opts, mut cache) = sess.time("run_global_ctxt", || { - core::run_global_ctxt(tcx, show_coverage, render_options, output_format) - }); + let (krate, render_opts, mut cache, expanded_macros) = sess + .time("run_global_ctxt", || { + core::run_global_ctxt(tcx, show_coverage, render_options, output_format) + }); info!("finished with rustc"); if let Some(options) = scrape_examples_options { @@ -927,10 +941,32 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { info!("going to format"); match output_format { config::OutputFormat::Html => sess.time("render_html", || { - run_renderer::<html::render::Context<'_>>(krate, render_opts, cache, tcx) + run_renderer( + krate, + render_opts, + cache, + tcx, + |krate, render_opts, cache, tcx| { + html::render::Context::init( + krate, + render_opts, + cache, + tcx, + expanded_macros, + ) + }, + ) }), config::OutputFormat::Json => sess.time("render_json", || { - run_renderer::<json::JsonRenderer<'_>>(krate, render_opts, cache, tcx) + run_renderer( + krate, + render_opts, + cache, + tcx, + |krate, render_opts, cache, tcx| { + json::JsonRenderer::init(krate, render_opts, cache, tcx) + }, + ) }), // Already handled above with doctest runners. config::OutputFormat::Doctest => unreachable!(), diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs index 9f71d6ae789..16034c11827 100644 --- a/src/librustdoc/scrape_examples.rs +++ b/src/librustdoc/scrape_examples.rs @@ -18,7 +18,6 @@ use rustc_span::edition::Edition; use rustc_span::{BytePos, FileName, SourceFile}; use tracing::{debug, trace, warn}; -use crate::formats::renderer::FormatRenderer; use crate::html::render::Context; use crate::{clean, config, formats}; @@ -276,7 +275,8 @@ pub(crate) fn run( let inner = move || -> Result<(), String> { // Generates source files for examples renderopts.no_emit_shared = true; - let (cx, _) = Context::init(krate, renderopts, cache, tcx).map_err(|e| e.to_string())?; + let (cx, _) = Context::init(krate, renderopts, cache, tcx, Default::default()) + .map_err(|e| e.to_string())?; // Collect CrateIds corresponding to provided target crates // If two different versions of the crate in the dependency tree, then examples will be |
