Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c985b40

Browse files
authoredMar 3, 2025
Unrolled build for rust-lang#137684
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````
2 parents d491662 + b97310c commit c985b40

File tree

11 files changed

+87
-16
lines changed

11 files changed

+87
-16
lines changed
 

‎src/librustdoc/config.rs

+22-6
Original file line numberDiff line numberDiff line change
@@ -315,23 +315,30 @@ pub(crate) enum ModuleSorting {
315315
Alphabetical,
316316
}
317317

318-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
318+
#[derive(Clone, Debug, PartialEq, Eq)]
319319
pub(crate) enum EmitType {
320320
Unversioned,
321321
Toolchain,
322322
InvocationSpecific,
323+
DepInfo(Option<PathBuf>),
323324
}
324325

325326
impl FromStr for EmitType {
326327
type Err = ();
327328

328329
fn from_str(s: &str) -> Result<Self, Self::Err> {
329-
use EmitType::*;
330330
match s {
331-
"unversioned-shared-resources" => Ok(Unversioned),
332-
"toolchain-shared-resources" => Ok(Toolchain),
333-
"invocation-specific" => Ok(InvocationSpecific),
334-
_ => Err(()),
331+
"unversioned-shared-resources" => Ok(Self::Unversioned),
332+
"toolchain-shared-resources" => Ok(Self::Toolchain),
333+
"invocation-specific" => Ok(Self::InvocationSpecific),
334+
"dep-info" => Ok(Self::DepInfo(None)),
335+
option => {
336+
if let Some(file) = option.strip_prefix("dep-info=") {
337+
Ok(Self::DepInfo(Some(Path::new(file).into())))
338+
} else {
339+
Err(())
340+
}
341+
}
335342
}
336343
}
337344
}
@@ -340,6 +347,15 @@ impl RenderOptions {
340347
pub(crate) fn should_emit_crate(&self) -> bool {
341348
self.emit.is_empty() || self.emit.contains(&EmitType::InvocationSpecific)
342349
}
350+
351+
pub(crate) fn dep_info(&self) -> Option<Option<&Path>> {
352+
for emit in &self.emit {
353+
if let EmitType::DepInfo(file) = emit {
354+
return Some(file.as_deref());
355+
}
356+
}
357+
None
358+
}
343359
}
344360

345361
/// Create the input (string or file path)

