Add rustdoc support for --emit=dep-info[=path]

This commit is contained in:
Guillaume Gomez 2025-02-26 17:13:30 +01:00
parent 745297e7aa
commit 98eb2e3e5a
3 changed files with 48 additions and 14 deletions

View file

@ -315,23 +315,30 @@ pub(crate) enum ModuleSorting {
Alphabetical,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) enum EmitType {
Unversioned,
Toolchain,
InvocationSpecific,
DepInfo(Option<PathBuf>),
}
impl FromStr for EmitType {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
use EmitType::*;
match s {
"unversioned-shared-resources" => Ok(Unversioned),
"toolchain-shared-resources" => Ok(Toolchain),
"invocation-specific" => Ok(InvocationSpecific),
_ => Err(()),
"unversioned-shared-resources" => Ok(Self::Unversioned),
"toolchain-shared-resources" => Ok(Self::Toolchain),
"invocation-specific" => Ok(Self::InvocationSpecific),
"dep-info" => Ok(Self::DepInfo(None)),
option => {
if let Some(file) = option.strip_prefix("dep-info=") {
Ok(Self::DepInfo(Some(Path::new(file).into())))
} else {
Err(())
}
}
}
}
}
@ -340,6 +347,15 @@ impl RenderOptions {
pub(crate) fn should_emit_crate(&self) -> bool {
self.emit.is_empty() || self.emit.contains(&EmitType::InvocationSpecific)
}
pub(crate) fn dep_info(&self) -> Option<Option<&Path>> {
for emit in &self.emit {
if let EmitType::DepInfo(file) = emit {
return Some(file.as_deref());
}
}
None
}
}
/// Create the input (string or file path)

View file

@ -15,11 +15,12 @@ use rustc_hir::def::Res;
use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{HirId, Path};
use rustc_interface::interface;
use rustc_lint::{MissingDoc, late_lint_mod};
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
use rustc_session::config::{self, CrateType, ErrorOutputType, Input, ResolveDocLinks};
use rustc_session::config::{
self, CrateType, ErrorOutputType, Input, OutFileName, OutputType, OutputTypes, ResolveDocLinks,
};
pub(crate) use rustc_session::config::{Options, UnstableOptions};
use rustc_session::{Session, lint};
use rustc_span::source_map;
@ -219,7 +220,7 @@ pub(crate) fn create_config(
remap_path_prefix,
..
}: RustdocOptions,
RenderOptions { document_private, .. }: &RenderOptions,
render_options: &RenderOptions,
) -> rustc_interface::Config {
// Add the doc cfg into the doc build.
cfgs.push("doc".to_string());
@ -245,8 +246,11 @@ pub(crate) fn create_config(
let crate_types =
if proc_macro_crate { vec![CrateType::ProcMacro] } else { vec![CrateType::Rlib] };
let resolve_doc_links =
if *document_private { ResolveDocLinks::All } else { ResolveDocLinks::Exported };
let resolve_doc_links = if render_options.document_private {
ResolveDocLinks::All
} else {
ResolveDocLinks::Exported
};
let test = scrape_examples_options.map(|opts| opts.scrape_tests).unwrap_or(false);
// plays with error output here!
let sessopts = config::Options {
@ -269,10 +273,18 @@ pub(crate) fn create_config(
crate_name,
test,
remap_path_prefix,
output_types: if let Some(file) = render_options.dep_info() {
OutputTypes::new(&[(
OutputType::DepInfo,
file.map(|f| OutFileName::Real(f.to_path_buf())),
)])
} else {
OutputTypes::new(&[])
},
..Options::default()
};
interface::Config {
rustc_interface::Config {
opts: sessopts,
crate_cfg: cfgs,
crate_check_cfg: check_cfgs,

View file

@ -561,7 +561,7 @@ fn opts() -> Vec<RustcOptGroup> {
"",
"emit",
"Comma separated list of types of output for rustdoc to emit",
"[unversioned-shared-resources,toolchain-shared-resources,invocation-specific]",
"[unversioned-shared-resources,toolchain-shared-resources,invocation-specific,dep-info]",
),
opt(Unstable, FlagMulti, "", "no-run", "Compile doctests without running them", ""),
opt(
@ -890,7 +890,13 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
// 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;
} else if run_check {
}
if render_opts.dep_info().is_some() {
rustc_interface::passes::write_dep_info(tcx);
}
if run_check {
// Since we're in "check" mode, no need to generate anything beyond this point.
return;
}