From 816a6d999865fa24060c2047dd7f9faed109edbb Mon Sep 17 00:00:00 2001 From: Randolf Jung Date: Thu, 24 Sep 2026 01:38:12 -0700 Subject: [PATCH] rustdoc: align the doctest runner with the test platform --- rust/private/rustdoc_test.bzl | 6 +- test/unit/rustdoc/BUILD.bazel | 25 ++++++ test/unit/rustdoc/rustdoc_unit_test.bzl | 100 ++++++++++++++++++++++++ 3 files changed, 129 insertions(+), 2 deletions(-) diff --git a/rust/private/rustdoc_test.bzl b/rust/private/rustdoc_test.bzl index 664878cecd..9a6a0efac4 100644 --- a/rust/private/rustdoc_test.bzl +++ b/rust/private/rustdoc_test.bzl @@ -209,7 +209,7 @@ def _compiled_rust_doc_test_impl(ctx, toolchain, crate_info): execution_requirements = {"supports-path-mapping": ""} if action.supports_path_mapping else None, ) - test_runner = ctx.actions.declare_file(ctx.label.name) + test_runner = ctx.actions.declare_file(ctx.label.name + (".exe" if ctx.executable._test_runner_bin.extension == "exe" else "")) ctx.actions.symlink( output = test_runner, target_file = ctx.executable._test_runner_bin, @@ -330,6 +330,8 @@ def _rust_doc_test_impl(ctx): if use_compiled_doctest: return _compiled_rust_doc_test_impl(ctx, toolchain, crate_info) else: + if toolchain.exec_triple.str != toolchain.target_triple.str: + fail("Cross-built doctests require experimental_compile_rustdoc_tests and a nightly compiler; legacy doctests execute their compiler during the test.") return _legacy_rust_doc_test_impl(ctx, toolchain, crate_info) rust_doc_test = rule( @@ -389,7 +391,7 @@ rust_doc_test = rule( ), "_test_runner_bin": attr.label( doc = "A binary used for running compiled doc test binaries.", - cfg = "exec", + cfg = config.exec("test"), default = Label("//rust/private/rustdoc:rustdoc_test_runner"), executable = True, ), diff --git a/test/unit/rustdoc/BUILD.bazel b/test/unit/rustdoc/BUILD.bazel index f4375c3426..5198f8190a 100644 --- a/test/unit/rustdoc/BUILD.bazel +++ b/test/unit/rustdoc/BUILD.bazel @@ -3,3 +3,28 @@ load(":rustdoc_unit_test.bzl", "rustdoc_test_suite") rustdoc_test_suite( name = "rustdoc_test_suite", ) + +# Distinct platforms exercise test helpers without executing foreign binaries. +platform( + name = "macos_aarch64", + constraint_values = [ + "@platforms//cpu:aarch64", + "@platforms//os:macos", + ], +) + +platform( + name = "macos_x86_64", + constraint_values = [ + "@platforms//cpu:x86_64", + "@platforms//os:macos", + ], +) + +config_setting( + name = "compiled_doctests", + flag_values = { + "//rust/settings:experimental_compile_rustdoc_tests": "true", + "//rust/toolchain/channel:channel": "nightly", + }, +) diff --git a/test/unit/rustdoc/rustdoc_unit_test.bzl b/test/unit/rustdoc/rustdoc_unit_test.bzl index b0740cb861..53ef8a1190 100644 --- a/test/unit/rustdoc/rustdoc_unit_test.bzl +++ b/test/unit/rustdoc/rustdoc_unit_test.bzl @@ -1,5 +1,6 @@ """Unittest to verify properties of rustdoc rules""" +load("@bazel_features//:features.bzl", "bazel_features") load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") load("@bazel_skylib//rules:write_file.bzl", "write_file") load("@rules_cc//cc:defs.bzl", "cc_library") @@ -197,6 +198,65 @@ rustdoc_with_json_error_format_test = analysistest.make(_rustdoc_with_json_error }) rustdoc_test_uses_cc_library_native_lib_test = analysistest.make(_rustdoc_test_uses_cc_library_native_lib_test_impl) +def _compiled_runner_file(target): + executable = target[DefaultInfo].files_to_run.executable + action = [action for action in target.actions if executable in action.outputs.to_list()][0] + return action.inputs.to_list()[0] + +def _compiled_runner_test_impl(ctx): + env = analysistest.begin(ctx) + target = analysistest.target_under_test(env) + runner = _compiled_runner_file(target) + executable = target[DefaultInfo].files_to_run.executable + + asserts.true(env, any([action.mnemonic == "RustdocTestCompile" for action in target.actions])) + asserts.equals(env, runner.extension, executable.extension) + return analysistest.end(env) + +compiled_runner_test = analysistest.make( + _compiled_runner_test_impl, +) + +def _compiled_runner_platform_test_impl(ctx): + env = analysistest.begin(ctx) + target = analysistest.target_under_test(env) + runner = _compiled_runner_file(target) + asserts.true( + env, + runner.path.startswith("bazel-out/macos_x86_64-"), + "Expected the test-platform runner, got {}".format(runner.path), + ) + return analysistest.end(env) + +compiled_runner_platform_test = analysistest.make( + _compiled_runner_platform_test_impl, + config_settings = { + "//command_line_option:extra_execution_platforms": [ + str(Label(":macos_aarch64")), + str(Label(":macos_x86_64")), + ], + "//command_line_option:platforms": str(Label(":macos_x86_64")), + }, +) + +def _legacy_cross_build_test_impl(ctx): + env = analysistest.begin(ctx) + asserts.expect_failure(env, "Cross-built doctests require experimental_compile_rustdoc_tests") + return analysistest.end(env) + +legacy_cross_build_test = analysistest.make( + _legacy_cross_build_test_impl, + expect_failure = True, + config_settings = { + "//command_line_option:extra_execution_platforms": [ + str(Label(":macos_aarch64")), + str(Label(":macos_x86_64")), + ], + "//command_line_option:platforms": str(Label(":macos_x86_64")), + str(Label("//rust/settings:experimental_compile_rustdoc_tests")): False, + }, +) + def _target_maker(rule_fn, name, rustdoc_deps = [], rustdoc_proc_macro_deps = [], **kwargs): rule_fn( name = name, @@ -464,6 +524,13 @@ def _define_targets(): target_compatible_with = NOT_WINDOWS, ) + rust_doc_test( + name = "compiled_runner_fixture", + crate = ":lib", + deps = [":adder"], + tags = ["manual"], + ) + def rustdoc_test_suite(name): """Entry-point macro called from the BUILD file. @@ -533,6 +600,36 @@ def rustdoc_test_suite(name): target_under_test = ":lib_with_cc_library_doctest", ) + compiled_runner_test( + name = "compiled_runner_test", + target_compatible_with = select({ + ":compiled_doctests": [], + "//conditions:default": ["@platforms//:incompatible"], + }), + target_under_test = ":compiled_runner_fixture", + ) + + compiled_runner_platform_test( + name = "compiled_runner_platform_test", + target_under_test = ":compiled_runner_fixture", + target_compatible_with = [ + "@platforms//cpu:aarch64", + "@platforms//os:macos", + ] + ([] if bazel_features.toolchains.has_default_test_toolchain_type else ["@platforms//:incompatible"]) + select({ + ":compiled_doctests": [], + "//conditions:default": ["@platforms//:incompatible"], + }), + ) + + legacy_cross_build_test( + name = "legacy_cross_build_test", + target_under_test = ":lib_doctest", + target_compatible_with = [ + "@platforms//cpu:aarch64", + "@platforms//os:macos", + ], + ) + rustdoc_for_generated_root_test( name = "rustdoc_for_generated_root_test", target_under_test = ":gen_lib_doc", @@ -562,6 +659,9 @@ def rustdoc_test_suite(name): ":rustdoc_with_args_test", ":rustdoc_with_json_error_format_test", ":rustdoc_test_uses_cc_library_native_lib_test", + ":compiled_runner_test", + ":compiled_runner_platform_test", + ":legacy_cross_build_test", ":rustdoc_for_generated_root_test", ":rustdoc_zip_output_test", ],