diff --git a/rust/private/rust_analyzer.bzl b/rust/private/rust_analyzer.bzl index d565a75d35..d44f291697 100644 --- a/rust/private/rust_analyzer.bzl +++ b/rust/private/rust_analyzer.bzl @@ -23,7 +23,13 @@ to Cargo.toml files. load("//rust/platform:triple_mappings.bzl", "system_to_dylib_ext", "triple_to_system") load("//rust/private:common.bzl", "rust_common") load("//rust/private:rustc.bzl", "BuildInfo") -load("//rust/private:utils.bzl", "dedent", "find_toolchain") +load( + "//rust/private:utils.bzl", + "concat", + "dedent", + "dedup_expand_location", + "find_toolchain", +) RustAnalyzerInfo = provider( doc = "RustAnalyzerInfo holds rust crate metadata for targets", @@ -182,14 +188,11 @@ def _create_single_crate(ctx, info): "include_dirs": [crate_root, _EXEC_ROOT_TEMPLATE + out_dir_path], } - # We deduplicate the entries from each of the additional targets to work around - # https://github.com/bazelbuild/bazel/issues/16664 - # # TODO: The only imagined use case is an env var holding a filename in the workspace passed to a # macro like include_bytes!. Other use cases might exist that require more complex logic. - expand_targets = _deduplicate(_concat([getattr(ctx.rule.attr, attr, []) for attr in ["data", "compile_data"]])) + expand_targets = concat([getattr(ctx.rule.attr, attr, []) for attr in ["data", "compile_data"]]) - crate["env"].update({k: ctx.expand_location(v, expand_targets) for k, v in info.env.items()}) + crate["env"].update({k: dedup_expand_location(ctx, v, expand_targets) for k, v in info.env.items()}) # Omit when a crate appears to depend on itself (e.g. foo_test crates). # It can happen a single source file is present in multiple crates - there can @@ -208,12 +211,6 @@ def _create_single_crate(ctx, info): crate["proc_macro_dylib_path"] = _EXEC_ROOT_TEMPLATE + info.proc_macro_dylib_path return crate -def _deduplicate(xs): - return {x: True for x in xs}.keys() - -def _concat(xss): - return [x for xs in xss for x in xs] - def _rust_analyzer_toolchain_impl(ctx): toolchain = platform_common.ToolchainInfo( rustc_srcs = ctx.attr.rustc_srcs, diff --git a/rust/private/utils.bzl b/rust/private/utils.bzl index 0714887f6e..dfaf3f3e9e 100644 --- a/rust/private/utils.bzl +++ b/rust/private/utils.bzl @@ -223,6 +223,18 @@ def get_preferred_artifact(library_to_link, use_pic): library_to_link.dynamic_library ) +# The normal ctx.expand_location, but with an additional deduplication step. +# We do this to work around a potential crash, see +# https://github.com/bazelbuild/bazel/issues/16664 +def dedup_expand_location(ctx, input, targets = []): + return ctx.expand_location(input, _deduplicate(targets)) + +def _deduplicate(xs): + return {x: True for x in xs}.keys() + +def concat(xss): + return [x for xs in xss for x in xs] + def _expand_location_for_build_script_runner(ctx, env, data): """A trivial helper for `expand_dict_value_locations` and `expand_list_element_locations` @@ -240,7 +252,7 @@ def _expand_location_for_build_script_runner(ctx, env, data): env = env.replace(directive, "$${pwd}/" + directive) return ctx.expand_make_variables( env, - ctx.expand_location(env, data), + dedup_expand_location(ctx, env, data), {}, ) diff --git a/rust/toolchain.bzl b/rust/toolchain.bzl index 45fd8925e3..b0bc2cb7f6 100644 --- a/rust/toolchain.bzl +++ b/rust/toolchain.bzl @@ -3,7 +3,13 @@ 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") +load( + "//rust/private:utils.bzl", + "dedent", + "dedup_expand_location", + "find_cc_toolchain", + "make_static_lib_symlink", +) rust_analyzer_toolchain = _rust_analyzer_toolchain @@ -456,7 +462,8 @@ def _rust_toolchain_impl(ctx): expanded_stdlib_linkflags = [] for flag in ctx.attr.stdlib_linkflags: expanded_stdlib_linkflags.append( - ctx.expand_location( + dedup_expand_location( + ctx, flag, targets = rust_std[rust_common.stdlib_info].srcs, ),