Depend on a copy of rustfmt for the target (#2685)

The toolchain_files() and current_rust_toolchain() rules return files
for the current 'exec' platform. This is perfecly reasonable if you want
to use these tools as part of ctx.actions.run(). But if you want to use
these as part of 'data = []' (runfiles), they must be built for the
target.

Fixes: https://github.com/bazelbuild/rules_rust/issues/2684
diff --git a/rust/private/toolchain_utils.bzl b/rust/private/toolchain_utils.bzl
index 4fb2ae8..64f759f 100644
--- a/rust/private/toolchain_utils.bzl
+++ b/rust/private/toolchain_utils.bzl
@@ -53,7 +53,7 @@
     )]
 
 toolchain_files = rule(
-    doc = "A rule for fetching files from a rust toolchain.",
+    doc = "A rule for fetching files from a rust toolchain for the exec platform.",
     implementation = _toolchain_files_impl,
     attrs = {
         "tool": attr.string(
@@ -95,3 +95,32 @@
         str(Label("@rules_rust//rust:toolchain_type")),
     ],
 )
+
+def _transition_to_target_impl(settings, _attr):
+    return {
+        # String conversion is needed to prevent a crash with Bazel 6.x.
+        "//command_line_option:extra_execution_platforms": [
+            str(platform)
+            for platform in settings["//command_line_option:platforms"]
+        ],
+    }
+
+_transition_to_target = transition(
+    implementation = _transition_to_target_impl,
+    inputs = ["//command_line_option:platforms"],
+    outputs = ["//command_line_option:extra_execution_platforms"],
+)
+
+def _toolchain_files_for_target_impl(ctx):
+    return [ctx.attr.toolchain_files[0][DefaultInfo]]
+
+toolchain_files_for_target = rule(
+    doc = "A rule for fetching files from a rust toolchain for the target platform.",
+    implementation = _toolchain_files_for_target_impl,
+    attrs = {
+        "toolchain_files": attr.label(cfg = _transition_to_target, mandatory = True),
+        "_allowlist_function_transition": attr.label(
+            default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
+        ),
+    },
+)
diff --git a/rust/toolchain/BUILD.bazel b/rust/toolchain/BUILD.bazel
index 6cae508..b5e57af 100644
--- a/rust/toolchain/BUILD.bazel
+++ b/rust/toolchain/BUILD.bazel
@@ -1,5 +1,5 @@
 load("//rust/private:rustfmt.bzl", "current_rustfmt_toolchain")
-load("//rust/private:toolchain_utils.bzl", "current_rust_toolchain", "toolchain_files")
+load("//rust/private:toolchain_utils.bzl", "current_rust_toolchain", "toolchain_files", "toolchain_files_for_target")
 
 package(default_visibility = ["//visibility:public"])
 
@@ -41,6 +41,12 @@
     name = "current_rustfmt_toolchain",
 )
 
+toolchain_files_for_target(
+    name = "current_rustfmt_toolchain_for_target",
+    toolchain_files = ":current_rustfmt_toolchain",
+    visibility = ["//:__subpackages__"],
+)
+
 alias(
     name = "current_rustfmt_files",
     actual = "current_rustfmt_toolchain",
diff --git a/tools/rustfmt/BUILD.bazel b/tools/rustfmt/BUILD.bazel
index 1a74c99..c8aeb81 100644
--- a/tools/rustfmt/BUILD.bazel
+++ b/tools/rustfmt/BUILD.bazel
@@ -20,11 +20,11 @@
     ),
     data = [
         "//:rustfmt.toml",
-        "//rust/toolchain:current_rustfmt_toolchain",
+        "//rust/toolchain:current_rustfmt_toolchain_for_target",
     ],
     edition = "2018",
     rustc_env = {
-        "RUSTFMT": "$(rlocationpath //rust/toolchain:current_rustfmt_toolchain)",
+        "RUSTFMT": "$(rlocationpath //rust/toolchain:current_rustfmt_toolchain_for_target)",
         "RUSTFMT_CONFIG": "$(rlocationpath //:rustfmt.toml)",
     },
     deps = [
@@ -55,10 +55,7 @@
         "ASPECT_REPOSITORY": aspect_repository(),
         "RUST_DEFAULT_EDITION": "$(RUST_DEFAULT_EDITION)",
     },
-    toolchains = [
-        "@rules_rust//rust/toolchain:current_rust_toolchain",
-        "@rules_rust//rust/toolchain:current_rustfmt_toolchain",
-    ],
+    toolchains = ["@rules_rust//rust/toolchain:current_rust_toolchain"],
     visibility = ["//visibility:public"],
     deps = [
         ":rustfmt_lib",
@@ -94,15 +91,12 @@
     srcs = [
         "src/upstream_rustfmt_wrapper.rs",
     ],
-    data = ["//rust/toolchain:current_rustfmt_toolchain"],
+    data = ["//rust/toolchain:current_rustfmt_toolchain_for_target"],
     edition = "2018",
     rustc_env = {
-        "RUSTFMT": "$(rlocationpath //rust/toolchain:current_rustfmt_toolchain)",
+        "RUSTFMT": "$(rlocationpath //rust/toolchain:current_rustfmt_toolchain_for_target)",
     },
-    toolchains = [
-        "@rules_rust//rust/toolchain:current_rust_toolchain",
-        "@rules_rust//rust/toolchain:current_rustfmt_toolchain",
-    ],
+    toolchains = ["@rules_rust//rust/toolchain:current_rust_toolchain"],
     visibility = ["//visibility:public"],
     deps = [
         "//tools/runfiles",