Skip to content

Commit c078494

Browse files
authored
Don't leak deps from rust_proc_macro (#1206)
Don't leak deps from `rust_proc_macro`
1 parent 7c865ff commit c078494

File tree

7 files changed

+103
-2
lines changed

7 files changed

+103
-2
lines changed

rust/private/rustc.bzl

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,11 +173,22 @@ def collect_deps(
173173
dep = crate_info,
174174
))
175175

176-
transitive_crates.append(depset([crate_info], transitive = [dep_info.transitive_crates]))
176+
transitive_crates.append(
177+
depset(
178+
[crate_info],
179+
transitive = [] if "proc-macro" in [
180+
crate_info.type,
181+
crate_info.wrapped_crate_type,
182+
] else [dep_info.transitive_crates],
183+
),
184+
)
177185
transitive_crate_outputs.append(
178186
depset(
179187
[crate_info.output],
180-
transitive = [dep_info.transitive_crate_outputs],
188+
transitive = [] if "proc-macro" in [
189+
crate_info.type,
190+
crate_info.wrapped_crate_type,
191+
] else [dep_info.transitive_crate_outputs],
181192
),
182193
)
183194
transitive_noncrates.append(dep_info.transitive_noncrates)

test/unit/proc_macro/BUILD.bazel

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
1+
load(
2+
"//test/unit/proc_macro:leaks_deps/proc_macro_does_not_leak_deps.bzl",
3+
"proc_macro_does_not_leak_deps_test_suite",
4+
)
15
load(":proc_macro_test.bzl", "proc_macro_test_suite")
26

37
proc_macro_test_suite(
48
name = "proc_macro_test_suite",
59
)
10+
11+
proc_macro_does_not_leak_deps_test_suite(
12+
name = "proc_macro_does_not_leak_deps_test_suite",
13+
)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use proc_macro::TokenStream;
2+
use proc_macro_dep::forty_two;
3+
4+
#[proc_macro]
5+
pub fn make_forty_two(_item: TokenStream) -> TokenStream {
6+
forty_two().to_string().parse().unwrap()
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
load("//rust:defs.bzl", "rust_library")
2+
3+
rust_library(
4+
name = "proc_macro_dep",
5+
srcs = ["proc_macro_dep.rs"],
6+
visibility = ["//test:__subpackages__"],
7+
)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub fn forty_two() -> i32 {
2+
42
3+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
"""Unittest to verify proc-macro targets"""
2+
3+
load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
4+
load("//rust:defs.bzl", "rust_proc_macro", "rust_test")
5+
load(
6+
"//test/unit:common.bzl",
7+
"assert_action_mnemonic",
8+
)
9+
10+
def _proc_macro_does_not_leak_deps_impl(ctx):
11+
env = analysistest.begin(ctx)
12+
actions = analysistest.target_under_test(env).actions
13+
action = actions[0]
14+
assert_action_mnemonic(env, action, "Rustc")
15+
16+
# Our test target has a dependency on "proc_macro_dep" via a rust_proc_macro target,
17+
# so the proc_macro_dep rlib should not appear as an input to the Rustc action, nor as -Ldependency on the command line.
18+
proc_macro_dep_inputs = [i for i in action.inputs.to_list() if "proc_macro_dep" in i.path]
19+
proc_macro_dep_args = [arg for arg in action.argv if "proc_macro_dep" in arg]
20+
21+
asserts.equals(env, 0, len(proc_macro_dep_inputs))
22+
asserts.equals(env, 0, len(proc_macro_dep_args))
23+
24+
return analysistest.end(env)
25+
26+
proc_macro_does_not_leak_deps_test = analysistest.make(_proc_macro_does_not_leak_deps_impl)
27+
28+
def _proc_macro_does_not_leak_deps_test():
29+
rust_proc_macro(
30+
name = "proc_macro_definition",
31+
srcs = ["leaks_deps/proc_macro_definition.rs"],
32+
deps = ["//test/unit/proc_macro/leaks_deps/proc_macro_dep"],
33+
)
34+
35+
rust_test(
36+
name = "deps_not_leaked",
37+
srcs = ["leaks_deps/proc_macro_user.rs"],
38+
proc_macro_deps = [":proc_macro_definition"],
39+
)
40+
41+
proc_macro_does_not_leak_deps_test(
42+
name = "proc_macro_does_not_leak_deps_test",
43+
target_under_test = ":deps_not_leaked",
44+
)
45+
46+
def proc_macro_does_not_leak_deps_test_suite(name):
47+
"""Entry-point macro called from the BUILD file.
48+
49+
Args:
50+
name: Name of the macro.
51+
"""
52+
_proc_macro_does_not_leak_deps_test()
53+
54+
native.test_suite(
55+
name = name,
56+
tests = [
57+
":proc_macro_does_not_leak_deps_test",
58+
],
59+
)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
use proc_macro_definition::make_forty_two;
2+
3+
#[test]
4+
fn test_answer_macro() {
5+
assert_eq!(make_forty_two!(), 42);
6+
}

0 commit comments

Comments
 (0)