Build `rust_test` targets using a crate name different from the underlying lib (#2803)

This PR also makes `rust_test` put its compilation outputs in the same
directory as the `rust_library` rule (i.e. not in a `test-{hash}`
subdirectory anymore).

After this change both the `rust_library` and `rust_test` rules will put
all its compilation outputs in the same directory, but there won't be
any name collisions in non-sandboxed environments (see
https://github.com/bazelbuild/rules_rust/pull/1427 for more context).

This is a partial rollback of
https://github.com/bazelbuild/rules_rust/commit/10185339ddd5db93a7ca4b10e2255e97c81f99cb
and
https://github.com/bazelbuild/rules_rust/commit/26344d4cd7bca958ab289eda3ac4c24f3a36fbeb.
diff --git a/docs/defs.md b/docs/defs.md
index 4c20a2a..2f49a50 100644
--- a/docs/defs.md
+++ b/docs/defs.md
@@ -567,9 +567,7 @@
 )
 ```
 
-Run the test with `bazel test //hello_lib:hello_lib_test`. The crate
-will be built using the same crate name as the underlying ":hello_lib"
-crate.
+Run the test with `bazel test //hello_lib:hello_lib_test`.
 
 ### Example: `test` directory
 
diff --git a/docs/flatten.md b/docs/flatten.md
index cfab41c..46ef53c 100644
--- a/docs/flatten.md
+++ b/docs/flatten.md
@@ -1050,9 +1050,7 @@
 )
 ```
 
-Run the test with `bazel test //hello_lib:hello_lib_test`. The crate
-will be built using the same crate name as the underlying ":hello_lib"
-crate.
+Run the test with `bazel test //hello_lib:hello_lib_test`.
 
 ### Example: `test` directory
 
diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl
index 2a248e3..1701880 100644
--- a/rust/private/rust.bzl
+++ b/rust/private/rust.bzl
@@ -296,6 +296,7 @@
 
     toolchain = find_toolchain(ctx)
 
+    crate_name = compute_crate_name(ctx.workspace_name, ctx.label, toolchain, ctx.attr.crate_name)
     crate_type = "bin"
     deps = transform_deps(ctx.attr.deps)
     proc_macro_deps = transform_deps(ctx.attr.proc_macro_deps + get_import_macro_deps(ctx))
@@ -309,13 +310,8 @@
         # Target is building the crate in `test` config
         crate = ctx.attr.crate[rust_common.crate_info] if rust_common.crate_info in ctx.attr.crate else ctx.attr.crate[rust_common.test_crate_info].crate
 
-        output_hash = determine_output_hash(crate.root, ctx.label)
         output = ctx.actions.declare_file(
-            "test-%s/%s%s" % (
-                output_hash,
-                ctx.label.name,
-                toolchain.binary_ext,
-            ),
+            ctx.label.name + toolchain.binary_ext,
         )
 
         srcs, crate_root = transform_sources(ctx, ctx.files.srcs, getattr(ctx.file, "crate_root", None))
