rs_bindings_from_cc: Add a step to apply `rust_bindings_from_cc_aspect` patch to rules_rust repo.

PiperOrigin-RevId: 553070997
Change-Id: Ie48f03592b1861e40fa5805bdd5e990f7e8fab73
diff --git a/WORKSPACE b/WORKSPACE
index 37eaebe..7eb4507 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -30,6 +30,16 @@
 
 http_archive(
     name = "rules_rust",
+    patch_args = [
+        "-p1",
+    ],
+    patches = [
+        # copybara:strip_begin(Google-internal)
+        # The patch is based on the copybara transformations here:
+        # http://google3/third_party/bazel_rules/rules_rust/copy.bara.sky;l=398;rcl=549936350
+        # copybara:strip_end
+        "@@//bazel/rules_rust:attach_rust_bindings_from_cc_aspect.patch",
+    ],
     sha256 = "4a9cb4fda6ccd5b5ec393b2e944822a62e050c7c06f1ea41607f14c4fdec57a2",
     urls = ["https://github.com/bazelbuild/rules_rust/releases/download/0.25.1/rules_rust-v0.25.1.tar.gz"],
 )
diff --git a/bazel/rules_rust/BUILD.bazel b/bazel/rules_rust/BUILD.bazel
new file mode 100644
index 0000000..ffd0fb0
--- /dev/null
+++ b/bazel/rules_rust/BUILD.bazel
@@ -0,0 +1 @@
+package(default_visibility = ["//visibility:public"])
diff --git a/bazel/rules_rust/attach_rust_bindings_from_cc_aspect.patch b/bazel/rules_rust/attach_rust_bindings_from_cc_aspect.patch
new file mode 100644
index 0000000..31f10f5
--- /dev/null
+++ b/bazel/rules_rust/attach_rust_bindings_from_cc_aspect.patch
@@ -0,0 +1,86 @@
+# Part of the Crubit project, under the Apache License v2.0 with LLVM
+# Exceptions. See /LICENSE for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl
+index 1a3c4ebf..0a1c2f2c 100644
+--- a/rust/private/rust.bzl
++++ b/rust/private/rust.bzl
+@@ -14,7 +14,17 @@
+
+ """Rust rule implementations"""
+
+-load("@bazel_skylib//lib:paths.bzl", "paths")
++load(
++    "@@//rs_bindings_from_cc/bazel_support:rust_bindings_from_cc_aspect.bzl",
++    "rust_bindings_from_cc_aspect",
++)
++load(
++    "@@//bazel/rules_rust:collect_deps.bzl",
++    "collect_transformed_deps",
++    "get_cc_import_namespace_variable",
++    "get_namespace_json_files",
++)
++load("@bazel_skylib//lib:paths.bzl", "paths")
+ load("//rust/private:common.bzl", "rust_common")
+ load("//rust/private:providers.bzl", "BuildInfo")
+ load("//rust/private:rustc.bzl", "rustc_compile_action")
+@@ -305,7 +315,7 @@ def _rust_library_common(ctx, crate_type):
+             output = rust_lib,
+             metadata = rust_metadata,
+             edition = get_edition(ctx.attr, toolchain, ctx.label),
+-            rustc_env = ctx.attr.rustc_env,
++            rustc_env = ctx.attr.rustc_env | get_cc_import_namespace_variable(ctx),
+             rustc_env_files = ctx.files.rustc_env_files,
+             is_test = False,
+             compile_data = depset(ctx.files.compile_data),
+@@ -352,7 +362,7 @@ def _rust_binary_impl(ctx):
+             aliases = ctx.attr.aliases,
+             output = output,
+             edition = get_edition(ctx.attr, toolchain, ctx.label),
+-            rustc_env = ctx.attr.rustc_env,
++            rustc_env = ctx.attr.rustc_env | get_cc_import_namespace_variable(ctx),
+             rustc_env_files = ctx.files.rustc_env_files,
+             is_test = False,
+             compile_data = depset(ctx.files.compile_data),
+@@ -376,7 +386,7 @@ def _rust_test_impl(ctx):
+     toolchain = find_toolchain(ctx)
+
+     crate_type = "bin"
+-    deps = transform_deps(ctx.attr.deps)
++    deps = collect_transformed_deps(ctx)
+     proc_macro_deps = transform_deps(ctx.attr.proc_macro_deps + get_import_macro_deps(ctx))
+
+     if ctx.attr.crate:
+@@ -418,7 +428,7 @@ def _rust_test_impl(ctx):
+             aliases = ctx.attr.aliases,
+             output = output,
+             edition = crate.edition,
+-            rustc_env = rustc_env,
++            rustc_env = rustc_env  | get_cc_import_namespace_variable(ctx),
+             rustc_env_files = rustc_env_files,
+             is_test = True,
+             compile_data = compile_data,
+@@ -454,10 +464,10 @@ def _rust_test_impl(ctx):
+             aliases = ctx.attr.aliases,
+             output = output,
+             edition = get_edition(ctx.attr, toolchain, ctx.label),
+-            rustc_env = ctx.attr.rustc_env,
++            rustc_env = ctx.attr.rustc_env | get_cc_import_namespace_variable(ctx),
+             rustc_env_files = ctx.files.rustc_env_files,
+             is_test = True,
+-            compile_data = depset(ctx.files.compile_data),
++            compile_data = depset(ctx.files.compile_data + get_namespace_json_files(ctx)),
+             compile_data_targets = depset(ctx.attr.compile_data),
+             owner = ctx.label,
+         )
+@@ -614,6 +620,10 @@ _common_attrs = {
+         """),
+         allow_files = True,
+     ),
++    "cc_deps": attr.label_list(
++        aspects = [rust_bindings_from_cc_aspect],
++        default = []
++    ),
+     "deps": attr.label_list(
+         doc = dedent("""\
+             List of other libraries to be linked to this library target.
diff --git a/bazel/rules_rust/collect_deps.bzl b/bazel/rules_rust/collect_deps.bzl
new file mode 100644
index 0000000..d88491e
--- /dev/null
+++ b/bazel/rules_rust/collect_deps.bzl
@@ -0,0 +1,114 @@
+# Part of the Crubit project, under the Apache License v2.0 with LLVM
+# Exceptions. See /LICENSE for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+""""A helper function to gather providers from rust_bindings_from_cc_aspect."""
+
+load(
+    "@@//rs_bindings_from_cc/bazel_support:providers.bzl",
+    "RustBindingsFromCcInfo",
+)
+
+# buildifier: disable=bzl-visibility
+load(
+    "@rules_rust//rust/private:providers.bzl",
+    "BuildInfo",
+    "CrateInfo",
+    "DepInfo",
+    "DepVariantInfo",
+)
+
+def collect_transformed_deps(ctx):
+    """Creates DepVariantInfos from all dependencies and from the rust_bindings_from_cc_aspect.
+
+    Args:
+        ctx (ctx): The target's context object.
+
+    Returns:
+        list[DepVariantInfo]: a list of DepVariantInfos that this target depends on.
+    """
+    deps = [DepVariantInfo(
+        crate_info = dep[CrateInfo] if CrateInfo in dep else None,
+        dep_info = dep[DepInfo] if DepInfo in dep else None,
+        build_info = dep[BuildInfo] if BuildInfo in dep else None,
+        cc_info = dep[CcInfo] if CcInfo in dep else None,
+    ) for dep in ctx.attr.deps]
+
+    for dep in ctx.attr.deps:
+        if RustBindingsFromCcInfo in dep:
+            deps.append(dep[RustBindingsFromCcInfo].dep_variant_info)
+            deps.append(
+                DepVariantInfo(
+                    cc_info = dep[RustBindingsFromCcInfo].cc_info,
+                    crate_info = None,
+                    dep_info = None,
+                    build_info = None,
+                ),
+            )
+
+    if hasattr(ctx.attr, "cc_deps"):
+        for dep in ctx.attr.cc_deps:
+            if RustBindingsFromCcInfo in dep:
+                deps.append(dep[RustBindingsFromCcInfo].dep_variant_info)
+                deps.append(
+                    DepVariantInfo(
+                        cc_info = dep[RustBindingsFromCcInfo].cc_info,
+                        crate_info = None,
+                        dep_info = None,
+                        build_info = None,
+                    ),
+                )
+
+    return deps
+
+def get_cc_import_namespace_variable(ctx):
+    """Returns a dictionary containing the CC_IMPORT_NAMESPACES environment variable.
+
+    Args:
+        ctx (ctx): The target's context object.
+
+    Returns:
+        dict {String: String}: A dictionary with a single "CC_IMPORT_NAMESPACES" key, whose value
+            are json encoded paths to the C++ dependencies' namespaces files.
+    """
+    namespace_json_filepaths = []
+    if hasattr(ctx.attr, "cc_deps"):
+        namespace_json_filepaths.extend([
+            dep[RustBindingsFromCcInfo].namespaces.path
+            for dep in ctx.attr.cc_deps
+            if RustBindingsFromCcInfo in dep
+        ])
+
+    cc_import_namespaces_var_name = "CC_IMPORT_NAMESPACES"
+
+    # For `rust_test` we need to collect the json namespace files listed in `cc_deps`, as well as
+    # the json namespace files listed in the underlying `crate`'s `cc_deps`.
+    crate = getattr(ctx.attr, "crate", None)
+    if crate:
+        if CrateInfo not in crate:
+            fail("A rust target must provide a CrateInfo")
+
+        if cc_import_namespaces_var_name in crate[CrateInfo].rustc_env:
+            namespace_json_filepaths.extend(json.decode(crate[CrateInfo].rustc_env[cc_import_namespaces_var_name]))
+
+    if namespace_json_filepaths:
+        return {
+            cc_import_namespaces_var_name: json.encode(namespace_json_filepaths),
+        }
+    return {}
+
+def get_namespace_json_files(ctx):
+    """Returns the C++ dependencies' namespace json files.
+
+    Args:
+        ctx (ctx): The target's context object.
+
+    Returns:
+        list[Artifact]: The C++ dependencies' namespace json files.
+    """
+    if hasattr(ctx.attr, "cc_deps"):
+        return [
+            dep[RustBindingsFromCcInfo].namespaces
+            for dep in ctx.attr.cc_deps
+            if RustBindingsFromCcInfo in dep
+        ]
+    return []
diff --git a/rs_bindings_from_cc/bazel_support/deps_for_bindings.bzl b/rs_bindings_from_cc/bazel_support/deps_for_bindings.bzl
index 291369a..0632678 100644
--- a/rs_bindings_from_cc/bazel_support/deps_for_bindings.bzl
+++ b/rs_bindings_from_cc/bazel_support/deps_for_bindings.bzl
@@ -16,7 +16,7 @@
     "DepVariantInfo",
 )
 load(
-    "//rs_bindings_from_cc/bazel_support:providers.bzl",
+    "@@//rs_bindings_from_cc/bazel_support:providers.bzl",
     "DepsForBindingsInfo",
 )
 
