Replace slashes with underscores in default crate names. (#1336)
This is another attempt at #1334, which sought to make "/" characters legal in Rust target names.
This PR differs from #1334 in how it handles build artifacts that are based on `crate_info.output`. There are a few places that currently assume that calling `ctx.actions.declare_file(...)` will always declare a file in the same directory as `crate_info.output`, i.e. as `ctx.actions.declare_file(ctx.label.name + ...)`. In a world where label names may include slashes (which is the case today!), this is not a safe assumption, since a slash in the target name causes bazel to create a subdirectory for the output.
Specifically, this PR fixes incorrect locations for the following items (when the target name includes a slash):
* PDB files
* dSYM files
* .lib files
This leaves a few things that look like they make the same assumption, but I'm not sure how they're used or if they should be updated:
* `"_ambiguous_libs/" + crate_info.output.basename + "/" + symlink_name` for ambiguous libraries
* The linkstamp output path (`"_objs/" + crate_info.output.basename + "/" + ...`)
diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl
index 0c70aa9..c34e250 100644
--- a/rust/private/rustc.bzl
+++ b/rust/private/rustc.bzl
@@ -923,7 +923,7 @@
if toolchain.os == "windows" and crate_info.type == "cdylib":
# Rustc generates the import library with a `.dll.lib` extension rather than the usual `.lib` one that msvc
# expects (see https://github.com/rust-lang/rust/pull/29520 for more context).
- interface_library = ctx.actions.declare_file(crate_info.output.basename + ".lib")
+ interface_library = ctx.actions.declare_file(crate_info.output.basename + ".lib", sibling = crate_info.output)
outputs.append(interface_library)
# The action might generate extra output that we don't want to include in the `DefaultInfo` files.
@@ -935,10 +935,10 @@
dsym_folder = None
if crate_info.type in ("cdylib", "bin") and not crate_info.is_test:
if toolchain.os == "windows":
- pdb_file = ctx.actions.declare_file(crate_info.output.basename[:-len(crate_info.output.extension)] + "pdb")
+ pdb_file = ctx.actions.declare_file(crate_info.output.basename[:-len(crate_info.output.extension)] + "pdb", sibling = crate_info.output)
action_outputs.append(pdb_file)
elif toolchain.os == "darwin":
- dsym_folder = ctx.actions.declare_directory(crate_info.output.basename + ".dSYM")
+ dsym_folder = ctx.actions.declare_directory(crate_info.output.basename + ".dSYM", sibling = crate_info.output)
action_outputs.append(dsym_folder)
if ctx.executable._process_wrapper:
diff --git a/rust/private/utils.bzl b/rust/private/utils.bzl
index 1e61993..83dbb1e 100644
--- a/rust/private/utils.bzl
+++ b/rust/private/utils.bzl
@@ -272,7 +272,9 @@
Returns:
str: The name of the crate for this target.
"""
- return name.replace("-", "_")
+ for illegal in ("-", "/"):
+ name = name.replace(illegal, "_")
+ return name
def _invalid_chars_in_crate_name(name):
"""Returns any invalid chars in the given crate name.
diff --git a/test/unit/crate_name/crate_name_test.bzl b/test/unit/crate_name/crate_name_test.bzl
index 968f2b5..8671951 100644
--- a/test/unit/crate_name/crate_name_test.bzl
+++ b/test/unit/crate_name/crate_name_test.bzl
@@ -48,7 +48,7 @@
def _invalid_default_crate_name_test_impl(ctx):
env = analysistest.begin(ctx)
- asserts.expect_failure(env, "contains invalid character(s): /")
+ asserts.expect_failure(env, "contains invalid character(s): @")
return analysistest.end(env)
def _invalid_custom_crate_name_test_impl(ctx):
@@ -119,7 +119,7 @@
def _crate_name_test():
rust_library(
- name = "default-crate-name-library",
+ name = "default/crate-name-library",
srcs = ["lib.rs"],
edition = "2018",
)
@@ -132,7 +132,7 @@
)
rust_binary(
- name = "default-crate-name-binary",
+ name = "default/crate-name-binary",
srcs = ["main.rs"],
edition = "2018",
)
@@ -145,7 +145,7 @@
)
rust_test(
- name = "default-crate-name-test",
+ name = "default/crate-name-test",
srcs = ["main.rs"],
edition = "2018",
)
@@ -158,7 +158,7 @@
)
rust_library(
- name = "invalid/default-crate-name",
+ name = "invalid@default-crate-name",
srcs = ["lib.rs"],
edition = "2018",
tags = ["manual", "norustfmt"],
@@ -197,7 +197,7 @@
default_crate_name_library_test(
name = "default_crate_name_library_test",
- target_under_test = ":default-crate-name-library",
+ target_under_test = ":default/crate-name-library",
)
custom_crate_name_library_test(
@@ -207,7 +207,7 @@
default_crate_name_binary_test(
name = "default_crate_name_binary_test",
- target_under_test = ":default-crate-name-binary",
+ target_under_test = ":default/crate-name-binary",
)
custom_crate_name_binary_test(
@@ -217,7 +217,7 @@
default_crate_name_test_test(
name = "default_crate_name_test_test",
- target_under_test = ":default-crate-name-test",
+ target_under_test = ":default/crate-name-test",
)
custom_crate_name_test_test(
@@ -227,7 +227,7 @@
invalid_default_crate_name_test(
name = "invalid_default_crate_name_test",
- target_under_test = ":invalid/default-crate-name",
+ target_under_test = ":invalid@default-crate-name",
)
invalid_custom_crate_name_test(