# What: use a working Windows direct linker for `rules_rs` exec toolchains and
# preserve the Windows stdlib link flags the stable wrapper was dropping.
# Scope: Windows-only linker metadata for the generated `rules_rs` toolchains.

diff --git a/rs/experimental/toolchains/declare_rustc_toolchains.bzl b/rs/experimental/toolchains/declare_rustc_toolchains.bzl
--- a/rs/experimental/toolchains/declare_rustc_toolchains.bzl
+++ b/rs/experimental/toolchains/declare_rustc_toolchains.bzl
@@ -58,6 +58,8 @@ def declare_rustc_toolchains(
         rust_toolchain(
             name = rust_toolchain_name,
             rust_doc = "{}rustdoc".format(rustc_repo_label),
+            linker = "{}rust-lld".format(rustc_repo_label) if exec_triple.system == "windows" else None,
+            linker_type = "direct" if exec_triple.system == "windows" else None,
             rust_std = select(rust_std_select),
             rustc = "{}rustc".format(rustc_repo_label),
             cargo = "{}cargo".format(cargo_repo_label),
@@ -104,7 +106,20 @@ def declare_rustc_toolchains(
                 "@platforms//os:nixos": ["-ldl", "-lpthread"],
                 "@platforms//os:openbsd": ["-lpthread"],
                 "@platforms//os:ios": ["-lSystem", "-lobjc", "-Wl,-framework,Security", "-Wl,-framework,Foundation", "-lresolv"],
-                # TODO: windows
+                "@rules_rs//rs/experimental/platforms/constraints:windows_gnullvm": [
+                    "advapi32.lib",
+                    "ws2_32.lib",
+                    "userenv.lib",
+                    "Bcrypt.lib",
+                ],
+                "@rules_rs//rs/experimental/platforms/constraints:windows_msvc": [
+                    "advapi32.lib",
+                    "ws2_32.lib",
+                    "userenv.lib",
+                    "Bcrypt.lib",
+                    "ucrt.lib",
+                ],
+                # TODO: other platforms
                 "//conditions:default": [],
             }),
             default_edition = edition,
diff --git a/rs/private/rustc_repository.bzl b/rs/private/rustc_repository.bzl
--- a/rs/private/rustc_repository.bzl
+++ b/rs/private/rustc_repository.bzl
@@ -7,10 +7,24 @@ load(
 )
 load(":rust_repository_utils.bzl", "RUST_REPOSITORY_COMMON_ATTR", "download_and_extract")
+
+_WINDOWS_EXEC_LINKER_BUILD = """
+filegroup(
+    name = "rust-lld",
+    srcs = ["bin/lld-link.exe"],
+    visibility = ["//visibility:public"],
+)
+"""
 
 def _rustc_repository_impl(rctx):
     exec_triple = triple(rctx.attr.triple)
     download_and_extract(rctx, "rustc", "rustc", exec_triple)
     build_content = [BUILD_for_compiler(exec_triple)]
+    if exec_triple.system == "windows":
+        lld_link = rctx.which("lld-link.exe")
+        if lld_link == None:
+            fail("lld-link.exe not found on PATH")
+        rctx.symlink(lld_link, "bin/lld-link.exe")
+        build_content.append(_WINDOWS_EXEC_LINKER_BUILD)
     if includes_rust_analyzer_proc_macro_srv(rctx.attr.version, rctx.attr.iso_date):
         build_content.append(BUILD_for_rust_analyzer_proc_macro_srv(exec_triple))
     rctx.file("BUILD.bazel", "\n".join(build_content))