‎src/librustdoc/core.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ use rustc_hir::def::Res;
1515
use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId};
1616
use rustc_hir::intravisit::{self, Visitor};
1717
use rustc_hir::{HirId, Path};
18-
use rustc_interface::interface;
1918
use rustc_lint::{MissingDoc, late_lint_mod};
2019
use rustc_middle::hir::nested_filter;
2120
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
22-
use rustc_session::config::{self, CrateType, ErrorOutputType, Input, ResolveDocLinks};
21+
use rustc_session::config::{
22+
self, CrateType, ErrorOutputType, Input, OutFileName, OutputType, OutputTypes, ResolveDocLinks,
23+
};
2324
pub(crate) use rustc_session::config::{Options, UnstableOptions};
2425
use rustc_session::{Session, lint};
2526
use rustc_span::source_map;
@@ -219,7 +220,7 @@ pub(crate) fn create_config(
219220
remap_path_prefix,
220221
..
221222
}: RustdocOptions,
222-
RenderOptions { document_private, .. }: &RenderOptions,
223+
render_options: &RenderOptions,
223224
) -> rustc_interface::Config {
224225
// Add the doc cfg into the doc build.
225226
cfgs.push("doc".to_string());
@@ -245,8 +246,11 @@ pub(crate) fn create_config(
245246

246247
let crate_types =
247248
if proc_macro_crate { vec![CrateType::ProcMacro] } else { vec![CrateType::Rlib] };
248-
let resolve_doc_links =
249-
if *document_private { ResolveDocLinks::All } else { ResolveDocLinks::Exported };
249+
let resolve_doc_links = if render_options.document_private {
250+
ResolveDocLinks::All
251+
} else {
252+
ResolveDocLinks::Exported
253+
};
250254
let test = scrape_examples_options.map(|opts| opts.scrape_tests).unwrap_or(false);
251255
// plays with error output here!
252256
let sessopts = config::Options {
@@ -269,10 +273,18 @@ pub(crate) fn create_config(
269273
crate_name,
270274
test,
271275
remap_path_prefix,
276+
output_types: if let Some(file) = render_options.dep_info() {
277+
OutputTypes::new(&[(
278+
OutputType::DepInfo,
279+
file.map(|f| OutFileName::Real(f.to_path_buf())),
280+
)])
281+
} else {
282+
OutputTypes::new(&[])
283+
},
272284
..Options::default()
273285
};
274286

275-
interface::Config {
287+
rustc_interface::Config {
276288
opts: sessopts,
277289
crate_cfg: cfgs,
278290
crate_check_cfg: check_cfgs,

‎src/librustdoc/html/render/write_shared.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ fn write_rendered_cross_crate_info(
153153
include_sources: bool,
154154
) -> Result<(), Error> {
155155
let m = &opt.should_merge;
156-
if opt.emit.is_empty() || opt.emit.contains(&EmitType::InvocationSpecific) {
156+
if opt.should_emit_crate() {
157157
if include_sources {
158158
write_rendered_cci::<SourcesPart, _>(SourcesPart::blank, dst, crates, m)?;
159159
}

‎src/librustdoc/lib.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ fn opts() -> Vec<RustcOptGroup> {
561561
"",
562562
"emit",
563563
"Comma separated list of types of output for rustdoc to emit",
564-
"[unversioned-shared-resources,toolchain-shared-resources,invocation-specific]",
564+
"[unversioned-shared-resources,toolchain-shared-resources,invocation-specific,dep-info]",
565565
),
566566
opt(Unstable, FlagMulti, "", "no-run", "Compile doctests without running them", ""),
567567
opt(
@@ -890,7 +890,13 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
890890
// if we ran coverage, bail early, we don't need to also generate docs at this point
891891
// (also we didn't load in any of the useful passes)
892892
return;
893-
} else if run_check {
893+
}
894+
895+
if render_opts.dep_info().is_some() {
896+
rustc_interface::passes::write_dep_info(tcx);
897+
}
898+
899+
if run_check {
894900
// Since we're in "check" mode, no need to generate anything beyond this point.
895901
return;
896902
}

‎src/tools/run-make-support/src/external_deps/rustdoc.rs

+7
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,11 @@ impl Rustdoc {
132132
self.cmd.arg(format);
133133
self
134134
}
135+
136+
/// Specify type(s) of output files to generate.
137+
pub fn emit<S: AsRef<str>>(&mut self, kinds: S) -> &mut Self {
138+
let kinds = kinds.as_ref();
139+
self.cmd.arg(format!("--emit={kinds}"));
140+
self
141+
}
135142
}

‎tests/run-make/rustdoc-default-output/output-default.stdout

+1-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ Options:
153153
--generate-redirect-map
154154
Generate JSON file at the top level instead of
155155
generating HTML redirection files
156-
--emit [unversioned-shared-resources,toolchain-shared-resources,invocation-specific]
156+
--emit [unversioned-shared-resources,toolchain-shared-resources,invocation-specific,dep-info]
157157
Comma separated list of types of output for rustdoc to
158158
emit
159159
--no-run Compile doctests without running them
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include!("foo.rs");
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
blablabla
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub fn foo() {}
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#![crate_name = "foo"]
2+
3+
#[cfg_attr(doc, doc = include_str!("doc.md"))]
4+
pub struct Bar;
5+
6+
mod bar;
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// This is a simple smoke test for rustdoc's `--emit dep-info` feature. It prints out
2+
// information about dependencies in a Makefile-compatible format, as a `.d` file.
3+
4+
use run_make_support::assertion_helpers::assert_contains;
5+
use run_make_support::{path, rfs, rustdoc};
6+
7+
fn main() {
8+
// We're only emitting dep info, so we shouldn't be running static analysis to
9+
// figure out that this program is erroneous.
10+
rustdoc().input("lib.rs").arg("-Zunstable-options").emit("dep-info").run();
11+
12+
let content = rfs::read_to_string("foo.d");
13+
assert_contains(&content, "lib.rs:");
14+
assert_contains(&content, "foo.rs:");
15+
assert_contains(&content, "bar.rs:");
16+
assert_contains(&content, "doc.md:");
17+
18+
// Now we check that we can provide a file name to the `dep-info` argument.
19+
rustdoc().input("lib.rs").arg("-Zunstable-options").emit("dep-info=bla.d").run();
20+
assert!(path("bla.d").exists());
21+
}

0 commit comments

Comments
 (0)
Failed to load comments.