diff --git a/rs_bindings_from_cc/bazel_support/rust_bindings_from_cc_aspect.bzl b/rs_bindings_from_cc/bazel_support/rust_bindings_from_cc_aspect.bzl
index d1b8466..48a606d 100644
--- a/rs_bindings_from_cc/bazel_support/rust_bindings_from_cc_aspect.bzl
+++ b/rs_bindings_from_cc/bazel_support/rust_bindings_from_cc_aspect.bzl
@@ -12,26 +12,26 @@
 """
 
 load(
-    "//rs_bindings_from_cc/bazel_support:providers.bzl",
+    "@@//rs_bindings_from_cc/bazel_support:providers.bzl",
     "DepsForBindingsInfo",
     "RustBindingsFromCcInfo",
     "RustToolchainHeadersInfo",
 )
 load(
-    "//rs_bindings_from_cc/bazel_support:rust_bindings_from_cc_utils.bzl",
+    "@@//rs_bindings_from_cc/bazel_support:rust_bindings_from_cc_utils.bzl",
     "bindings_attrs",
     "generate_and_compile_bindings",
 )
 load(
-    "//rs_bindings_from_cc/bazel_support:crubit_feature_hint.bzl",
+    "@@//rs_bindings_from_cc/bazel_support:crubit_feature_hint.bzl",
     "find_crubit_features",
 )
 load(
-    "//rs_bindings_from_cc/bazel_support:rust_bindings_from_cc_cli_flag_aspect_hint.bzl",
+    "@@//rs_bindings_from_cc/bazel_support:rust_bindings_from_cc_cli_flag_aspect_hint.bzl",
     "collect_rust_bindings_from_cc_cli_flags",
 )
 load(
-    "//rs_bindings_from_cc/bazel_support:additional_rust_srcs_for_crubit_bindings_aspect_hint.bzl",
+    "@@//rs_bindings_from_cc/bazel_support:additional_rust_srcs_for_crubit_bindings_aspect_hint.bzl",
     "get_additional_rust_srcs",
 )
 
diff --git a/rs_bindings_from_cc/bazel_support/rust_bindings_from_cc_binary.bzl b/rs_bindings_from_cc/bazel_support/rust_bindings_from_cc_binary.bzl
index 01a1ed2..c651e92 100644
--- a/rs_bindings_from_cc/bazel_support/rust_bindings_from_cc_binary.bzl
+++ b/rs_bindings_from_cc/bazel_support/rust_bindings_from_cc_binary.bzl
@@ -14,7 +14,7 @@
 """
 
 load(
-    "//rs_bindings_from_cc/bazel_support:rust_bindings_from_cc_transition.bzl",
+    "@@//rs_bindings_from_cc/bazel_support:rust_bindings_from_cc_transition.bzl",
     "rust_bindings_from_cc_transition",
 )
 
