diff --git a/src/compiler/build_runner/compilation_files.rs b/src/compiler/build_runner/compilation_files.rs index ccce7b4e072..8a6be2cdf9f 100644 --- a/src/compiler/build_runner/compilation_files.rs +++ b/src/compiler/build_runner/compilation_files.rs @@ -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 diff --git a/src/compiler/mod.rs b/src/compiler/mod.rs index fcfbc012d62..d7fa56e1c46 100644 --- a/src/compiler/mod.rs +++ b/src/compiler/mod.rs @@ -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!( @@ -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 @@ -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=") + } 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 { @@ -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="); diff --git a/src/ops/cargo_doc.rs b/src/ops/cargo_doc.rs index f088ae8ad33..ce219328c5a 100644 --- a/src/ops/cargo_doc.rs +++ b/src/ops/cargo_doc.rs @@ -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)?; } diff --git a/tests/testsuite/doc.rs b/tests/testsuite/doc.rs index 8660bc82841..3952978cc41 100644 --- a/tests/testsuite/doc.rs +++ b/tests/testsuite/doc.rs @@ -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()); +}