Squashed 'third_party/rules_rust/' changes from bf59038cac..078c6908fc

078c6908fc add cc_common.link support for rust_library and rust_test (#1490)
c07aef0287 Skip supplying rpaths on Fuchsia (#1511)
6ee7c80bdb Propagate rustc_env{,_files} from rust_test.crate (#1443)
1cd0788d2a Apply get_lib_name correctly to the C++ runtime libraries (#1508)
90808f0dc4 Minor cleanup to documentation (#1505)
735640f2df Enable rust-analyzer tests on windows. (#1506)
0f34573166 Updated rules_rust to version 0.9.0 (#1503)
9b61b49934 Promoted crate_universe to non-experimental (#1504)
76360dd354 Implement rules archive release artifact in github action. (#1501)
4e5fac5980 Do not pass `--Clink-arg=-l` for libstd and libtest (#1500)
6c38934636 pipelining: add the ability to disable pipelining for a single rule. (#1499)
867fc37c17 rules_rust: enable pipelined compilation. (#1275)
c97f255dfe Delete deprecated targets (#1496)
43b42884a7 Updated examples to use crate_universe (#1494)
0ffde973e8 Updated `//util/import` to use crate_universe (#1492)
83a03ab03e Updated proto rules to fetch dependencies using crate_universe (#1491)
67e204ff22 fix: `rust_doc_test` failure to find params file (#1418)
0fc834bdfa Updated all toolchain_type definitions to be named `toolchain_type`. (#1479)
3be056a7a3 toolchain files: ensure test depends on std (#1486)
228ebfa6eb Updated rules_rust to version `0.8.1`. (#1484)
685dfda497 Fixed use of rust-analyzer with rust_static_library and rust_shared_library (#1482)
2d7f94543f Fix rust-analyzer being unable to find rust sysroot sources. (#1483)
81a77acde2 Updated rules_rust to version `0.8.0`. (#1472)
caad908848 Give useful error on missing workspace manifest (#1475)
0e86b9dd30 Added `rust_analyzer_toolchain` and repository rules for creating one (#1455)
838e4ea828 Update docs on lockfiles (#1477)
fce1222628 Fix typo in function name (#1478)
1929bfbc3e Added Rust version 1.62.1 (#1476)
9a8e878d3d Fix `rust_binary_without_process_wrapper` build with `--stamp` (#1473)
25baabc205 Updated bindgen version (#1470)
8c9d5c7051 Updated rust-analyzer generator to use clap (#1471)
6d8009dbc8 Update `//bindgen` to use `crate_universe` (#1440)
67c97d44ff Updated `tools/rust_analyzer` to use `crate_universe`. (#1448)
6c285eb28e Updated `wasm_bindgen` rules dependencies. (#1464)
82a437cc17 Fixed crate_universe lockfile checks for crates_repository rule (#1468)
e83d5f3c77 Limit coverage to requested files (#1467)
daff327ea7 Stamp only binaries by default (#1452)
adc80a301d Cleanup crate_universe dependency macros (#1460)
824b121acc Updated header of crate_universe generated files to include a regen command (#1461)
d44e1d8363 feat: add `rustc_flags` attr to `rust_doc` rule (#1458)
6b54feb0ff add a way to distinguish proc-macro deps (#1420)
6070b3c9f4 Fixed missing items in distro artifact (#1450)
1e83e74159 do not add proc-macro deps to transitive_link_search_paths (#1424)
ced94dec1b Fix @libgit2 (#1457)
03d1d5e4ac Add extra_rustc_flag and extra_exec_rustc_flag (#1413)
711adc7985 crate_universe: shorten `crate_universe_crate_index` to `cui` (#1454)
8cb9247f18 Replaced small genrules with uses of bazel_skylib (#1451)
38e841aece Upgrade stardoc (#1444)
674762f66a Updated toolchain repository rules to represent one toolchain per repo (#1442)
b22a6e1416 Re-enable disabled windows jobs in CI (#1353)
2fb94c48fd docs: Update homepage to use latest version (#1441)
389c58fcb1 Updated rules_rust to version `0.7.0`. (#1436)
60f26d49d8 exclude `BUILD` and `WORKSPACE` files from generated crate_universe targets (#1437)
26344d4cd7 Have rust_test put its compilation outputs in a subdirectory (#1434)
8b0f644122 Updated crate_universe version to `0.4.0`. (#1435)
adf92b1534 update crate_universe `--repin` args to not require values. (#1433)
da75146d0a Do not attempt to instrument rust code for coverage if rust_toolchain.llvm-cov is None (#1432)
bde2c36821 Added Rust 1.62.0 (#1427)
7056f22bd0 Fixed crate_universe not finding target library names for "rlib"s (#1429)
3d65214d23 crate_universe support for individually updating packages. (#1426)
5a9d999db9 Updated `attr.label` attribute defaults to use `Label` constructor (#1422)
52fc70145a Added `TemplateVariableInfo` to `rust_toolchain`. (#1416)
7465c1aa29 Add test coverage support (#1324)
c5c3603da6 Bump the min supported bazel version (#1414)
937bdc9d05 Add a `cargo_dep_env` rule for setting build.rs environment variables (#1415)
91466fc0d1 Updated `rules_rust` version to `0.6.0`. (#1397)
97264b79d5 Update wasm_bindgen to use crate universe. (#1398)
d3197a65c5 Updated crate_universe version (to `0.3.0`) and dependencies (#1409)
a15e67d666 Deleted "extra workspace member" functionality from crate_universe (#1406)
5910a7585a Use a vec, not set for rustc_flags for crate_universe annotations (#1404)
3aa88ab067 Deleted deprecated `rust_analyzer` rule. (#1405)
7adf7210d0 cargo: Fix handling of relative sysroots (#1371)
57607239ec Enable rustfmt CI for Windows. (#1403)
30e68b49be Added more "ignore" tags to rustfmt and clippy rules. (#1400)
53ad14eead Added support for vendoring external manifests (#1381)
ff243c6ef0 Reorganized rustfmt source tree (#1399)
94e0044afe Refactored the Rustfmt tool to work cross-platform (#1375)
8fca438124 Ran clang-format on all C++ sources (#1396)
e765719e29 Added TemplateVariableInfo to rust_toolchain (#1377)
81590f4b6a Fixed Clippy bug with `--@rules_rust//:clippy_flags`. (#1392)
d77b9f7c6a Use  `target_compatible_with` to make `macos` with `Xcode` happy (#1391)
ec27dbe310 Added comments to internal function (#1378)
a9dd2f9200 Removed deprecated file (#1380)
16175c881c Renamed toolchain files targets (#1376)
c7cb5bd7a8 Support crates that have mix of generated and nongenerated inputs (#1340)
521e649ff4 Avoid using common substrings as encodings. (#1370)
28ac6b133d Use a more compact encoding in the `import` macro. (#1365)
3a099bfa97 Fix incorrect assertion in test_env_launcher test (#1368)
4661093fb1 Use target instead of rule in rust_register_toolchains edition docs (#1366)
652f2802e3 Add `env` attribute to `rust_toolchain`. (#1363)
9520f37f1e Update rules_perl in examples (#1364)
1b451c301e Add armv7-linux-androideabi tier 2 triple (#1362)
0265c293f1 Ensure crate_features to be included correctly in rust_project.json (#1356)
121d65fe6a Updated `rules_rust` version to `0.5.0` (#1360)
aca4ec1a0f crate_universe: fix typo (#1314)
69ca2611c5 Don't leak native dependencies of proc_macro (#1359)
4c7f08b8b9 Fixed missing docs (#1358)
e48bec94de feat: build script toolchains annotations (#1344)
ffb946f4b7 Ensure memchr is linked after libobject (#1349)
edca1d8042 Add developing notes for crate_universe (#1351)
120f911d2f Updated rust_bindgen dependencies API (#1354)
42c4528a5f Added Rust 1.61.0 (#1347)
c05e0c6ab1 Fixed fetch_shas script to correctly include .gz and .xz extensions (#1355)
9770b0dd75 Update apple_support (#1346)
87eb807e67 Added support for Rust 1.61.0 to crate_universe (#1348)
84c1d42128 Temporarily disable windows job in CI. (#1352)
421d30e4ff Remove unnecessary `crate_name` usage in `rust_test_suite`. (#1345)
10185339dd Build `rust_test` targets with `crate` using the same crate name as the underlying library target. (#1332)
0049ce3884 Add support for riscv32 targets (#1323)
3aa6de3c63 remove experimental_use_whole_archive_for_native_deps (#1338)
a066bfed46 Replace slashes with underscores in default crate names. (#1336)
1b91e592d5 Revert "Replace slashes with underscores in default crate names. (#1334)" (#1335)
51f8e302e9 "sandwich" rlibs between native deps in linker order (#1333)
df354904a1 Replace slashes with underscores in default crate names. (#1334)
21eed19188 Bump version to 0.4.0 (#1329)
d3d9abac4d Support . workspace member (#1326)
fccaae3055 Error calling `all_crate_deps` without `Cargo.toml` (#1327)
d7c532cb78 Updated wasm_bindgen dependencies API (#1313)
fb4d5546ea Updated wasm_bindgen rules to only require core `rules_nodejs` rules (#1311)
1590670ae1 Prevents running of clippy on bindgen targets (#1320)
73d0164a34 Add support for aarch64-apple-ios-sim (#1304)
61eee54c73 Add bazel-* directories in cargo_manifest_dir/external_crate to gitignore (#1279)
42f78f25e1 crate_universe: Improved documentation (#1305)
bddc4bd94a Silence warnings for example/test dependencies (#1312)
b04fe3b21f Use tinyjson from crates.io instead of github.com. (#1309)
1cab691d14 Remove doc about STATIC_RUST_URL env var. (#1306)
d86e06a884 Don't propagate non-shared transitive linker inputs from `rust_static|shared_library` (#1299)
5abeb93333 Don't emit `CrateInfo` from `rust_static_library` and `rust_shared_library` (#1298)
0175a1b7aa fix for using a nightly channel after https://github.com/bazelbuild/rules_rust/commit/841fc6fb82141576d91aecb1d3f2656d58b0ab71 (#1302)
e07881fa22 Updated crate_universe docs (#1301)
c63ad973f1 rustc: fix a conditional (#1300)
a6f332fcbe Use __EXEC_ROOT__ paths for genfiles in rust_analyzer aspect (#1293)
97de47df51 Remove 'triple' field from triple struct in favor of 'str' (#1297)
58627f59eb Make get_host_triple public to get a triple from Bazel's repository_ctx (#1289)
612f4362bc Updated `rules_rust` version to `0.3.1` (#1296)
26fa5a15de Fixed build issues in release artifact (#1295)
48bb32f817 crate_universe: Added tests for serialized config files. (#1291)
841fc6fb82 Enable xz archives (#1284)
f7cb22efa6 feat(#514): pass extra flags to clippy (#1264)
e9f8b48711 Updated `rules_rust` version to `0.3.0` (#1288)
c900e1c66c Revert "Add workaround for arm vs armv7 android issue (#1259)" (#1290)
01ebef2fb9 Remove DEFAULT_RUST_EDITION (#1256)
03a70796ab Outside of examples, fill in all `edition` attrs (#1257)
207ee4fbcf feat: support extra deps in rust_doc_test (#1286)
4e7d114a8e Fix typo in render config doc (#1281)
db17f291d3 Fix crate annotation anchor (#1282)
fdb6851a92 Fix target name in `rust_test` example. (#1280)
4fb6e40147 Don't leak additive build file content across crates (#1278)
965044ae2b Remove `rust_test` example which doesn't build. (#1267)
f6e7e0a93f add a stopgap experimental_use_whole_archive_for_native_deps attribute (#1269)
34fd46756a process_wrapper: add support for terminating rustc after it emits rmeta. (#1207)
b778fca0ac crate_universe: propagate build_script_tools (#1266)
f6f27a8734 Add workaround for arm vs armv7 android issue (#1259)
c3f56c2d50 Add the BUILD.bazel file to the wasm_bindgen distro filegroup target (#1246) (#1261)
1f2e6231de Set edition for process_wrapper and cargo_build_script_runner (#1254)
55790492ac Updated Rust to 1.60.0 (#1247)
b594f90f17 Workaround for issue in linux Cargo binaries (#1252)
8f0dd9042e rust_test_suite: ensure crate names are valid (#1248)
4144ddeb9c Updating `rules_rust` version to `0.2.1` (#1243)
65cad76a52 Fixed proto package in release artifact (#1241)
4d8de6e361 Updated repository pin in the docs (#1240)
e5a3970754 Updating `rules_rust` version to `0.2.0` (#1235)
d061bf640e Updated `crate_universe` version to `0.2.0` (#1239)
c0505da0d2 Replace `rust_repositories` with `rust_register_toolchains` in docs (#1237)
145ad7609f Fixed `crates_repository` deleting `.cargo/config.toml` files. (#1227)
20066b05e2 fix: distribute `//tools/rust_analyzer` (#1234)
b58ce89603 Enabled `rust_doc_test` for `crate_universe` (#1232)
d2e2470cbf Fix some unit tests to run from another workspace (#1226)
b03aee039a Fixed `crate_universe` clippy defects (#1228)
41b39f0c99 add bots using lld (and examples with clang as a drive by) (#1221)
84e98e4d2f don't emit --codegen={metadata,extra-filename} for rust_static_library and rust_shared_library (#1222)
e48c834a40 Renamed `crate_index` repository to `crate_universe_crate_index` (#1217)
99b4b2574f fix use of stamping in rust_binary_without_process_wrapper (#1218)
8df4517d37 Add NUM_JOBS env var to cargo build scripts (#1216)
628e85e70f Restrucutred `crate_universe` dependency macros (#1208)
e3d67a0a10 Updated docs to guide users to using releases (#1213)
fd912e644c Updated crate_universe docs. (#1212)
cde4c0826c Delete deprecated `rules` targets (#1210)
26e01c8386 cache the release archive in release actions (#1201)
3205c9d846 Updated crate_universe setup guide (#1202)
c078494678 Don't leak deps from rust_proc_macro (#1206)
7c865ffeb1 Build `_import_macro_dep` in `exec` mode (#1203)
635da93206 Updating `rules_rust` version to `0.1.0`. (#1198)
6c797c9070 disable advanced features of C++ rules (#1200)
86d47a1bba Tweak import macro bootstrap to trick rust analyzer aspect (#1179)
80d197205a Added release workflow (#1195)
cd44b3670a Added support for producing distribution archives (#1194)
a665447989 Traverse custom alias-like rules in the rust analyzer aspect (#1190)
4504983fa9 Add a test showing that rust_analayzer aspect traverses aliases (#1188)
297dd18215 Updated `crate_universe` to version `0.1.0`. (#1197)
0d9c7d5e1b Specify root target for rust_analyzer test (#1189)
4a0352fecd Updated `crate_universe` dependencies (#1196)
5126479254 Fixed crate_universe release tools (#1193)
e840400eb6 Remove last remains of use_process_wrapper flag. (#1192)
eb7db68d96 Fix iOS linker arguments (#1186)
de726a10c9 Create internal rust_binary rule instead of using transitions (#1187)
5e6ad9f638 Regenerated `cargo-raze` outputs with v0.15.0 (#1184)
980b662843 add static_library to get_preferred_artifact with pic (#1183)
97fd329540 Populate CFLAGS and CXXFLAGS when invoking build script. (#1081)

git-subtree-dir: third_party/rules_rust
git-subtree-split: 078c6908fc32c168b58e72cc3884dd8e30419e3a
Signed-off-by: Brian Silverman <bsilver16384@gmail.com>
Change-Id: Ifc218edaa852263bd76835ee7de44de07c08aec2
diff --git a/rust/private/repository_utils.bzl b/rust/private/repository_utils.bzl
index b6c83aa..86d3f78 100644
--- a/rust/private/repository_utils.bzl
+++ b/rust/private/repository_utils.bzl
@@ -7,7 +7,6 @@
     "system_to_dylib_ext",
     "system_to_staticlib_ext",
     "system_to_stdlib_linkflags",
-    "triple_to_constraint_set",
     "triple_to_system",
 )
 
@@ -15,8 +14,6 @@
 DEFAULT_STATIC_RUST_URL_TEMPLATES = ["https://static.rust-lang.org/dist/{}.tar.gz"]
 
 _build_file_for_compiler_template = """\
-load("@rules_rust//rust:toolchain.bzl", "rust_toolchain")
-
 filegroup(
     name = "rustc",
     srcs = ["bin/rustc{binary_ext}"],
@@ -46,7 +43,7 @@
 """
 
 def BUILD_for_compiler(target_triple):
-    """Emits a BUILD file the compiler `.tar.gz`.
+    """Emits a BUILD file the compiler archive.
 
     Args:
         target_triple (str): The triple of the target platform
@@ -63,8 +60,6 @@
     )
 
 _build_file_for_cargo_template = """\
-load("@rules_rust//rust:toolchain.bzl", "rust_toolchain")
-
 filegroup(
     name = "cargo",
     srcs = ["bin/cargo{binary_ext}"],
@@ -72,7 +67,7 @@
 )"""
 
 def BUILD_for_cargo(target_triple):
-    """Emits a BUILD file the cargo `.tar.gz`.
+    """Emits a BUILD file the cargo archive.
 
     Args:
         target_triple (str): The triple of the target platform
@@ -86,8 +81,6 @@
     )
 
 _build_file_for_rustfmt_template = """\
-load("@rules_rust//rust:toolchain.bzl", "rust_toolchain")
-
 filegroup(
     name = "rustfmt_bin",
     srcs = ["bin/rustfmt{binary_ext}"],
@@ -102,7 +95,7 @@
 """
 
 def BUILD_for_rustfmt(target_triple):
-    """Emits a BUILD file the rustfmt `.tar.gz`.
+    """Emits a BUILD file the rustfmt archive.
 
     Args:
         target_triple (str): The triple of the target platform
@@ -116,8 +109,6 @@
     )
 
 _build_file_for_clippy_template = """\
-load("@rules_rust//rust:toolchain.bzl", "rust_toolchain")
-
 filegroup(
     name = "clippy_driver_bin",
     srcs = ["bin/clippy-driver{binary_ext}"],
@@ -126,7 +117,7 @@
 """
 
 def BUILD_for_clippy(target_triple):
-    """Emits a BUILD file the clippy `.tar.gz`.
+    """Emits a BUILD file the clippy archive.
 
     Args:
         target_triple (str): The triple of the target platform
@@ -137,6 +128,35 @@
     system = triple_to_system(target_triple)
     return _build_file_for_clippy_template.format(binary_ext = system_to_binary_ext(system))
 
+_build_file_for_llvm_tools = """\
+filegroup(
+    name = "llvm_cov_bin",
+    srcs = ["lib/rustlib/{target_triple}/bin/llvm-cov{binary_ext}"],
+    visibility = ["//visibility:public"],
+)
+
+filegroup(
+    name = "llvm_profdata_bin",
+    srcs = ["lib/rustlib/{target_triple}/bin/llvm-profdata{binary_ext}"],
+    visibility = ["//visibility:public"],
+)
+"""
+
+def BUILD_for_llvm_tools(target_triple):
+    """Emits a BUILD file the llvm-tools binaries.
+
+    Args:
+        target_triple (str): The triple of the target platform
+
+    Returns:
+        str: The contents of a BUILD file
+    """
+    system = triple_to_system(target_triple)
+    return _build_file_for_llvm_tools.format(
+        binary_ext = system_to_binary_ext(system),
+        target_triple = target_triple,
+    )
+
 _build_file_for_stdlib_template = """\
 load("@rules_rust//rust:toolchain.bzl", "rust_stdlib_filegroup")
 
@@ -164,7 +184,7 @@
 """
 
 def BUILD_for_stdlib(target_triple):
-    """Emits a BUILD file the stdlib `.tar.gz`.
+    """Emits a BUILD file the stdlib archive.
 
     Args:
         target_triple (str): The triple of the target platform
@@ -181,16 +201,21 @@
     )
 
 _build_file_for_rust_toolchain_template = """\
+load("@rules_rust//rust:toolchain.bzl", "rust_toolchain")
+
 rust_toolchain(
-    name = "{toolchain_name}_impl",
+    name = "{toolchain_name}",
     rust_doc = "@{workspace_name}//:rustdoc",
     rust_std = "@{workspace_name}//:rust_std-{target_triple}",
     rustc = "@{workspace_name}//:rustc",
     rustfmt = {rustfmt_label},
     cargo = "@{workspace_name}//:cargo",
     clippy_driver = "@{workspace_name}//:clippy_driver_bin",
+    llvm_cov = {llvm_cov_label},
+    llvm_profdata = {llvm_profdata_label},
     rustc_lib = "@{workspace_name}//:rustc_lib",
     rustc_srcs = {rustc_srcs},
+    allocator_library = {allocator_library},
     binary_ext = "{binary_ext}",
     staticlib_ext = "{staticlib_ext}",
     dylib_ext = "{dylib_ext}",
@@ -209,8 +234,10 @@
         exec_triple,
         target_triple,
         include_rustc_srcs,
+        allocator_library,
         default_edition,
         include_rustfmt,
+        include_llvm_tools,
         stdlib_linkflags = None):
     """Emits a toolchain declaration to match an existing compiler and stdlib.
 
@@ -220,8 +247,10 @@
         exec_triple (str): The rust-style target that this compiler runs on
         target_triple (str): The rust-style target triple of the tool
         include_rustc_srcs (bool, optional): Whether to download rustc's src code. This is required in order to use rust-analyzer support. Defaults to False.
+        allocator_library (str, optional): Target that provides allocator functions when rust_library targets are embedded in a cc_binary.
         default_edition (str): Default Rust edition.
         include_rustfmt (bool): Whether rustfmt is present in the toolchain.
+        include_llvm_tools (bool): Whether llvm-tools are present in the toolchain.
         stdlib_linkflags (list, optional): Overriden flags needed for linking to rust
                                            stdlib, akin to BAZEL_LINKLIBS. Defaults to
                                            None.
@@ -240,6 +269,14 @@
     rustfmt_label = "None"
     if include_rustfmt:
         rustfmt_label = "\"@{workspace_name}//:rustfmt_bin\"".format(workspace_name = workspace_name)
+    llvm_cov_label = "None"
+    llvm_profdata_label = "None"
+    if include_llvm_tools:
+        llvm_cov_label = "\"@{workspace_name}//:llvm_cov_bin\"".format(workspace_name = workspace_name)
+        llvm_profdata_label = "\"@{workspace_name}//:llvm_profdata_bin\"".format(workspace_name = workspace_name)
+    allocator_library_label = "None"
+    if allocator_library:
+        allocator_library_label = "\"{allocator_library}\"".format(allocator_library = allocator_library)
 
     return _build_file_for_rust_toolchain_template.format(
         toolchain_name = name,
@@ -248,12 +285,15 @@
         staticlib_ext = system_to_staticlib_ext(system),
         dylib_ext = system_to_dylib_ext(system),
         rustc_srcs = rustc_srcs,
+        allocator_library = allocator_library_label,
         stdlib_linkflags = stdlib_linkflags,
         system = system,
         default_edition = default_edition,
         exec_triple = exec_triple,
         target_triple = target_triple,
         rustfmt_label = rustfmt_label,
+        llvm_cov_label = llvm_cov_label,
+        llvm_profdata_label = llvm_profdata_label,
     )
 
 _build_file_for_toolchain_template = """\
@@ -261,17 +301,23 @@
     name = "{name}",
     exec_compatible_with = {exec_constraint_sets_serialized},
     target_compatible_with = {target_constraint_sets_serialized},
-    toolchain = "@{parent_workspace_name}//:{name}_impl",
-    toolchain_type = "@rules_rust//rust:toolchain",
+    toolchain = "{toolchain}",
+    toolchain_type = "{toolchain_type}",
 )
 """
 
-def BUILD_for_toolchain(name, parent_workspace_name, exec_triple, target_triple):
+def BUILD_for_toolchain(
+        name,
+        toolchain,
+        toolchain_type,
+        target_compatible_with,
+        exec_compatible_with):
     return _build_file_for_toolchain_template.format(
         name = name,
-        exec_constraint_sets_serialized = serialized_constraint_set_from_triple(exec_triple),
-        target_constraint_sets_serialized = serialized_constraint_set_from_triple(target_triple),
-        parent_workspace_name = parent_workspace_name,
+        exec_constraint_sets_serialized = exec_compatible_with,
+        target_constraint_sets_serialized = target_compatible_with,
+        toolchain = toolchain,
+        toolchain_type = toolchain_type,
     )
 
 def load_rustfmt(ctx):
@@ -311,14 +357,56 @@
         ctx,
         iso_date = ctx.attr.iso_date,
         target_triple = target_triple,
-        tool_name = "rust",
-        tool_subdirectories = ["rustc", "clippy-preview", "cargo"],
+        tool_name = "rustc",
+        tool_subdirectories = ["rustc"],
         version = ctx.attr.version,
     )
 
-    compiler_build_file = BUILD_for_compiler(target_triple) + BUILD_for_clippy(target_triple) + BUILD_for_cargo(target_triple)
+    return BUILD_for_compiler(target_triple)
 
-    return compiler_build_file
+def load_clippy(ctx):
+    """Loads Clippy and yields corresponding BUILD for it
+
+    Args:
+        ctx (repository_ctx): A repository_ctx.
+
+    Returns:
+        str: The BUILD file contents for Clippy
+    """
+
+    target_triple = ctx.attr.exec_triple
+    load_arbitrary_tool(
+        ctx,
+        iso_date = ctx.attr.iso_date,
+        target_triple = target_triple,
+        tool_name = "clippy",
+        tool_subdirectories = ["clippy-preview"],
+        version = ctx.attr.version,
+    )
+
+    return BUILD_for_clippy(target_triple)
+
+def load_cargo(ctx):
+    """Loads Cargo and yields corresponding BUILD for it
+
+    Args:
+        ctx (repository_ctx): A repository_ctx.
+
+    Returns:
+        str: The BUILD file contents for Cargo
+    """
+
+    target_triple = ctx.attr.exec_triple
+    load_arbitrary_tool(
+        ctx,
+        iso_date = ctx.attr.iso_date,
+        target_triple = target_triple,
+        tool_name = "cargo",
+        tool_subdirectories = ["cargo"],
+        version = ctx.attr.version,
+    )
+
+    return BUILD_for_cargo(target_triple)
 
 def should_include_rustc_srcs(repository_ctx):
     """Determing whether or not to include rustc sources in the toolchain.
@@ -337,27 +425,24 @@
 
     return getattr(repository_ctx.attr, "include_rustc_srcs", False)
 
-def load_rust_src(ctx):
+def load_rust_src(ctx, sha256 = ""):
     """Loads the rust source code. Used by the rust-analyzer rust-project.json generator.
 
     Args:
         ctx (ctx): A repository_ctx.
+        sha256 (str): The sha256 value for the `rust-src` artifact
     """
     tool_suburl = produce_tool_suburl("rust-src", None, ctx.attr.version, ctx.attr.iso_date)
-    static_rust = ctx.os.environ.get("STATIC_RUST_URL", "https://static.rust-lang.org")
-    url = "{}/dist/{}.tar.gz".format(static_rust, tool_suburl)
+    url = ctx.attr.urls[0].format(tool_suburl)
 
     tool_path = produce_tool_path("rust-src", None, ctx.attr.version)
-    archive_path = tool_path + ".tar.gz"
-    ctx.download(
+    archive_path = tool_path + _get_tool_extension(ctx)
+    sha256 = sha256 or getattr(ctx.attr, "sha256s", {}).get(archive_path) or FILE_KEY_TO_SHA.get(archive_path) or ""
+    ctx.download_and_extract(
         url,
-        output = archive_path,
-        sha256 = ctx.attr.sha256s.get(tool_suburl) or FILE_KEY_TO_SHA.get(tool_suburl) or "",
-        auth = _make_auth_dict(ctx, [url]),
-    )
-    ctx.extract(
-        archive_path,
         output = "lib/rustlib/src",
+        sha256 = sha256,
+        auth = _make_auth_dict(ctx, [url]),
         stripPrefix = "{}/rust-src/lib/rustlib/src/rust".format(tool_path),
     )
     ctx.file(
@@ -370,6 +455,21 @@
 )""",
     )
 
+_build_file_for_rust_analyzer_toolchain_template = """\
+load("@rules_rust//rust:toolchain.bzl", "rust_analyzer_toolchain")
+
+rust_analyzer_toolchain(
+    name = "{name}",
+    rustc_srcs = "//lib/rustlib/src:rustc_srcs",
+    visibility = ["//visibility:public"],
+)
+"""
+
+def BUILD_for_rust_analyzer_toolchain(name):
+    return _build_file_for_rust_analyzer_toolchain_template.format(
+        name = name,
+    )
+
 def load_rust_stdlib(ctx, target_triple):
     """Loads a rust standard library and yields corresponding BUILD for it
 
@@ -378,7 +478,7 @@
         target_triple (str): The rust-style target triple of the tool
 
     Returns:
-        str: The BUILD file contents for this stdlib, and a toolchain decl to match
+        str: The BUILD file contents for this stdlib
     """
 
     load_arbitrary_tool(
@@ -390,28 +490,7 @@
         version = ctx.attr.version,
     )
 
-    toolchain_prefix = ctx.attr.toolchain_name_prefix or DEFAULT_TOOLCHAIN_NAME_PREFIX
-    stdlib_build_file = BUILD_for_stdlib(target_triple)
-
-    stdlib_linkflags = None
-    if "BAZEL_RUST_STDLIB_LINKFLAGS" in ctx.os.environ:
-        stdlib_linkflags = ctx.os.environ["BAZEL_RUST_STDLIB_LINKFLAGS"].split(":")
-
-    toolchain_build_file = BUILD_for_rust_toolchain(
-        name = "{toolchain_prefix}_{target_triple}".format(
-            toolchain_prefix = toolchain_prefix,
-            target_triple = target_triple,
-        ),
-        exec_triple = ctx.attr.exec_triple,
-        include_rustc_srcs = should_include_rustc_srcs(ctx),
-        target_triple = target_triple,
-        stdlib_linkflags = stdlib_linkflags,
-        workspace_name = ctx.attr.name,
-        default_edition = ctx.attr.edition,
-        include_rustfmt = not (not ctx.attr.rustfmt_version),
-    )
-
-    return stdlib_build_file + toolchain_build_file
+    return BUILD_for_stdlib(target_triple)
 
 def load_rustc_dev_nightly(ctx, target_triple):
     """Loads the nightly rustc dev component
@@ -450,6 +529,8 @@
         version = ctx.attr.version,
     )
 
+    return BUILD_for_llvm_tools(target_triple)
+
 def check_version_valid(version, iso_date, param_prefix = ""):
     """Verifies that the provided rust version and iso_date make sense.
 
@@ -465,21 +546,6 @@
     if version in ("beta", "nightly") and not iso_date:
         fail("{param_prefix}iso_date must be specified if version is 'beta' or 'nightly'".format(param_prefix = param_prefix))
 
-def serialized_constraint_set_from_triple(target_triple):
-    """Returns a string representing a set of constraints
-
-    Args:
-        target_triple (str): The target triple of the constraint set
-
-    Returns:
-        str: Formatted string representing the serialized constraint
-    """
-    constraint_set = triple_to_constraint_set(target_triple)
-    constraint_set_strs = []
-    for constraint in constraint_set:
-        constraint_set_strs.append("\"{}\"".format(constraint))
-    return "[{}]".format(", ".join(constraint_set_strs))
-
 def produce_tool_suburl(tool_name, target_triple, version, iso_date = None):
     """Produces a fully qualified Rust tool name for URL
 
@@ -520,10 +586,6 @@
     - https://static.rust-lang.org/dist/channel-rust-beta.toml
     - https://static.rust-lang.org/dist/channel-rust-nightly.toml
 
-    The environment variable `STATIC_RUST_URL` can be used to replace the schema and hostname of
-    the URLs used for fetching assets. `https://static.rust-lang.org/dist/channel-rust-stable.toml`
-    becomes `${STATIC_RUST_URL}/dist/channel-rust-stable.toml`
-
     Args:
         ctx (repository_ctx): A repository_ctx (no attrs required).
         tool_name (str): The name of the given tool per the archive naming.
@@ -551,32 +613,30 @@
     tool_suburl = produce_tool_suburl(tool_name, target_triple, version, iso_date)
     urls = []
 
-    static_rust_url_from_env = ctx.os.environ.get("STATIC_RUST_URL")
-    if static_rust_url_from_env:
-        urls.append("{}/dist/{}.tar.gz".format(static_rust_url_from_env, tool_suburl))
-
     for url in getattr(ctx.attr, "urls", DEFAULT_STATIC_RUST_URL_TEMPLATES):
         new_url = url.format(tool_suburl)
         if new_url not in urls:
             urls.append(new_url)
 
     tool_path = produce_tool_path(tool_name, target_triple, version)
-    archive_path = "{}.tar.gz".format(tool_path)
-    ctx.download(
-        urls,
-        output = archive_path,
-        sha256 = getattr(ctx.attr, "sha256s", dict()).get(tool_suburl) or
-                 FILE_KEY_TO_SHA.get(tool_suburl) or
-                 sha256,
-        auth = _make_auth_dict(ctx, urls),
-    )
+    archive_path = tool_path + _get_tool_extension(ctx)
+    sha256 = getattr(ctx.attr, "sha256s", dict()).get(archive_path) or FILE_KEY_TO_SHA.get(archive_path) or sha256
+
     for subdirectory in tool_subdirectories:
-        ctx.extract(
-            archive_path,
-            output = "",
+        # As long as the sha256 value is consistent accross calls here the
+        # cost of downloading an artifact is negated as by Bazel's caching.
+        result = ctx.download_and_extract(
+            urls,
+            sha256 = sha256,
+            auth = _make_auth_dict(ctx, urls),
             stripPrefix = "{}/{}".format(tool_path, subdirectory),
         )
 
+        # In the event no sha256 was provided, set it to the value of the first
+        # downloaded item so subsequent downloads use a cached artifact.
+        if not sha256:
+            sha256 = result.sha256
+
 def _make_auth_dict(ctx, urls):
     auth = getattr(ctx.attr, "auth", {})
     if not auth:
@@ -585,3 +645,12 @@
     for url in urls:
         ret[url] = auth
     return ret
+
+def _get_tool_extension(ctx):
+    urls = getattr(ctx.attr, "urls", DEFAULT_STATIC_RUST_URL_TEMPLATES)
+    if urls[0][-7:] == ".tar.gz":
+        return ".tar.gz"
+    elif urls[0][-7:] == ".tar.xz":
+        return ".tar.xz"
+    else:
+        return ""