diff --git a/rs_bindings_from_cc/bazel_support/rust_bindings_from_cc_transition.bzl b/rs_bindings_from_cc/bazel_support/rust_bindings_from_cc_transition.bzl
index f2b8bd0..1fabe76 100644
--- a/rs_bindings_from_cc/bazel_support/rust_bindings_from_cc_transition.bzl
+++ b/rs_bindings_from_cc/bazel_support/rust_bindings_from_cc_transition.bzl
@@ -7,8 +7,8 @@
 def _rust_bindings_from_cc_transition_impl(_settings, _attr):
     return {
         "@rules_rust//rust/settings:use_real_import_macro": False,
-        "//rs_bindings_from_cc/bazel_support:use_actual_bindings_generator": False,
-        "//rs_bindings_from_cc/bazel_support:use_actual_deps": False,
+        "@@//rs_bindings_from_cc/bazel_support:use_actual_bindings_generator": False,
+        "@@//rs_bindings_from_cc/bazel_support:use_actual_deps": False,
     }
 
 rust_bindings_from_cc_transition = transition(
@@ -16,7 +16,7 @@
     inputs = [],
     outputs = [
         "@rules_rust//rust/settings:use_real_import_macro",
-        "//rs_bindings_from_cc/bazel_support:use_actual_bindings_generator",
-        "//rs_bindings_from_cc/bazel_support:use_actual_deps",
+        "@@//rs_bindings_from_cc/bazel_support:use_actual_bindings_generator",
+        "@@//rs_bindings_from_cc/bazel_support:use_actual_deps",
     ],
 )
