Skip to content

Commit

Permalink
Unrolled build for rust-lang#137684
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#137684 - GuillaumeGomez:rustdoc-dep-info, r=notriddle

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

Fixes rust-lang#91982.

This PR adds the `--emit=dep-info` command line flag support. It will be helpful for `cargo` development.

cc ````@epage````

r? ````@notriddle````
  • Loading branch information
rust-timer authored Mar 3, 2025
2 parents d491662 + b97310c commit c985b40
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 16 deletions.
28 changes: 22 additions & 6 deletions src/librustdoc/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}
}
}
}
}
Expand All @@ -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)
Expand Down
24 changes: 18 additions & 6 deletions src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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());
Expand All @@ -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 {
Expand All @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/html/render/write_shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ fn write_rendered_cross_crate_info(
include_sources: bool,
) -> Result<(), Error> {
let m = &opt.should_merge;
if opt.emit.is_empty() || opt.emit.contains(&EmitType::InvocationSpecific) {
if opt.should_emit_crate() {
if include_sources {
write_rendered_cci::<SourcesPart, _>(SourcesPart::blank, dst, crates, m)?;
}
Expand Down
10 changes: 8 additions & 2 deletions src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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;
}
Expand Down
7 changes: 7 additions & 0 deletions src/tools/run-make-support/src/external_deps/rustdoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,11 @@ impl Rustdoc {
self.cmd.arg(format);
self
}

/// Specify type(s) of output files to generate.
pub fn emit<S: AsRef<str>>(&mut self, kinds: S) -> &mut Self {
let kinds = kinds.as_ref();
self.cmd.arg(format!("--emit={kinds}"));
self
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ Options:
--generate-redirect-map
Generate JSON file at the top level instead of
generating HTML redirection files
--emit [unversioned-shared-resources,toolchain-shared-resources,invocation-specific]
--emit [unversioned-shared-resources,toolchain-shared-resources,invocation-specific,dep-info]
Comma separated list of types of output for rustdoc to
emit
--no-run Compile doctests without running them
Expand Down
1 change: 1 addition & 0 deletions tests/run-make/rustdoc-dep-info/bar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include!("foo.rs");
1 change: 1 addition & 0 deletions tests/run-make/rustdoc-dep-info/doc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
blablabla
1 change: 1 addition & 0 deletions tests/run-make/rustdoc-dep-info/foo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub fn foo() {}
6 changes: 6 additions & 0 deletions tests/run-make/rustdoc-dep-info/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#![crate_name = "foo"]

#[cfg_attr(doc, doc = include_str!("doc.md"))]
pub struct Bar;

mod bar;
21 changes: 21 additions & 0 deletions tests/run-make/rustdoc-dep-info/rmake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// This is a simple smoke test for rustdoc's `--emit dep-info` feature. It prints out
// information about dependencies in a Makefile-compatible format, as a `.d` file.

use run_make_support::assertion_helpers::assert_contains;
use run_make_support::{path, rfs, rustdoc};

fn main() {
// We're only emitting dep info, so we shouldn't be running static analysis to
// figure out that this program is erroneous.
rustdoc().input("lib.rs").arg("-Zunstable-options").emit("dep-info").run();

let content = rfs::read_to_string("foo.d");
assert_contains(&content, "lib.rs:");
assert_contains(&content, "foo.rs:");
assert_contains(&content, "bar.rs:");
assert_contains(&content, "doc.md:");

// Now we check that we can provide a file name to the `dep-info` argument.
rustdoc().input("lib.rs").arg("-Zunstable-options").emit("dep-info=bla.d").run();
assert!(path("bla.d").exists());
}

0 comments on commit c985b40

Please sign in to comment.