diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index 982dbc273e..dc8ed83141 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -173,11 +173,22 @@ def collect_deps( dep = crate_info, )) - transitive_crates.append(depset([crate_info], transitive = [dep_info.transitive_crates])) + transitive_crates.append( + depset( + [crate_info], + transitive = [] if "proc-macro" in [ + crate_info.type, + crate_info.wrapped_crate_type, + ] else [dep_info.transitive_crates], + ), + ) transitive_crate_outputs.append( depset( [crate_info.output], - transitive = [dep_info.transitive_crate_outputs], + transitive = [] if "proc-macro" in [ + crate_info.type, + crate_info.wrapped_crate_type, + ] else [dep_info.transitive_crate_outputs], ), ) transitive_noncrates.append(dep_info.transitive_noncrates) diff --git a/test/unit/proc_macro/BUILD.bazel b/test/unit/proc_macro/BUILD.bazel index e2d56c177a..1927309a17 100644 --- a/test/unit/proc_macro/BUILD.bazel +++ b/test/unit/proc_macro/BUILD.bazel @@ -1,5 +1,13 @@ +load( + "//test/unit/proc_macro:leaks_deps/proc_macro_does_not_leak_deps.bzl", + "proc_macro_does_not_leak_deps_test_suite", +) load(":proc_macro_test.bzl", "proc_macro_test_suite") proc_macro_test_suite( name = "proc_macro_test_suite", ) + +proc_macro_does_not_leak_deps_test_suite( + name = "proc_macro_does_not_leak_deps_test_suite", +) diff --git a/test/unit/proc_macro/leaks_deps/proc_macro_definition.rs b/test/unit/proc_macro/leaks_deps/proc_macro_definition.rs new file mode 100644 index 0000000000..9fcad75d27 --- /dev/null +++ b/test/unit/proc_macro/leaks_deps/proc_macro_definition.rs @@ -0,0 +1,7 @@ +use proc_macro::TokenStream; +use proc_macro_dep::forty_two; + +#[proc_macro] +pub fn make_forty_two(_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 new file mode 100644 index 0000000000..b76d0cdca7 --- /dev/null +++ b/test/unit/proc_macro/leaks_deps/proc_macro_dep/BUILD.bazel @@ -0,0 +1,7 @@ +load("//rust:defs.bzl", "rust_library") + +rust_library( + name = "proc_macro_dep", + srcs = ["proc_macro_dep.rs"], + visibility = ["//test:__subpackages__"], +) diff --git a/test/unit/proc_macro/leaks_deps/proc_macro_dep/proc_macro_dep.rs b/test/unit/proc_macro/leaks_deps/proc_macro_dep/proc_macro_dep.rs new file mode 100644 index 0000000000..6d2a0376eb --- /dev/null +++ b/test/unit/proc_macro/leaks_deps/proc_macro_dep/proc_macro_dep.rs @@ -0,0 +1,3 @@ +pub fn forty_two() -> i32 { + 42 +} 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 new file mode 100644 index 0000000000..c2b716281c --- /dev/null +++ b/test/unit/proc_macro/leaks_deps/proc_macro_does_not_leak_deps.bzl @@ -0,0 +1,59 @@ +"""Unittest to verify proc-macro targets""" + +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") + + # 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] + + asserts.equals(env, 0, len(proc_macro_dep_inputs)) + asserts.equals(env, 0, len(proc_macro_dep_args)) + + return analysistest.end(env) + +proc_macro_does_not_leak_deps_test = analysistest.make(_proc_macro_does_not_leak_deps_impl) + +def _proc_macro_does_not_leak_deps_test(): + rust_proc_macro( + name = "proc_macro_definition", + srcs = ["leaks_deps/proc_macro_definition.rs"], + deps = ["//test/unit/proc_macro/leaks_deps/proc_macro_dep"], + ) + + rust_test( + name = "deps_not_leaked", + srcs = ["leaks_deps/proc_macro_user.rs"], + proc_macro_deps = [":proc_macro_definition"], + ) + + proc_macro_does_not_leak_deps_test( + name = "proc_macro_does_not_leak_deps_test", + target_under_test = ":deps_not_leaked", + ) + +def proc_macro_does_not_leak_deps_test_suite(name): + """Entry-point macro called from the BUILD file. + + Args: + name: Name of the macro. + """ + _proc_macro_does_not_leak_deps_test() + + native.test_suite( + name = name, + tests = [ + ":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 new file mode 100644 index 0000000000..0be3419dc8 --- /dev/null +++ b/test/unit/proc_macro/leaks_deps/proc_macro_user.rs @@ -0,0 +1,6 @@ +use proc_macro_definition::make_forty_two; + +#[test] +fn test_answer_macro() { + assert_eq!(make_forty_two!(), 42); +}