diff --git a/rs_bindings_from_cc/bazel_support/rust_bindings_from_cc_utils.bzl b/rs_bindings_from_cc/bazel_support/rust_bindings_from_cc_utils.bzl
index 5f11cbb..ae73072 100644
--- a/rs_bindings_from_cc/bazel_support/rust_bindings_from_cc_utils.bzl
+++ b/rs_bindings_from_cc/bazel_support/rust_bindings_from_cc_utils.bzl
@@ -8,12 +8,12 @@
 not be used yet.
 """
 
-load("//rs_bindings_from_cc/bazel_support:compile_cc.bzl", "compile_cc")
-load("//rs_bindings_from_cc/bazel_support:compile_rust.bzl", "compile_rust")
-load("//rs_bindings_from_cc/bazel_support:generate_bindings.bzl", "generate_bindings")
+load("@@//rs_bindings_from_cc/bazel_support:compile_cc.bzl", "compile_cc")
+load("@@//rs_bindings_from_cc/bazel_support:compile_rust.bzl", "compile_rust")
+load("@@//rs_bindings_from_cc/bazel_support:generate_bindings.bzl", "generate_bindings")
 load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
 load(
-    "//rs_bindings_from_cc/bazel_support:providers.bzl",
+    "@@//rs_bindings_from_cc/bazel_support:providers.bzl",
     "GeneratedBindingsInfo",
     "RustBindingsFromCcInfo",
 )
@@ -122,14 +122,14 @@
         default = "@bazel_tools//tools/cpp:current_cc_toolchain",
     ),
     "_generator": attr.label(
-        default = "//rs_bindings_from_cc/bazel_support:rust_bindings_from_cc_target",
+        default = "@@//rs_bindings_from_cc/bazel_support:rust_bindings_from_cc_target",
         executable = True,
         allow_single_file = True,
         cfg = "exec",
     ),
     "_deps_for_bindings": attr.label(
         doc = "Dependencies that are needed to compile the generated .cc and .rs file.",
-        default = "//rs_bindings_from_cc/bazel_support:deps_for_bindings",
+        default = "@@//rs_bindings_from_cc/bazel_support:deps_for_bindings",
     ),
     "_clang_format": attr.label(
         default = "//third_party/crosstool/google3_users:stable_clang-format",
@@ -166,6 +166,6 @@
         default = "//rs_bindings_from_cc:builtin_headers",
     ),
     "_generate_error_report": attr.label(
-        default = "//rs_bindings_from_cc/bazel_support:generate_error_report",
+        default = "@@//rs_bindings_from_cc/bazel_support:generate_error_report",
     ),
 }
diff --git a/rs_bindings_from_cc/bazel_support/toolchain_headers.bzl b/rs_bindings_from_cc/bazel_support/toolchain_headers.bzl
index 9715756..f6c9542 100644
--- a/rs_bindings_from_cc/bazel_support/toolchain_headers.bzl
+++ b/rs_bindings_from_cc/bazel_support/toolchain_headers.bzl
@@ -9,12 +9,12 @@
 """
 
 load(
-    "//rs_bindings_from_cc/bazel_support:providers.bzl",
+    "@@//rs_bindings_from_cc/bazel_support:providers.bzl",
     "DepsForBindingsInfo",
     "RustToolchainHeadersInfo",
 )
 load(
-    "//rs_bindings_from_cc/bazel_support:rust_bindings_from_cc_utils.bzl",
+    "@@//rs_bindings_from_cc/bazel_support:rust_bindings_from_cc_utils.bzl",
     "bindings_attrs",
     "generate_and_compile_bindings",
 )