)]}'
{
  "commit": "ed7afd2fc3fa5a3d8b8d03240b75501f0314c2d0",
  "tree": "b2166b5503fe38c3f68ed130133b41bf864d144f",
  "parents": [
    "df8c833da61ec3098e928e2e37d2eacadc6215fc"
  ],
  "author": {
    "name": "Marvin Hansen",
    "email": "marvin.hansen@gmail.com",
    "time": "Wed Aug 19 15:42:49 2026 +0000"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Wed Aug 19 15:42:49 2026 +0000"
  },
  "message": "fix(rustdoc): link doc tests against the cc_toolchain\u0027s runtime libs (#4220)\n\n`rust_doc_test` fails to link on any cc_toolchain that supplies its\nC++/unwind\nruntime via `static_runtime_lib` (i.e. enables\n`static_link_cpp_runtimes`).\nThis happens when cross compiling with the hermetic-LLVM e.g.:\n\n```\nld.lld: error: undefined symbol: _Unwind_Resume\n\u003e\u003e\u003e referenced by alloc.rs:0 ... liballoc-*.rlib\n... and the rest of the _Unwind_* family\n```\n\n`rust_library` / `rust_binary` / `rust_test` are fine. Only doc tests\nfail.\n\n## Evidence\n\nThe first commit adds only a test to reproduce the issue by extending\nthe\nfixture from #3741 (which already declares a cc_toolchain with\n`static_runtime_lib \u003d \":dummy.a\"`); the second commit adds the fix:\n\n| commit |\n`//test/unit/cc_toolchain_runtime_lib:runtime_libs_test/doc_test` |\n|---|---|\n| `test(rustdoc): reproduce ...` | **FAILED** |\n| `fix(rustdoc): link doc tests ...` | **PASSED** |\n\nThe failing action\u0027s argv shows the search path arriving while the\nlibrary\nreference never does:\n\n```\n\"-Lnative\u003dtest/unit/cc_toolchain_runtime_lib\",   \u003c- present\n...                                              \u003c- no -Clink-arg\u003d-ldummy\n```\n\n## Cause\n\n`add_native_link_flags` emits the runtime libs\u0027 `-Lnative\u003d`\nunconditionally but\ngates the matching `-lstatic\u003d` behind `include_link_flags`, which\nrustdoc sets\nto False (#2467). #4080 added a compensating `-Clink-arg\u003d-l` loop for\ndoc tests,\nbut this does not work for a `static_runtime_lib`.\n\n## Alternatives  \n\nInjecting the flag from outside doesn\u0027t work. The archive is already in\nthe\ndoc test\u0027s runfiles (via #3741), so `-Clink-arg\u003d\u003cits short_path\u003e` does\nfix doc\ntests. However, `toolchain.extra_rustc_flags` applies to every rustc\ninvocation,\nand normal `rust_test` binaries link in the execroot, where that\nrunfiles-relative path doesn\u0027t exist: `clang++: error: no such file or\ndirectory`. Doc tests and normal links need *different paths to the same\nfile*,\nNo single toolchain-level flag satisfies both. Per-target\n`rustdoc_flags`\ndoes work, but only by hardcoding the canonical repo name and the\nruntime lib\u0027s\ninternal layout in every `rust_doc_test`. However, this is\nunmaintainable in any major project.\n\n## Changes\n\n- `rustdoc.bzl` — extend the #4080 loop to the cc_toolchain runtime\nlibs,\nmirroring the crate-type split in `collect_inputs`. Guarded on\n`cc_toolchain`\n  being present (#3665).\n- `rustdoc_test.bzl` — add those libs\u0027 root to `--strip_substring`.\nRequired:\n  they\u0027re built in a different configuration than the crate outputs, so\notherwise the `-Lnative\u003d` path stays an execroot path that doesn\u0027t exist\nin\nthe runfiles tree the doc test runs from. Only non-empty roots are added\n—\nsource-file runtime libs need no stripping, and an empty root would emit\n  `--strip_substring\u003d/`, which `rustdoc_test_writer` applies as a plain\n  `str::replace`.\n\nThe libs already reach runfiles via `ctx.runfiles(transitive_files \u003d\naction.inputs)`\nthanks to #3741.\n\n## Testing\n\n`bazel test -- //... -//test/unit/remap_path_prefix:integration_test` on\nmacOS:\n**569 passed / 35 skipped**, against **568 / 35** before. The new doc\ntest is\nthe only target that changed status; every other action was a cache hit,\nso\nthis is a provable no-op where `static_runtime_lib` is empty.\n \nThe patch has also been verified against a repo that builds with\nhermetic-LLVM and all failing doc tests\npassed.\n\n---------\n\nSigned-off-by: Marvin Hansen \u003cmarvin.hansen@gmail.com\u003e",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "4c407755f9940ed54f174273452a7f853027ea2d",
      "old_mode": 33188,
      "old_path": "rust/private/rustdoc.bzl",
      "new_id": "cc0a23e5c7b6ffe08c194418595b6ac78c6dd6ed",
      "new_mode": 33188,
      "new_path": "rust/private/rustdoc.bzl"
    },
    {
      "type": "modify",
      "old_id": "733444eff783e3a54341949cb9268f3a5dac382f",
      "old_mode": 33188,
      "old_path": "rust/private/rustdoc_test.bzl",
      "new_id": "664878cecd9bc6ff4e996fc0c31cfda0c43d1ecc",
      "new_mode": 33188,
      "new_path": "rust/private/rustdoc_test.bzl"
    },
    {
      "type": "modify",
      "old_id": "b097e1faf04b4e6598a0c30ab488680f8ca8c201",
      "old_mode": 33188,
      "old_path": "test/unit/cc_toolchain_runtime_lib/cc_toolchain_runtime_lib_test.bzl",
      "new_id": "504cb106a260823324462a3638c56933142c4e9e",
      "new_mode": 33188,
      "new_path": "test/unit/cc_toolchain_runtime_lib/cc_toolchain_runtime_lib_test.bzl"
    }
  ]
}
