Added `rust_analyzer_toolchain` and repository rules for creating one (#1455)

* Added `rust_analyzer_toolchain` and repository rules for creating one

* Regenerate documentation

* Update rust/repositories.bzl

Co-authored-by: Daniel Wagner-Hall <dawagner@gmail.com>

* Updated rust_analyzer_toolchain export

* Fixed rust_analyzer_toolchain_repository rule

Co-authored-by: Daniel Wagner-Hall <dawagner@gmail.com>
diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel
index 7afa1dc..2bc17ba 100644
--- a/WORKSPACE.bazel
+++ b/WORKSPACE.bazel
@@ -4,7 +4,7 @@
 
 rules_rust_dependencies()
 
-rust_register_toolchains(include_rustc_srcs = True)
+rust_register_toolchains()
 
 load("@rules_rust//crate_universe:repositories.bzl", "crate_universe_dependencies")
 
diff --git a/docs/BUILD.bazel b/docs/BUILD.bazel
index 9427b06..ebca2dc 100644
--- a/docs/BUILD.bazel
+++ b/docs/BUILD.bazel
@@ -72,6 +72,7 @@
         header_template = ":rust_analyzer.vm",
         symbols = [
             "rust_analyzer_aspect",
+            "rust_analyzer_toolchain",
         ],
     ),
     page(
diff --git a/docs/flatten.md b/docs/flatten.md
index 3bd90e9..e4eef54 100644
--- a/docs/flatten.md
+++ b/docs/flatten.md
@@ -14,6 +14,7 @@
 * [incompatible_flag](#incompatible_flag)
 * [rules_rust_dependencies](#rules_rust_dependencies)
 * [rust_analyzer_aspect](#rust_analyzer_aspect)
+* [rust_analyzer_toolchain](#rust_analyzer_toolchain)
 * [rust_binary](#rust_binary)
 * [rust_bindgen](#rust_bindgen)
 * [rust_bindgen_dependencies](#rust_bindgen_dependencies)
@@ -177,6 +178,25 @@
 | <a id="incompatible_flag-issue"></a>issue |  The link to the github issue associated with this flag   | String | required |  |
 
 
+<a id="rust_analyzer_toolchain"></a>
+
+## rust_analyzer_toolchain
+
+<pre>
+rust_analyzer_toolchain(<a href="#rust_analyzer_toolchain-name">name</a>, <a href="#rust_analyzer_toolchain-rustc_srcs">rustc_srcs</a>)
+</pre>
+
+A toolchain for [rust-analyzer](https://rust-analyzer.github.io/).
+
+**ATTRIBUTES**
+
+
+| Name  | Description | Type | Mandatory | Default |
+| :------------- | :------------- | :------------- | :------------- | :------------- |
+| <a id="rust_analyzer_toolchain-name"></a>name |  A unique name for this target.   | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required |  |
+| <a id="rust_analyzer_toolchain-rustc_srcs"></a>rustc_srcs |  The source code of rustc.   | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required |  |
+
+
 <a id="rust_binary"></a>
 
 ## rust_binary
@@ -1168,8 +1188,8 @@
 ## rust_toolchain_repository_proxy
 
 <pre>
-rust_toolchain_repository_proxy(<a href="#rust_toolchain_repository_proxy-name">name</a>, <a href="#rust_toolchain_repository_proxy-exec_compatible_with">exec_compatible_with</a>, <a href="#rust_toolchain_repository_proxy-exec_triple">exec_triple</a>, <a href="#rust_toolchain_repository_proxy-parent_workspace_name">parent_workspace_name</a>,
-                                <a href="#rust_toolchain_repository_proxy-repo_mapping">repo_mapping</a>, <a href="#rust_toolchain_repository_proxy-target_compatible_with">target_compatible_with</a>, <a href="#rust_toolchain_repository_proxy-target_triple">target_triple</a>)
+rust_toolchain_repository_proxy(<a href="#rust_toolchain_repository_proxy-name">name</a>, <a href="#rust_toolchain_repository_proxy-exec_compatible_with">exec_compatible_with</a>, <a href="#rust_toolchain_repository_proxy-repo_mapping">repo_mapping</a>, <a href="#rust_toolchain_repository_proxy-target_compatible_with">target_compatible_with</a>,
+                                <a href="#rust_toolchain_repository_proxy-toolchain">toolchain</a>, <a href="#rust_toolchain_repository_proxy-toolchain_type">toolchain_type</a>)
 </pre>
 
 Generates a toolchain-bearing repository that declares the toolchains from some other rust_toolchain_repository.
@@ -1180,12 +1200,11 @@
 | Name  | Description | Type | Mandatory | Default |
 | :------------- | :------------- | :------------- | :------------- | :------------- |
 | <a id="rust_toolchain_repository_proxy-name"></a>name |  A unique name for this repository.   | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required |  |
-| <a id="rust_toolchain_repository_proxy-exec_compatible_with"></a>exec_compatible_with |  TODO   | List of strings | optional | [] |
-| <a id="rust_toolchain_repository_proxy-exec_triple"></a>exec_triple |  The Rust-style target triple for the compilation platform   | String | required |  |
-| <a id="rust_toolchain_repository_proxy-parent_workspace_name"></a>parent_workspace_name |  The name of the other rust_toolchain_repository   | String | required |  |
+| <a id="rust_toolchain_repository_proxy-exec_compatible_with"></a>exec_compatible_with |  A list of constraints for the execution platform for this toolchain.   | List of strings | optional | [] |
 | <a id="rust_toolchain_repository_proxy-repo_mapping"></a>repo_mapping |  A dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.&lt;p&gt;For example, an entry <code>"@foo": "@bar"</code> declares that, for any time this repository depends on <code>@foo</code> (such as a dependency on <code>@foo//some:target</code>, it should actually resolve that dependency within globally-declared <code>@bar</code> (<code>@bar//some:target</code>).   | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | required |  |
-| <a id="rust_toolchain_repository_proxy-target_compatible_with"></a>target_compatible_with |  TODO   | List of strings | optional | [] |
-| <a id="rust_toolchain_repository_proxy-target_triple"></a>target_triple |  The Rust-style target that this compiler builds for   | String | required |  |
+| <a id="rust_toolchain_repository_proxy-target_compatible_with"></a>target_compatible_with |  A list of constraints for the target platform for this toolchain.   | List of strings | optional | [] |
+| <a id="rust_toolchain_repository_proxy-toolchain"></a>toolchain |  The name of the toolchain implementation target.   | String | required |  |
+| <a id="rust_toolchain_repository_proxy-toolchain_type"></a>toolchain_type |  The toolchain type of the toolchain to declare   | String | required |  |
 
 
 <a id="rust_toolchain_tools_repository"></a>
@@ -1200,7 +1219,7 @@
 
 Composes a single workspace containing the toolchain components for compiling on a given platform to a series of target platforms.
 
-A given instance of this rule should be accompanied by a rust_toolchain_repository_proxy invocation to declare its toolchains to Bazel; the indirection allows separating toolchain selection from toolchain fetching.
+A given instance of this rule should be accompanied by a toolchain_repository_proxy invocation to declare its toolchains to Bazel; the indirection allows separating toolchain selection from toolchain fetching.
 
 **ATTRIBUTES**
 
@@ -1834,9 +1853,9 @@
 | <a id="rust_toolchain_repository-target_triple"></a>target_triple |  The Rust-style target to build for.   |  none |
 | <a id="rust_toolchain_repository-exec_compatible_with"></a>exec_compatible_with |  A list of constraints for the execution platform for this toolchain.   |  <code>None</code> |
 | <a id="rust_toolchain_repository-target_compatible_with"></a>target_compatible_with |  A list of constraints for the target platform for this toolchain.   |  <code>None</code> |
-| <a id="rust_toolchain_repository-include_rustc_srcs"></a>include_rustc_srcs |  Whether to download rustc's src code. This is required in order to use rust-analyzer support. Defaults to False.   |  <code>False</code> |
-| <a id="rust_toolchain_repository-iso_date"></a>iso_date |  The date of the tool. Defaults to None.   |  <code>None</code> |
-| <a id="rust_toolchain_repository-rustfmt_version"></a>rustfmt_version |  The version of rustfmt to be associated with the toolchain. Defaults to None.   |  <code>None</code> |
+| <a id="rust_toolchain_repository-include_rustc_srcs"></a>include_rustc_srcs |  Whether to download rustc's src code. This is required in order to use rust-analyzer support.   |  <code>False</code> |
+| <a id="rust_toolchain_repository-iso_date"></a>iso_date |  The date of the tool.   |  <code>None</code> |
+| <a id="rust_toolchain_repository-rustfmt_version"></a>rustfmt_version |  The version of rustfmt to be associated with the toolchain.   |  <code>None</code> |
 | <a id="rust_toolchain_repository-edition"></a>edition |  The rust edition to be used by default (2015, 2018, or 2021). If absent, every rule is required to specify its <code>edition</code> attribute.   |  <code>None</code> |
 | <a id="rust_toolchain_repository-dev_components"></a>dev_components |  Whether to download the rustc-dev components. Requires version to be "nightly". Defaults to False.   |  <code>False</code> |
 | <a id="rust_toolchain_repository-sha256s"></a>sha256s |  A dict associating tool subdirectories to sha256 hashes. See [rust_repositories](#rust_repositories) for more details.   |  <code>None</code> |
diff --git a/docs/rust_analyzer.md b/docs/rust_analyzer.md
index 82c4fc0..ec10392 100644
--- a/docs/rust_analyzer.md
+++ b/docs/rust_analyzer.md
@@ -2,6 +2,7 @@
 # Rust Analyzer
 
 * [rust_analyzer_aspect](#rust_analyzer_aspect)
+* [rust_analyzer_toolchain](#rust_analyzer_toolchain)
 
 
 ## Overview
@@ -13,7 +14,10 @@
 
 ### Setup
 
-First, add the following to the `WORKSPACE` file:
+First, ensure `rules_rust` is setup in your workspace. By default, `rust_register_toolchains` will
+ensure a [rust_analyzer_toolchain](#rust_analyzer_toolchain) is registered within the WORKSPACE.
+
+Next, load the dependencies for the `rust-project.json` generator tool:
 
 ```python
 load("@rules_rust//tools/rust_analyzer:deps.bzl", "rust_analyzer_dependencies")
@@ -21,22 +25,27 @@
 rust_analyzer_dependencies()
 ```
 
-Next, add the following lines to the `.bazelrc` file of your workspace:
-```
-build --repo_env=RULES_RUST_TOOLCHAIN_INCLUDE_RUSTC_SRCS=true
-```
-
-This will ensure rust source code is available to `rust-analyzer`. Users
-can also set `include_rustc_srcs = True` on any `rust_repository` or
-`rust_repositories` calls in the workspace but the environment variable
-has higher priority and can override the attribute.
-
 Finally, run `bazel run @rules_rust//tools/rust_analyzer:gen_rust_project`
 whenever dependencies change to regenerate the `rust-project.json` file. It
 should be added to `.gitignore` because it is effectively a build artifact.
 Once the `rust-project.json` has been generated in the project root,
 rust-analyzer can pick it up upon restart.
 
+For users who do not use `rust_register_toolchains` to register toolchains, the following can be added
+to their WORKSPACE to register a `rust_analyzer_toolchain`. Please make sure the Rust version used in
+this toolchain matches the version used by the currently registered toolchain or the sources/documentation
+# will not match what's being compiled with and can lead to confusing results.
+
+```python
+load("@rules_rust//rust:repositories.bzl", "rust_analyzer_toolchain_repository")
+
+register_toolchains(rust_analyzer_toolchain_repository(
+    name = "rust_analyzer_toolchain",
+    # This should match the currently registered toolchain.
+    version = "1.62.0",
+))
+```
+
 #### VSCode
 
 To set this up using [VSCode](https://code.visualstudio.com/), users should first install the
@@ -70,6 +79,25 @@
 ```
 
 
+<a id="rust_analyzer_toolchain"></a>
+
+## rust_analyzer_toolchain
+
+<pre>
+rust_analyzer_toolchain(<a href="#rust_analyzer_toolchain-name">name</a>, <a href="#rust_analyzer_toolchain-rustc_srcs">rustc_srcs</a>)
+</pre>
+
+A toolchain for [rust-analyzer](https://rust-analyzer.github.io/).
+
+**ATTRIBUTES**
+
+
+| Name  | Description | Type | Mandatory | Default |
+| :------------- | :------------- | :------------- | :------------- | :------------- |
+| <a id="rust_analyzer_toolchain-name"></a>name |  A unique name for this target.   | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required |  |
+| <a id="rust_analyzer_toolchain-rustc_srcs"></a>rustc_srcs |  The source code of rustc.   | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required |  |
+
+
 <a id="rust_analyzer_aspect"></a>
 
 ## rust_analyzer_aspect
diff --git a/docs/rust_analyzer.vm b/docs/rust_analyzer.vm
index 5ddc041..863995a 100644
--- a/docs/rust_analyzer.vm
+++ b/docs/rust_analyzer.vm
@@ -8,7 +8,10 @@
 
 ### Setup
 
-First, add the following to the `WORKSPACE` file:
+First, ensure `rules_rust` is setup in your workspace. By default, `rust_register_toolchains` will
+ensure a [rust_analyzer_toolchain](#rust_analyzer_toolchain) is registered within the WORKSPACE.
+
+Next, load the dependencies for the `rust-project.json` generator tool:
 
 ```python
 load("@rules_rust//tools/rust_analyzer:deps.bzl", "rust_analyzer_dependencies")
@@ -16,22 +19,27 @@
 rust_analyzer_dependencies()
 ```
 
-Next, add the following lines to the `.bazelrc` file of your workspace:
-```
-build --repo_env=RULES_RUST_TOOLCHAIN_INCLUDE_RUSTC_SRCS=true
-```
-
-This will ensure rust source code is available to `rust-analyzer`. Users
-can also set `include_rustc_srcs = True` on any `rust_repository` or
-`rust_repositories` calls in the workspace but the environment variable
-has higher priority and can override the attribute.
-
 Finally, run `bazel run @rules_rust//tools/rust_analyzer:gen_rust_project`
 whenever dependencies change to regenerate the `rust-project.json` file. It
 should be added to `.gitignore` because it is effectively a build artifact.
 Once the `rust-project.json` has been generated in the project root,
 rust-analyzer can pick it up upon restart.
 
+For users who do not use `rust_register_toolchains` to register toolchains, the following can be added
+to their WORKSPACE to register a `rust_analyzer_toolchain`. Please make sure the Rust version used in
+this toolchain matches the version used by the currently registered toolchain or the sources/documentation
+# will not match what's being compiled with and can lead to confusing results.
+
+```python
+load("@rules_rust//rust:repositories.bzl", "rust_analyzer_toolchain_repository")
+
+register_toolchains(rust_analyzer_toolchain_repository(
+    name = "rust_analyzer_toolchain",
+    # This should match the currently registered toolchain.
+    version = "1.62.0",
+))
+```
+
 #### VSCode
 
 To set this up using [VSCode](https://code.visualstudio.com/), users should first install the
diff --git a/docs/rust_repositories.md b/docs/rust_repositories.md
index 86db4ff..49990ff 100644
--- a/docs/rust_repositories.md
+++ b/docs/rust_repositories.md
@@ -120,8 +120,8 @@
 ## rust_toolchain_repository_proxy
 
 <pre>
-rust_toolchain_repository_proxy(<a href="#rust_toolchain_repository_proxy-name">name</a>, <a href="#rust_toolchain_repository_proxy-exec_compatible_with">exec_compatible_with</a>, <a href="#rust_toolchain_repository_proxy-exec_triple">exec_triple</a>, <a href="#rust_toolchain_repository_proxy-parent_workspace_name">parent_workspace_name</a>,
-                                <a href="#rust_toolchain_repository_proxy-repo_mapping">repo_mapping</a>, <a href="#rust_toolchain_repository_proxy-target_compatible_with">target_compatible_with</a>, <a href="#rust_toolchain_repository_proxy-target_triple">target_triple</a>)
+rust_toolchain_repository_proxy(<a href="#rust_toolchain_repository_proxy-name">name</a>, <a href="#rust_toolchain_repository_proxy-exec_compatible_with">exec_compatible_with</a>, <a href="#rust_toolchain_repository_proxy-repo_mapping">repo_mapping</a>, <a href="#rust_toolchain_repository_proxy-target_compatible_with">target_compatible_with</a>,
+                                <a href="#rust_toolchain_repository_proxy-toolchain">toolchain</a>, <a href="#rust_toolchain_repository_proxy-toolchain_type">toolchain_type</a>)
 </pre>
 
 Generates a toolchain-bearing repository that declares the toolchains from some other rust_toolchain_repository.
@@ -132,12 +132,11 @@
 | Name  | Description | Type | Mandatory | Default |
 | :------------- | :------------- | :------------- | :------------- | :------------- |
 | <a id="rust_toolchain_repository_proxy-name"></a>name |  A unique name for this repository.   | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required |  |
-| <a id="rust_toolchain_repository_proxy-exec_compatible_with"></a>exec_compatible_with |  TODO   | List of strings | optional | [] |
-| <a id="rust_toolchain_repository_proxy-exec_triple"></a>exec_triple |  The Rust-style target triple for the compilation platform   | String | required |  |
-| <a id="rust_toolchain_repository_proxy-parent_workspace_name"></a>parent_workspace_name |  The name of the other rust_toolchain_repository   | String | required |  |
+| <a id="rust_toolchain_repository_proxy-exec_compatible_with"></a>exec_compatible_with |  A list of constraints for the execution platform for this toolchain.   | List of strings | optional | [] |
 | <a id="rust_toolchain_repository_proxy-repo_mapping"></a>repo_mapping |  A dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.&lt;p&gt;For example, an entry <code>"@foo": "@bar"</code> declares that, for any time this repository depends on <code>@foo</code> (such as a dependency on <code>@foo//some:target</code>, it should actually resolve that dependency within globally-declared <code>@bar</code> (<code>@bar//some:target</code>).   | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | required |  |
-| <a id="rust_toolchain_repository_proxy-target_compatible_with"></a>target_compatible_with |  TODO   | List of strings | optional | [] |
-| <a id="rust_toolchain_repository_proxy-target_triple"></a>target_triple |  The Rust-style target that this compiler builds for   | String | required |  |
+| <a id="rust_toolchain_repository_proxy-target_compatible_with"></a>target_compatible_with |  A list of constraints for the target platform for this toolchain.   | List of strings | optional | [] |
+| <a id="rust_toolchain_repository_proxy-toolchain"></a>toolchain |  The name of the toolchain implementation target.   | String | required |  |
+| <a id="rust_toolchain_repository_proxy-toolchain_type"></a>toolchain_type |  The toolchain type of the toolchain to declare   | String | required |  |
 
 
 <a id="rust_toolchain_tools_repository"></a>
@@ -152,7 +151,7 @@
 
 Composes a single workspace containing the toolchain components for compiling on a given platform to a series of target platforms.
 
-A given instance of this rule should be accompanied by a rust_toolchain_repository_proxy invocation to declare its toolchains to Bazel; the indirection allows separating toolchain selection from toolchain fetching.
+A given instance of this rule should be accompanied by a toolchain_repository_proxy invocation to declare its toolchains to Bazel; the indirection allows separating toolchain selection from toolchain fetching.
 
 **ATTRIBUTES**
 
@@ -307,9 +306,9 @@
 | <a id="rust_toolchain_repository-target_triple"></a>target_triple |  The Rust-style target to build for.   |  none |
 | <a id="rust_toolchain_repository-exec_compatible_with"></a>exec_compatible_with |  A list of constraints for the execution platform for this toolchain.   |  <code>None</code> |
 | <a id="rust_toolchain_repository-target_compatible_with"></a>target_compatible_with |  A list of constraints for the target platform for this toolchain.   |  <code>None</code> |
-| <a id="rust_toolchain_repository-include_rustc_srcs"></a>include_rustc_srcs |  Whether to download rustc's src code. This is required in order to use rust-analyzer support. Defaults to False.   |  <code>False</code> |
-| <a id="rust_toolchain_repository-iso_date"></a>iso_date |  The date of the tool. Defaults to None.   |  <code>None</code> |
-| <a id="rust_toolchain_repository-rustfmt_version"></a>rustfmt_version |  The version of rustfmt to be associated with the toolchain. Defaults to None.   |  <code>None</code> |
+| <a id="rust_toolchain_repository-include_rustc_srcs"></a>include_rustc_srcs |  Whether to download rustc's src code. This is required in order to use rust-analyzer support.   |  <code>False</code> |
+| <a id="rust_toolchain_repository-iso_date"></a>iso_date |  The date of the tool.   |  <code>None</code> |
+| <a id="rust_toolchain_repository-rustfmt_version"></a>rustfmt_version |  The version of rustfmt to be associated with the toolchain.   |  <code>None</code> |
 | <a id="rust_toolchain_repository-edition"></a>edition |  The rust edition to be used by default (2015, 2018, or 2021). If absent, every rule is required to specify its <code>edition</code> attribute.   |  <code>None</code> |
 | <a id="rust_toolchain_repository-dev_components"></a>dev_components |  Whether to download the rustc-dev components. Requires version to be "nightly". Defaults to False.   |  <code>False</code> |
 | <a id="rust_toolchain_repository-sha256s"></a>sha256s |  A dict associating tool subdirectories to sha256 hashes. See [rust_repositories](#rust_repositories) for more details.   |  <code>None</code> |
diff --git a/docs/symbols.bzl b/docs/symbols.bzl
index 07151d0..42e2f20 100644
--- a/docs/symbols.bzl
+++ b/docs/symbols.bzl
@@ -77,6 +77,7 @@
 )
 load(
     "@rules_rust//rust:toolchain.bzl",
+    _rust_analyzer_toolchain = "rust_analyzer_toolchain",
     _rust_stdlib_filegroup = "rust_stdlib_filegroup",
     _rust_toolchain = "rust_toolchain",
 )
@@ -149,6 +150,7 @@
 rust_clippy = _rust_clippy
 rust_clippy_aspect = _rust_clippy_aspect
 rust_analyzer_aspect = _rust_analyzer_aspect
+rust_analyzer_toolchain = _rust_analyzer_toolchain
 
 crate = _crate
 crates_repository = _crates_repository
diff --git a/examples/WORKSPACE.bazel b/examples/WORKSPACE.bazel
index ffdbbd0..005d052 100644
--- a/examples/WORKSPACE.bazel
+++ b/examples/WORKSPACE.bazel
@@ -14,7 +14,6 @@
 
 rust_register_toolchains(
     edition = "2018",
-    include_rustc_srcs = True,
 )
 
 load("@rules_rust//bindgen:repositories.bzl", "rust_bindgen_dependencies", "rust_bindgen_register_toolchains")
diff --git a/examples/crate_universe/WORKSPACE.bazel b/examples/crate_universe/WORKSPACE.bazel
index 5a23249..c0c6371 100644
--- a/examples/crate_universe/WORKSPACE.bazel
+++ b/examples/crate_universe/WORKSPACE.bazel
@@ -11,7 +11,6 @@
 
 rust_register_toolchains(
     edition = "2018",
-    include_rustc_srcs = True,
 )
 
 load("@rules_rust//crate_universe:repositories.bzl", "crate_universe_dependencies")
diff --git a/rust/BUILD.bazel b/rust/BUILD.bazel
index a1eaa59..672f228 100644
--- a/rust/BUILD.bazel
+++ b/rust/BUILD.bazel
@@ -29,6 +29,7 @@
         "//rust/platform:distro",
         "//rust/private:distro",
         "//rust/settings:distro",
+        "//rust/rust_analyzer:distro",
         "//rust/toolchain:distro",
         "BUILD.bazel",
     ],
diff --git a/rust/private/repository_utils.bzl b/rust/private/repository_utils.bzl
index 5b4da53..7d7f1e3 100644
--- a/rust/private/repository_utils.bzl
+++ b/rust/private/repository_utils.bzl
@@ -294,21 +294,23 @@
     name = "{name}",
     exec_compatible_with = {exec_constraint_sets_serialized},
     target_compatible_with = {target_constraint_sets_serialized},
-    toolchain = "@{parent_workspace_name}//:rust_toolchain",
-    toolchain_type = "@rules_rust//rust:toolchain",
+    toolchain = "{toolchain}",
+    toolchain_type = "{toolchain_type}",
 )
 """
 
 def BUILD_for_toolchain(
         name,
-        parent_workspace_name,
+        toolchain,
+        toolchain_type,
         target_compatible_with,
         exec_compatible_with):
     return _build_file_for_toolchain_template.format(
         name = name,
         exec_constraint_sets_serialized = exec_compatible_with,
         target_constraint_sets_serialized = target_compatible_with,
-        parent_workspace_name = parent_workspace_name,
+        toolchain = toolchain,
+        toolchain_type = toolchain_type,
     )
 
 def load_rustfmt(ctx):
@@ -416,26 +418,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)
     url = ctx.attr.urls[0].format(tool_suburl)
 
     tool_path = produce_tool_path("rust-src", None, ctx.attr.version)
     archive_path = tool_path + _get_tool_extension(ctx)
-    ctx.download(
+    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(archive_path) or FILE_KEY_TO_SHA.get(archive_path) 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(
@@ -448,6 +448,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
 
diff --git a/rust/private/rust_analyzer.bzl b/rust/private/rust_analyzer.bzl
index 771f659..a73e3aa 100644
--- a/rust/private/rust_analyzer.bzl
+++ b/rust/private/rust_analyzer.bzl
@@ -191,18 +191,39 @@
         crate["proc_macro_dylib_path"] = _exec_root_tmpl + info.proc_macro_dylib_path
     return crate
 
-def _rust_analyzer_detect_sysroot_impl(ctx):
-    rust_toolchain = find_toolchain(ctx)
+def _rust_analyzer_toolchain_impl(ctx):
+    toolchain = platform_common.ToolchainInfo(
+        rustc_srcs = ctx.attr.rustc_srcs,
+    )
 
-    if not rust_toolchain.rustc_srcs:
+    return [toolchain]
+
+rust_analyzer_toolchain = rule(
+    implementation = _rust_analyzer_toolchain_impl,
+    doc = "A toolchain for [rust-analyzer](https://rust-analyzer.github.io/).",
+    attrs = {
+        "rustc_srcs": attr.label(
+            doc = "The source code of rustc.",
+            mandatory = True,
+        ),
+    },
+    incompatible_use_toolchain_transition = True,
+)
+
+def _rust_analyzer_detect_sysroot_impl(ctx):
+    rust_analyzer_toolchain = ctx.toolchains[Label("@rules_rust//rust/rust_analyzer:toolchain_type")]
+
+    if not rust_analyzer_toolchain.rustc_srcs:
         fail(
-            "Current Rust toolchain doesn't contain rustc sources in `rustc_srcs` attribute.",
-            "These are needed by rust analyzer.",
-            "If you are using the default Rust toolchain, add `rust_repositories(include_rustc_srcs = True, ...).` to your WORKSPACE file.",
+            "Current Rust-Analyzer toolchain doesn't contain rustc sources in `rustc_srcs` attribute.",
+            "These are needed by rust-analyzer. If you are using the default Rust toolchain, add `rust_repositories(include_rustc_srcs = True, ...).` to your WORKSPACE file.",
         )
-    sysroot_src = rust_toolchain.rustc_srcs.label.package + "/library"
-    if rust_toolchain.rustc_srcs.label.workspace_root:
-        sysroot_src = _exec_root_tmpl + rust_toolchain.rustc_srcs.label.workspace_root + "/" + sysroot_src
+
+    rustc_srcs = rust_analyzer_toolchain.rustc_srcs
+
+    sysroot_src = rustc_srcs.label.package + "/library"
+    if rustc_srcs.label.workspace_root:
+        sysroot_src = _exec_root_tmpl + rustc_srcs.label.workspace_root + "/" + sysroot_src
 
     sysroot_src_file = ctx.actions.declare_file(ctx.label.name + ".rust_analyzer_sysroot_src")
     ctx.actions.write(
@@ -214,7 +235,10 @@
 
 rust_analyzer_detect_sysroot = rule(
     implementation = _rust_analyzer_detect_sysroot_impl,
-    toolchains = ["@rules_rust//rust:toolchain"],
+    toolchains = [
+        "@rules_rust//rust:toolchain",
+        "@rules_rust//rust/rust_analyzer:toolchain_type",
+    ],
     incompatible_use_toolchain_transition = True,
     doc = dedent("""\
         Detect the sysroot and store in a file for use by the gen_rust_project tool.
diff --git a/rust/private/toolchain_utils.bzl b/rust/private/toolchain_utils.bzl
index 4e32b6d..3d61746 100644
--- a/rust/private/toolchain_utils.bzl
+++ b/rust/private/toolchain_utils.bzl
@@ -42,8 +42,6 @@
         )
     elif ctx.attr.tool == "rustc_lib":
         files = toolchain.rustc_lib
-    elif ctx.attr.tool == "rustc_srcs":
-        files = toolchain.rustc_srcs.files
     elif ctx.attr.tool == "rust_std" or ctx.attr.tool == "rust_stdlib" or ctx.attr.tool == "rust_lib":
         files = toolchain.rust_std
     else:
@@ -67,7 +65,6 @@
                 "rust_std",
                 "rust_stdlib",
                 "rustc_lib",
-                "rustc_srcs",
                 "rustc",
                 "rustdoc",
                 "rustfmt",
diff --git a/rust/repositories.bzl b/rust/repositories.bzl
index 9b8d582..3fcfba3 100644
--- a/rust/repositories.bzl
+++ b/rust/repositories.bzl
@@ -8,6 +8,7 @@
 load("//rust/private:common.bzl", "rust_common")
 load(
     "//rust/private:repository_utils.bzl",
+    "BUILD_for_rust_analyzer_toolchain",
     "BUILD_for_rust_toolchain",
     "BUILD_for_toolchain",
     "DEFAULT_STATIC_RUST_URL_TEMPLATES",
@@ -135,6 +136,27 @@
     if not rustfmt_version:
         rustfmt_version = version
 
+    rust_analyzer_repo_name = "rust_analyzer_{}".format(version)
+    if iso_date:
+        rust_analyzer_repo_name = "{}-{}".format(
+            rust_analyzer_repo_name,
+            iso_date,
+        )
+
+    maybe(
+        rust_analyzer_toolchain_repository,
+        name = rust_analyzer_repo_name,
+        version = version,
+        urls = urls,
+        sha256s = sha256s,
+        iso_date = iso_date,
+    )
+
+    if register_toolchains:
+        native.register_toolchains("@{}//:toolchain".format(
+            rust_analyzer_repo_name,
+        ))
+
     for exec_triple, name in DEFAULT_TOOLCHAIN_TRIPLES.items():
         maybe(
             rust_repository_set,
@@ -217,7 +239,7 @@
         "Composes a single workspace containing the toolchain components for compiling on a given " +
         "platform to a series of target platforms.\n" +
         "\n" +
-        "A given instance of this rule should be accompanied by a rust_toolchain_repository_proxy " +
+        "A given instance of this rule should be accompanied by a toolchain_repository_proxy " +
         "invocation to declare its toolchains to Bazel; the indirection allows separating toolchain " +
         "selection from toolchain fetching."
     ),
@@ -278,46 +300,46 @@
     environ = ["RULES_RUST_TOOLCHAIN_INCLUDE_RUSTC_SRCS"],
 )
 
-def _rust_toolchain_repository_proxy_impl(repository_ctx):
+def _toolchain_repository_proxy_impl(repository_ctx):
     repository_ctx.file("WORKSPACE.bazel", """workspace(name = "{}")""".format(
         repository_ctx.name,
     ))
 
     repository_ctx.file("BUILD.bazel", BUILD_for_toolchain(
-        name = "rust_toolchain",
-        parent_workspace_name = repository_ctx.attr.parent_workspace_name,
+        name = "toolchain",
+        toolchain = repository_ctx.attr.toolchain,
+        toolchain_type = repository_ctx.attr.toolchain_type,
         target_compatible_with = json.encode(repository_ctx.attr.target_compatible_with),
         exec_compatible_with = json.encode(repository_ctx.attr.exec_compatible_with),
     ))
 
-rust_toolchain_repository_proxy = repository_rule(
+toolchain_repository_proxy = repository_rule(
     doc = (
         "Generates a toolchain-bearing repository that declares the toolchains from some other " +
         "rust_toolchain_repository."
     ),
     attrs = {
         "exec_compatible_with": attr.string_list(
-            doc = "TODO",
-        ),
-        "exec_triple": attr.string(
-            doc = "The Rust-style target triple for the compilation platform",
-            mandatory = True,
-        ),
-        "parent_workspace_name": attr.string(
-            doc = "The name of the other rust_toolchain_repository",
-            mandatory = True,
+            doc = "A list of constraints for the execution platform for this toolchain.",
         ),
         "target_compatible_with": attr.string_list(
-            doc = "TODO",
+            doc = "A list of constraints for the target platform for this toolchain.",
         ),
-        "target_triple": attr.string(
-            doc = "The Rust-style target that this compiler builds for",
+        "toolchain": attr.string(
+            doc = "The name of the toolchain implementation target.",
+            mandatory = True,
+        ),
+        "toolchain_type": attr.string(
+            doc = "The toolchain type of the toolchain to declare",
             mandatory = True,
         ),
     },
-    implementation = _rust_toolchain_repository_proxy_impl,
+    implementation = _toolchain_repository_proxy_impl,
 )
 
+# For legacy support
+rust_toolchain_repository_proxy = toolchain_repository_proxy
+
 def rust_toolchain_repository(
         name,
         version,
@@ -346,10 +368,10 @@
         target_triple (str): The Rust-style target to build for.
         exec_compatible_with (list, optional): A list of constraints for the execution platform for this toolchain.
         target_compatible_with (list, optional): A list of constraints for the target platform for this toolchain.
-        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.
-        iso_date (str, optional): The date of the tool. Defaults to None.
+        include_rustc_srcs (bool, optional): Whether to download rustc's src code. This is required in order to use rust-analyzer support.
+        iso_date (str, optional): The date of the tool.
         rustfmt_version (str, optional):  The version of rustfmt to be associated with the
-            toolchain. Defaults to None.
+            toolchain.
         edition (str, optional): The rust edition to be used by default (2015, 2018, or 2021). If absent, every rule is required to specify its `edition` attribute.
         dev_components (bool, optional): Whether to download the rustc-dev components.
             Requires version to be "nightly". Defaults to False.
@@ -384,19 +406,103 @@
         auth = auth,
     )
 
-    rust_toolchain_repository_proxy(
+    toolchain_repository_proxy(
         name = name,
-        exec_triple = exec_triple,
-        target_triple = target_triple,
-        parent_workspace_name = name + "_tools",
+        toolchain = "@{}//:{}".format(name + "_tools", "rust_toolchain"),
+        toolchain_type = "@rules_rust//rust:toolchain",
         exec_compatible_with = exec_compatible_with,
         target_compatible_with = target_compatible_with,
     )
 
-    return "@{name}//:rust_toolchain".format(
+    return "@{name}//:toolchain".format(
         name = name,
     )
 
+def _rust_analyzer_toolchain_srcs_repository_impl(repository_ctx):
+    load_rust_src(repository_ctx)
+
+    repository_ctx.file("WORKSPACE.bazel", """workspace(name = "{}")""".format(
+        repository_ctx.name,
+    ))
+
+    repository_ctx.file("BUILD.bazel", BUILD_for_rust_analyzer_toolchain(
+        name = "rust_analyzer_toolchain",
+    ))
+
+rust_analyzer_toolchain_srcs_repository = repository_rule(
+    doc = "A repository rule for defining a rust_analyzer_toolchain with a `rust-src` artifact.",
+    attrs = {
+        "auth": attr.string_dict(
+            doc = (
+                "Auth object compatible with repository_ctx.download to use when downloading files. " +
+                "See [repository_ctx.download](https://docs.bazel.build/versions/main/skylark/lib/repository_ctx.html#download) for more details."
+            ),
+        ),
+        "iso_date": attr.string(
+            doc = "The date of the tool (or None, if the version is a specific version).",
+        ),
+        "sha256s": attr.string_dict(
+            doc = "A dict associating tool subdirectories to sha256 hashes. See [rust_repositories](#rust_repositories) for more details.",
+        ),
+        "urls": attr.string_list(
+            doc = "A list of mirror urls containing the tools from the Rust-lang static file server. These must contain the '{}' used to substitute the tool being fetched (using .format).",
+            default = DEFAULT_STATIC_RUST_URL_TEMPLATES,
+        ),
+        "version": attr.string(
+            doc = "The version of the tool among \"nightly\", \"beta\", or an exact version.",
+            mandatory = True,
+        ),
+    },
+    implementation = _rust_analyzer_toolchain_srcs_repository_impl,
+)
+
+def rust_analyzer_toolchain_repository(
+        name,
+        version,
+        exec_compatible_with = [],
+        target_compatible_with = [],
+        iso_date = None,
+        sha256s = None,
+        urls = None,
+        auth = None):
+    """Assemble a remote rust_analyzer_toolchain target based on the given params.
+
+    Args:
+        name (str): The name of the toolchain proxy repository contianing the registerable toolchain.
+        version (str): The version of the tool among "nightly", "beta', or an exact version.
+        exec_compatible_with (list, optional): A list of constraints for the execution platform for this toolchain.
+        target_compatible_with (list, optional): A list of constraints for the target platform for this toolchain.
+        iso_date (str, optional): The date of the tool.
+        sha256s (str, optional): A dict associating tool subdirectories to sha256 hashes. See
+            [rust_repositories](#rust_repositories) for more details.
+        urls (list, optional): A list of mirror urls containing the tools from the Rust-lang static file server. These must contain the '{}' used to substitute the tool being fetched (using .format). Defaults to ['https://static.rust-lang.org/dist/{}.tar.gz']
+        auth (dict): Auth object compatible with repository_ctx.download to use when downloading files.
+            See [repository_ctx.download](https://docs.bazel.build/versions/main/skylark/lib/repository_ctx.html#download) for more details.
+
+    Returns:
+        str: The name of a registerable rust_analyzer_toolchain.
+    """
+    rust_analyzer_toolchain_srcs_repository(
+        name = name + "_srcs",
+        version = version,
+        iso_date = iso_date,
+        sha256s = sha256s,
+        urls = urls,
+        auth = auth,
+    )
+
+    toolchain_repository_proxy(
+        name = name,
+        toolchain = "@{}//:{}".format(name + "_srcs", "rust_analyzer_toolchain"),
+        toolchain_type = "@rules_rust//rust/rust_analyzer:toolchain_type",
+        exec_compatible_with = exec_compatible_with,
+        target_compatible_with = target_compatible_with,
+    )
+
+    return "@{}//:toolchain".format(
+        name,
+    )
+
 def _rust_toolchain_set_repository_impl(repository_ctx):
     repository_ctx.file("WORKSPACE.bazel", """workspace(name = "{}")""".format(
         repository_ctx.name,
diff --git a/rust/rust_analyzer/BUILD.bazel b/rust/rust_analyzer/BUILD.bazel
new file mode 100644
index 0000000..2b9f2bf
--- /dev/null
+++ b/rust/rust_analyzer/BUILD.bazel
@@ -0,0 +1,13 @@
+package(default_visibility = ["//visibility:public"])
+
+toolchain_type(
+    name = "toolchain_type",
+)
+
+filegroup(
+    name = "distro",
+    srcs = [
+        "BUILD.bazel",
+    ],
+    visibility = ["//:__subpackages__"],
+)
diff --git a/rust/toolchain.bzl b/rust/toolchain.bzl
index 35f280f..349c393 100644
--- a/rust/toolchain.bzl
+++ b/rust/toolchain.bzl
@@ -2,8 +2,11 @@
 
 load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
 load("//rust/private:common.bzl", "rust_common")
+load("//rust/private:rust_analyzer.bzl", _rust_analyzer_toolchain = "rust_analyzer_toolchain")
 load("//rust/private:utils.bzl", "dedent", "find_cc_toolchain", "make_static_lib_symlink")
 
+rust_analyzer_toolchain = _rust_analyzer_toolchain
+
 def _rust_stdlib_filegroup_impl(ctx):
     rust_std = ctx.files.srcs
     dot_a_files = []
diff --git a/rust/toolchain/BUILD.bazel b/rust/toolchain/BUILD.bazel
index dffc380..fede5de 100644
--- a/rust/toolchain/BUILD.bazel
+++ b/rust/toolchain/BUILD.bazel
@@ -69,17 +69,6 @@
 )
 
 toolchain_files(
-    name = "current_rustc_srcs_files",
-    tool = "rustc_srcs",
-)
-
-alias(
-    name = "current_exec_rustc_srcs_files",
-    actual = "current_rustc_srcs_files",
-    deprecation = "instead use `@rules_rust//rust/toolchain:current_rustc_srcs_files`",
-)
-
-toolchain_files(
     name = "current_rust_stdlib_files",
     tool = "rust_stdlib",
 )