Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/compiler/build_runner/compilation_files.rs

@weihanglo weihanglo Aug 7, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you walk me through the failure rust-lang/rust#160724 (comment)?

I guess bootstrap pass -Zrustdoc-mergeable-info unconditionally when generating rustdoc JSON, but why?

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's the log output around where this is failing. The crash, and the failure, are in Cargo, not Rustdoc. https://triage.rust-lang.org/gha-logs/rust-lang/rust/92954202748#L2026-08-07T20:23:47.1415288Z

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like bootstrap passes -Zrustdoc-mergeable-info to the JSON doc build because that's the same target it uses for HTML docs. https://github.com/rust-lang/rust/blob/49c80b5a0db8abd63315c04ff34f58629e388281/src/bootstrap/src/core/build_steps/doc.rs#L666-L670

Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> {
flavor: FileFlavor::Normal,
}];

if bcx.gctx.cli_unstable().rustdoc_mergeable_info {
if bcx.gctx.cli_unstable().rustdoc_mergeable_info && !wants_json_doc {
// `-Zrustdoc-mergeable-info` always uses the new layout.
outputs.push(OutputFile {
path: self
Expand Down
11 changes: 7 additions & 4 deletions src/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,7 @@ fn prepare_rustdoc(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> CargoResu
let bcx = build_runner.bcx;
// script_metadata is not needed here, it is only for tests.
let mut rustdoc = build_runner.compilation.rustdoc_process(unit, None)?;
let wants_json_output = build_runner.bcx.build_config.intent.wants_doc_json_output();
if unit.pkg.manifest().is_embedded() {
if !bcx.gctx.cli_unstable().script {
anyhow::bail!(
Expand All @@ -889,7 +890,7 @@ fn prepare_rustdoc(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> CargoResu

unit.kind.add_target_arg(&mut rustdoc);

let doc_dir = if build_runner.bcx.build_config.intent.wants_doc_json_output() {
let doc_dir = if wants_json_output {
// Always use new layout for '--output-format=json'.
// In fix for https://github.com/rust-lang/cargo/issues/16291

Expand All @@ -908,7 +909,9 @@ fn prepare_rustdoc(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> CargoResu
if build_runner.bcx.gctx.cli_unstable().rustdoc_depinfo {
// html-static-files is required for keeping the shared styling resources
// html-non-static-files is required for keeping the original rustdoc emission
let mut arg = if build_runner.bcx.gctx.cli_unstable().rustdoc_mergeable_info {
let mut arg = if wants_json_output {
OsString::from("--emit=dep-info=")

@weihanglo weihanglo Aug 8, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an issue in rustdoc blocking this: rust-lang/rust#158869. I think this would produce zero JSON output with -Zrustdoc-depinfo.

A bit surprised we didn't have a test catching it.

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. That's not working.

To fix it, I think rustdoc needs changed. It was already broken before, though, so can we keep going?

} else if build_runner.bcx.gctx.cli_unstable().rustdoc_mergeable_info {
// toolchain resources are written at the end, at the same time as merging
OsString::from("--emit=html-non-static-files,dep-info=")
} else {
Expand All @@ -921,12 +924,12 @@ fn prepare_rustdoc(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> CargoResu
if build_runner.bcx.gctx.cli_unstable().checksum_freshness {
rustdoc.arg("-Z").arg("checksum-hash-algorithm=blake3");
}
} else if build_runner.bcx.gctx.cli_unstable().rustdoc_mergeable_info {
} else if build_runner.bcx.gctx.cli_unstable().rustdoc_mergeable_info && !wants_json_output {
// toolchain resources are written at the end, at the same time as merging
rustdoc.arg("--emit=html-non-static-files");
}

if build_runner.bcx.gctx.cli_unstable().rustdoc_mergeable_info {
if build_runner.bcx.gctx.cli_unstable().rustdoc_mergeable_info && !wants_json_output {
// write out mergeable data to be imported
rustdoc.arg("-Zunstable-options");
let mut arg = OsString::from("--write-doc-meta-dir=");
Expand Down
3 changes: 2 additions & 1 deletion src/ops/cargo_doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ pub struct DocOptions {
pub fn doc(ws: &Workspace<'_>, options: &DocOptions) -> CargoResult<()> {
let compilation = ops::compile(ws, &options.compile_opts)?;

if ws.gctx().cli_unstable().rustdoc_mergeable_info {
let wants_json_doc = matches!(options.output_format, OutputFormat::Json);
if ws.gctx().cli_unstable().rustdoc_mergeable_info && !wants_json_doc {
merge_cross_crate_info(ws, &compilation)?;
}

Expand Down
65 changes: 65 additions & 0 deletions tests/testsuite/doc.rs

@weihanglo weihanglo Aug 8, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind following C-TEST so the first commit serves as a repro. In the second commit, the git diff of the snapshot shows the bheavior change.

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Original file line number Diff line number Diff line change
Expand Up @@ -4214,3 +4214,68 @@ fn doc_output_format_json_with_deps() {
assert!(!p.root().join("target/doc/foo/index.html").exists());
assert!(!p.root().join("target/doc/bar/index.html").exists());
}

#[cargo_test(
nightly,
reason = "--output-format and -Zrustdoc-mergeable-info are unstable"
)]
fn doc_output_format_json_with_deps_and_mergeable_info() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
edition = "2021"

[dependencies]
bar = { path = "bar" }
"#,
)
.file("src/lib.rs", "pub fn foo_fn() {}")
.file(
"bar/Cargo.toml",
r#"
[package]
name = "bar"
version = "0.1.0"
edition = "2021"
"#,
)
.file("bar/src/lib.rs", "pub fn bar_fn() {}")
.build();

p.cargo("doc -Z unstable-options --output-format json -Zrustdoc-mergeable-info -v")
.masquerade_as_nightly_cargo(&["rustdoc-output-format"])
.with_stderr_data(
str![[r#"
[LOCKING] 1 package to highest compatible version
[CHECKING] bar v0.1.0 ([ROOT]/foo/bar)
[RUNNING] `rustc [..]--crate-name bar [..]`
[DOCUMENTING] bar v0.1.0 ([ROOT]/foo/bar)
[RUNNING] `rustdoc [..]--crate-name bar [..]--output-format=json[..]`
[DOCUMENTING] foo v0.1.0 ([ROOT]/foo)
[RUNNING] `rustdoc [..]--crate-name foo [..]--output-format=json[..]`
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
[GENERATED] [ROOT]/foo/target/doc/foo.json

"#]]
.unordered(),
)
.run();

let foo_json_path = p.root().join("target/doc/foo.json");
let bar_json_path = p.root().join("target/doc/bar.json");
assert!(foo_json_path.is_file());
assert!(bar_json_path.is_file());

let foo_json = fs::read_to_string(&foo_json_path).unwrap();
assert!(foo_json.contains("foo_fn"));

let bar_json = fs::read_to_string(&bar_json_path).unwrap();
assert!(bar_json.contains("bar_fn"));

assert!(!p.root().join("target/doc/foo/index.html").exists());
assert!(!p.root().join("target/doc/bar/index.html").exists());
}