Don't leak native dependencies of proc_macro (#1359)
Native dependencies of a `rust_proc_macro` shouldn't propagate to the libraries depending on the `rust_proc_macro` target.
diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl
index 5a9d569..ac62460 100644
--- a/rust/private/rustc.bzl
+++ b/rust/private/rustc.bzl
@@ -191,7 +191,9 @@
] else [dep_info.transitive_crate_outputs],
),
)
- transitive_noncrates.append(dep_info.transitive_noncrates)
+
+ if "proc-macro" not in [crate_info.type, crate_info.wrapped_crate_type]:
+ transitive_noncrates.append(dep_info.transitive_noncrates)
transitive_build_infos.append(dep_info.transitive_build_infos)
transitive_link_search_paths.append(dep_info.link_search_path_files)
diff --git a/test/unit/proc_macro/leaks_deps/native/BUILD.bazel b/test/unit/proc_macro/leaks_deps/native/BUILD.bazel
new file mode 100644
index 0000000..988cfa3
--- /dev/null
+++ b/test/unit/proc_macro/leaks_deps/native/BUILD.bazel
@@ -0,0 +1,8 @@
+load("@rules_cc//cc:defs.bzl", "cc_library")
+
+package(default_visibility = ["//test:__subpackages__"])
+
+cc_library(
+ name = "native",
+ srcs = ["native.cc"],
+)
diff --git a/test/unit/proc_macro/leaks_deps/native/native.cc b/test/unit/proc_macro/leaks_deps/native/native.cc
new file mode 100644
index 0000000..7c6f54d
--- /dev/null
+++ b/test/unit/proc_macro/leaks_deps/native/native.cc
@@ -0,0 +1,7 @@
+#include <stdint.h>
+
+extern "C" {
+ int32_t forty_two_from_cc() {
+ return 42;
+ }
+}
diff --git a/test/unit/proc_macro/leaks_deps/proc_macro_definition_with_native_dependency.rs b/test/unit/proc_macro/leaks_deps/proc_macro_definition_with_native_dependency.rs
new file mode 100644
index 0000000..a4e368e
--- /dev/null
+++ b/test/unit/proc_macro/leaks_deps/proc_macro_definition_with_native_dependency.rs
@@ -0,0 +1,7 @@
+use proc_macro::TokenStream;
+use proc_macro_dep_with_native_dep::forty_two;
+
+#[proc_macro]
+pub fn make_forty_two_from_native_dep(_item: TokenStream) -> TokenStream {
+ forty_two().to_string().parse().unwrap()
+}
diff --git a/test/unit/proc_macro/leaks_deps/proc_macro_dep/BUILD.bazel b/test/unit/proc_macro/leaks_deps/proc_macro_dep/BUILD.bazel
index e7a4e7d..8bee950 100644
--- a/test/unit/proc_macro/leaks_deps/proc_macro_dep/BUILD.bazel
+++ b/test/unit/proc_macro/leaks_deps/proc_macro_dep/BUILD.bazel
@@ -1,8 +1,16 @@
load("//rust:defs.bzl", "rust_library")
+package(default_visibility = ["//test:__subpackages__"])
+
rust_library(
name = "proc_macro_dep",
srcs = ["proc_macro_dep.rs"],
edition = "2018",
- visibility = ["//test:__subpackages__"],
+)
+
+rust_library(
+ name = "proc_macro_dep_with_native_dep",
+ srcs = ["proc_macro_dep_with_native_dep.rs"],
+ edition = "2018",
+ deps = ["//test/unit/proc_macro/leaks_deps/native"],
)
diff --git a/test/unit/proc_macro/leaks_deps/proc_macro_dep/proc_macro_dep_with_native_dep.rs b/test/unit/proc_macro/leaks_deps/proc_macro_dep/proc_macro_dep_with_native_dep.rs
new file mode 100644
index 0000000..dd925eb
--- /dev/null
+++ b/test/unit/proc_macro/leaks_deps/proc_macro_dep/proc_macro_dep_with_native_dep.rs
@@ -0,0 +1,7 @@
+extern "C" {
+ pub fn forty_two_from_cc() -> i32;
+}
+
+pub fn forty_two() -> i32 {
+ unsafe { forty_two_from_cc() }
+}
diff --git a/test/unit/proc_macro/leaks_deps/proc_macro_does_not_leak_deps.bzl b/test/unit/proc_macro/leaks_deps/proc_macro_does_not_leak_deps.bzl
index 4666c6f..40c2e48 100644
--- a/test/unit/proc_macro/leaks_deps/proc_macro_does_not_leak_deps.bzl
+++ b/test/unit/proc_macro/leaks_deps/proc_macro_does_not_leak_deps.bzl
@@ -2,25 +2,32 @@
load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
load("//rust:defs.bzl", "rust_proc_macro", "rust_test")
-load(
- "//test/unit:common.bzl",
- "assert_action_mnemonic",
-)
def _proc_macro_does_not_leak_deps_impl(ctx):
env = analysistest.begin(ctx)
actions = analysistest.target_under_test(env).actions
- action = actions[0]
- assert_action_mnemonic(env, action, "Rustc")
+ rustc_action = None
+ for action in actions:
+ if action.mnemonic == "Rustc":
+ rustc_action = action
+ break
+
+ asserts.false(env, rustc_action == None)
# Our test target has a dependency on "proc_macro_dep" via a rust_proc_macro target,
# so the proc_macro_dep rlib should not appear as an input to the Rustc action, nor as -Ldependency on the command line.
- proc_macro_dep_inputs = [i for i in action.inputs.to_list() if "proc_macro_dep" in i.path]
- proc_macro_dep_args = [arg for arg in action.argv if "proc_macro_dep" in arg]
+ proc_macro_dep_inputs = [i for i in rustc_action.inputs.to_list() if "proc_macro_dep" in i.path]
+ proc_macro_dep_args = [arg for arg in rustc_action.argv if "proc_macro_dep" in arg]
asserts.equals(env, 0, len(proc_macro_dep_inputs))
asserts.equals(env, 0, len(proc_macro_dep_args))
+ # Our test target depends on proc_macro_dep:native directly, as well as transitively through the
+ # proc_macro. The proc_macro should not leak its dependency, so we should only get the "native"
+ # library once on the command line.
+ native_deps = [arg for arg in rustc_action.argv if arg.startswith("-Clink-arg=-lnative")]
+ asserts.equals(env, 1, len(native_deps))
+
return analysistest.end(env)
proc_macro_does_not_leak_deps_test = analysistest.make(_proc_macro_does_not_leak_deps_impl)
@@ -33,11 +40,27 @@
deps = ["//test/unit/proc_macro/leaks_deps/proc_macro_dep"],
)
+ rust_proc_macro(
+ name = "proc_macro_with_native_dep",
+ srcs = ["leaks_deps/proc_macro_definition_with_native_dependency.rs"],
+ edition = "2018",
+ deps = [
+ "//test/unit/proc_macro/leaks_deps/proc_macro_dep:proc_macro_dep_with_native_dep",
+ "//test/unit/proc_macro/leaks_deps/native",
+ ],
+ )
+
rust_test(
name = "deps_not_leaked",
srcs = ["leaks_deps/proc_macro_user.rs"],
edition = "2018",
- proc_macro_deps = [":proc_macro_definition"],
+ deps = [
+ "//test/unit/proc_macro/leaks_deps/native",
+ ],
+ proc_macro_deps = [
+ ":proc_macro_definition",
+ ":proc_macro_with_native_dep",
+ ],
)
proc_macro_does_not_leak_deps_test(
diff --git a/test/unit/proc_macro/leaks_deps/proc_macro_user.rs b/test/unit/proc_macro/leaks_deps/proc_macro_user.rs
index 0be3419..c038dd5 100644
--- a/test/unit/proc_macro/leaks_deps/proc_macro_user.rs
+++ b/test/unit/proc_macro/leaks_deps/proc_macro_user.rs
@@ -1,6 +1,17 @@
use proc_macro_definition::make_forty_two;
+use proc_macro_with_native_dep::make_forty_two_from_native_dep;
-#[test]
-fn test_answer_macro() {
- assert_eq!(make_forty_two!(), 42);
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_forty_two() {
+ assert_eq!(make_forty_two!(), 42);
+ }
+
+ #[test]
+ fn test_forty_two_from_native_dep() {
+ assert_eq!(make_forty_two_from_native_dep!(), 42);
+ }
}