Change:
); } let compiler = builder.compiler(stage, builder.config.build); <ins> let target_doc_dir_name = if format == DocumentationFormat::JSON { "json-doc" } else { "doc" }; let target_dir = builder.stage_out(compiler, Mode::Std).join(target.triple).join(target_doc_dir_name); </ins> // This is directory where the compiler will place the output of the command. // We will then copy the files from this directory into the final `out` directory, the specified // as a function parameter. <del> let out_dir = builder.stage_out(compiler, Mode::Std).join(target.triple).join("doc"); // `cargo` uses the same directory for both JSON docs and HTML docs. // This could lead to cross-contamination when copying files into the specified `out` directory. // For example: // ```bash // x doc std // x doc std --json // ``` // could lead to HTML docs being copied into the JSON docs output directory. // To avoid this issue, we clean the doc folder before invoking `cargo`. if out_dir.exists() { builder.remove_dir(&out_dir); } </del> <ins> let out_dir = target_dir.join(target.triple).join("doc"); </ins> let run_cargo_rustdoc_for = |package: &str| { let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "rustdoc"); compile::std_cargo(builder, target, compiler.stage, &mut cargo); cargo <ins> .arg("--target-dir") .arg(&*target_dir.to_string_lossy()) </ins> .arg("-p") .arg(package) .arg("-Zskip-rustdoc-fingerprint")

Discussion:
I tried this: I expected to see this happen: The second invocation takes essentially no time. Instead, this happened: The docs were completely rebuilt. The problem is that we remove the docs between each invocation: this is a regression from - do you think you'll have time to follow up? I think we can either add a stamp file to avoid rebuilding, or find some other way to avoid removing the whole directory - maybe we can only remove/copy the files, rather than everything? <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --HEAD is branched from . <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Ok, I confirmed that rustdoc only creates JSON files with --output-format json: So it should be enough to only copy .json files when passed --json, and only non-json files when it's not passed. We should also add a test that produces the same output in json-doc as , to avoid a regression if rustdoc starts emitting JSON files in the default HTML format.
I can't jump on it immediately, but I should be able to follow up in a couple of weeks
claim
We can do this validation for dir, but I am not sure if this is possible for dir since each time json output changes. The layout of json context is getting change even if you don't change anyhing on the source code. I print sha2 sums below to demonstrate the situation. 1st attempt: 2nd attempt right after the first attempt The demonstration is from
thanks for investigating; sounds like we should report that as a separate bug in rustdoc. But for now it's ok if the files don't match exactly as long as the file names are the same between runs.