@@ -342,7 +338,7 @@
 
         # Build the test binary using the dependency's srcs.
         crate_info_dict = dict(
-            name = crate.name,
+            name = crate_name,
             type = crate_type,
             root = crate.root,
             srcs = depset(srcs, transitive = [crate.srcs]),
@@ -368,13 +364,8 @@
             crate_root = crate_root_src(ctx.attr.name, ctx.files.srcs, crate_root_type)
         srcs, crate_root = transform_sources(ctx, ctx.files.srcs, crate_root)
 
-        output_hash = determine_output_hash(crate_root, ctx.label)
         output = ctx.actions.declare_file(
-            "test-%s/%s%s" % (
-                output_hash,
-                ctx.label.name,
-                toolchain.binary_ext,
-            ),
+            ctx.label.name + toolchain.binary_ext,
         )
 
         data_paths = depset(direct = getattr(ctx.attr, "data", [])).to_list()
@@ -386,7 +377,7 @@
 
         # Target is a standalone crate. Build the test binary as its own crate.
         crate_info_dict = dict(
-            name = compute_crate_name(ctx.workspace_name, ctx.label, toolchain, ctx.attr.crate_name),
+            name = crate_name,
             type = crate_type,
             root = crate_root,
             srcs = depset(srcs),
@@ -1342,9 +1333,7 @@
         )
         ```
 
-        Run the test with `bazel test //hello_lib:hello_lib_test`. The crate
-        will be built using the same crate name as the underlying ":hello_lib"
-        crate.
+        Run the test with `bazel test //hello_lib:hello_lib_test`.
 
         ### Example: `test` directory
 
diff --git a/test/rust/src/lib.rs b/test/rust/src/lib.rs
index bee47c9..9dc6089 100644
--- a/test/rust/src/lib.rs
+++ b/test/rust/src/lib.rs
@@ -12,5 +12,4 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#![crate_name = "hello_lib"]
 pub mod greeter;
diff --git a/test/unit/linkstamps/linkstamps_test.bzl b/test/unit/linkstamps/linkstamps_test.bzl
index a0ae6fe..089972f 100644
--- a/test/unit/linkstamps/linkstamps_test.bzl
+++ b/test/unit/linkstamps/linkstamps_test.bzl
@@ -2,7 +2,7 @@
 
 load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
 load("@rules_cc//cc:defs.bzl", "cc_library")
-load("//rust:defs.bzl", "rust_binary", "rust_common", "rust_library", "rust_test")
+load("//rust:defs.bzl", "rust_binary", "rust_library", "rust_test")
 load("//test/unit:common.bzl", "assert_action_mnemonic")
 
 def _is_running_on_linux(ctx):
@@ -20,13 +20,9 @@
     linkstamp_out = linkstamp_action.outputs.to_list()[0]
     asserts.equals(env, linkstamp_out.basename, "linkstamp.o")
     tut_out = tut.files.to_list()[0]
-    is_test = tut[rust_common.crate_info].is_test
     workspace_prefix = "" if ctx.workspace_name == "rules_rust" else "/external/rules_rust"
 
-    # Rust compilation outputs coming from a test are put in test-{hash} directory
-    # which we need to remove in order to obtain the linkstamp file path.
-    dirname = "/".join(tut_out.dirname.split("/")[:-1]) if is_test else tut_out.dirname
-    expected_linkstamp_path = dirname + "/_objs/" + tut_out.basename + workspace_prefix + "/test/unit/linkstamps/linkstamp.o"
+    expected_linkstamp_path = tut_out.dirname + "/_objs/" + tut_out.basename + workspace_prefix + "/test/unit/linkstamps/linkstamp.o"
     asserts.equals(
         env,
         linkstamp_out.path,
diff --git a/test/unit/rust_test_outputs_are_in_subdirectory/BUILD.bazel b/test/unit/rust_test_outputs_are_in_subdirectory/BUILD.bazel
deleted file mode 100644
index bf00a3a..0000000
--- a/test/unit/rust_test_outputs_are_in_subdirectory/BUILD.bazel
+++ /dev/null
@@ -1,4 +0,0 @@
-load(":rust_test_outputs.bzl", "rust_test_outputs_test_suite")
-
-############################ UNIT TESTS #############################
-rust_test_outputs_test_suite(name = "rust_test_outputs_test_suite")
diff --git a/test/unit/rust_test_outputs_are_in_subdirectory/foo.rs b/test/unit/rust_test_outputs_are_in_subdirectory/foo.rs
deleted file mode 100644
index da0f5d9..0000000
--- a/test/unit/rust_test_outputs_are_in_subdirectory/foo.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub fn main() {}
diff --git a/test/unit/rust_test_outputs_are_in_subdirectory/rust_test_outputs.bzl b/test/unit/rust_test_outputs_are_in_subdirectory/rust_test_outputs.bzl
deleted file mode 100644
index 3fb4782..0000000
--- a/test/unit/rust_test_outputs_are_in_subdirectory/rust_test_outputs.bzl
+++ /dev/null
@@ -1,64 +0,0 @@
-"""Tests for rust_test outputs directory."""
-
-load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
-load("//rust:defs.bzl", "rust_binary", "rust_common", "rust_test")
-
-def _rust_test_outputs_test(ctx):
-    env = analysistest.begin(ctx)
-    tut = analysistest.target_under_test(env)
-
-    output = tut[rust_common.crate_info].output
-
-    asserts.true(env, output.dirname.split("/")[-1].startswith("test-"))
-
-    return analysistest.end(env)
-
-rust_test_outputs_test = analysistest.make(
-    _rust_test_outputs_test,
-)
-
-def _rust_test_outputs_targets():
-    rust_binary(
-        name = "bin_outputs",
-        srcs = ["foo.rs"],
-        edition = "2018",
-    )
-
-    rust_test(
-        name = "test_outputs_with_srcs",
-        srcs = ["foo.rs"],
-        edition = "2018",
-    )
-
-    rust_test_outputs_test(
-        name = "rust_test_outputs_using_srcs_attr",
-        target_under_test = ":test_outputs_with_srcs",
-    )
-
-    rust_test(
-        name = "test_outputs_with_crate",
-        crate = "bin_outputs",
-        edition = "2018",
-    )
-
-    rust_test_outputs_test(
-        name = "rust_test_outputs_using_crate_attr",
-        target_under_test = ":test_outputs_with_crate",
-    )
-
-def rust_test_outputs_test_suite(name):
-    """Entry-point macro called from the BUILD file.
-
-    Args:
-        name: Name of the macro.
-    """
-
-    _rust_test_outputs_targets()
-
-    native.test_suite(
-        name = name,
-        tests = [
-            ":rust_test_outputs_using_srcs_attr",
-            ":rust_test_outputs_using_crate_attr",
-        ],
-    )