use absolute value of hash function to determine crate name (#1064)

diff --git a/rust/private/utils.bzl b/rust/private/utils.bzl
index 218537b..bc00e69 100644
--- a/rust/private/utils.bzl
+++ b/rust/private/utils.bzl
@@ -132,7 +132,12 @@
     Returns:
         str: A string representation of the hash.
     """
-    return repr(hash(crate_root.path))
+
+    # Take the absolute value of hash() since it could be negative.
+    h = hash(crate_root.path)
+    if h < 0:
+        h = -h
+    return repr(h)
 
 def get_preferred_artifact(library_to_link):
     """Get the first available library to link from a LibraryToLink object.
diff --git a/test/BUILD.bazel b/test/BUILD.bazel
index 45e499a..499b269 100644
--- a/test/BUILD.bazel
+++ b/test/BUILD.bazel
@@ -5,7 +5,7 @@
 
 rule_test(
     name = "hello_lib_rule_test",
-    generates = ["libhello_lib--145651613.rlib"],
+    generates = ["libhello_lib-145651613.rlib"],
     rule = "//test/rust:hello_lib",
 )
 
diff --git a/test/unit/crate_name/crate_name_test.bzl b/test/unit/crate_name/crate_name_test.bzl
index 2a5d8ce..217bdfd 100644
--- a/test/unit/crate_name/crate_name_test.bzl
+++ b/test/unit/crate_name/crate_name_test.bzl
@@ -56,6 +56,21 @@
     asserts.expect_failure(env, "contains invalid character(s): -")
     return analysistest.end(env)
 
+def _slib_library_name_test_impl(ctx):
+    """Regression test for extra-filename.
+
+    Checks that the extra hash value appended to the library filename only
+    contains one dash. Previously, the hash for `slib` was negative,
+    resulting in an extra dash in the filename (--codegen_extra_filename=--517943325).
+
+    Args:
+      ctx: rule context.
+    """
+    env = analysistest.begin(ctx)
+    tut = analysistest.target_under_test(env)
+    assert_argv_contains(env, tut.actions[0], "--codegen=extra-filename=-517943325")
+    return analysistest.end(env)
+
 default_crate_name_library_test = analysistest.make(
     _default_crate_name_library_test_impl,
 )
@@ -82,6 +97,9 @@
     _invalid_custom_crate_name_test_impl,
     expect_failure = True,
 )
+slib_library_name_test = analysistest.make(
+    _slib_library_name_test_impl,
+)
 
 def _crate_name_test():
     rust_library(
@@ -130,6 +148,16 @@
         tags = ["manual", "norustfmt"],
     )
 
+    rust_library(
+        name = "slib",
+        srcs = ["slib.rs"],
+    )
+
+    slib_library_name_test(
+        name = "slib_library_name_test",
+        target_under_test = ":slib",
+    )
+
     default_crate_name_library_test(
         name = "default_crate_name_library_test",
         target_under_test = ":default-crate-name-library",
diff --git a/test/unit/crate_name/slib.rs b/test/unit/crate_name/slib.rs
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/test/unit/crate_name/slib.rs
@@ -0,0 +1 @@
+