Skip to content

Commit 2b822a5

Browse files
committed
Refactor rustc_compile_action to return dict of provider types to providers
1 parent 94cd8d6 commit 2b822a5

File tree

8 files changed

+79
-70
lines changed

8 files changed

+79
-70
lines changed

extensions/prost/private/prost.bzl

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -125,25 +125,22 @@ def _compile_proto(
125125
return lib_rs, package_info_file
126126

127127
def _get_crate_info(providers):
128-
"""Finds the CrateInfo provider in the list of providers."""
129-
for provider in providers:
130-
if hasattr(provider, "name"):
131-
return provider
132-
fail("Couldn't find a CrateInfo in the list of providers")
128+
"""Finds the CrateInfo provider in the dict of providers."""
129+
if "crate_info" in providers:
130+
return providers["crate_info"]
131+
fail("Couldn't find a CrateInfo in the providers")
133132

134133
def _get_dep_info(providers):
135-
"""Finds the DepInfo provider in the list of providers."""
136-
for provider in providers:
137-
if hasattr(provider, "direct_crates"):
138-
return provider
139-
fail("Couldn't find a DepInfo in the list of providers")
134+
"""Finds the DepInfo provider in the dict of providers."""
135+
if "dep_info" in providers:
136+
return providers["dep_info"]
137+
fail("Couldn't find a DepInfo in the providers")
140138

141139
def _get_cc_info(providers):
142-
"""Finds the CcInfo provider in the list of providers."""
143-
for provider in providers:
144-
if hasattr(provider, "linking_context"):
145-
return provider
146-
fail("Couldn't find a CcInfo in the list of providers")
140+
"""Finds the CcInfo provider in the dict of providers."""
141+
if "CcInfo" in providers:
142+
return providers["CcInfo"]
143+
fail("Couldn't find a CcInfo in the providers")
147144

148145
def _compile_rust(
149146
*,

extensions/protobuf/proto.bzl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,10 @@ def _rust_proto_compile(protos, descriptor_sets, imports, crate_name, ctx, is_gr
246246
),
247247
output_hash = output_hash,
248248
)
249-
providers.append(OutputGroupInfo(rust_generated_srcs = srcs))
250-
return providers
249+
# Convert dict to list and add OutputGroupInfo
250+
result = list(providers.values())
251+
result.append(OutputGroupInfo(rust_generated_srcs = srcs))
252+
return result
251253

252254
def _rust_protogrpc_library_impl(ctx, is_grpc):
253255
"""Implementation of the rust_(proto|grpc)_library.

extensions/wasm_bindgen/private/wasm_bindgen_test.bzl

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -173,18 +173,21 @@ def _rust_wasm_bindgen_test_impl(ctx):
173173
# Force the use of a browser for now as there is no node integration.
174174
env["WASM_BINDGEN_USE_BROWSER"] = "1"
175175

176+
# Extract DefaultInfo and create a modified version with the wrapper as executable
177+
default_info = crate_providers["DefaultInfo"]
178+
files = default_info.files.to_list()
179+
if len(files) != 1:
180+
fail("Unexpected number of output files for `{}`: {}".format(ctx.label, files))
181+
wasm_file = files[0]
182+
env["TEST_WASM_BINARY"] = _rlocationpath(files[0], ctx.workspace_name)
183+
184+
# Build providers list from the dict, replacing DefaultInfo with our modified version
176185
providers = []
177-
178-
for prov in crate_providers:
179-
if type(prov) == "DefaultInfo":
180-
files = prov.files.to_list()
181-
if len(files) != 1:
182-
fail("Unexpected number of output files for `{}`: {}".format(ctx.label, files))
183-
wasm_file = files[0]
184-
env["TEST_WASM_BINARY"] = _rlocationpath(files[0], ctx.workspace_name)
186+
for key, prov in crate_providers.items():
187+
if key == "DefaultInfo":
185188
providers.append(DefaultInfo(
186-
files = prov.files,
187-
runfiles = prov.default_runfiles.merge(ctx.runfiles(files = [wasm_file], transitive_files = wb_toolchain.all_test_files)),
189+
files = default_info.files,
190+
runfiles = default_info.default_runfiles.merge(ctx.runfiles(files = [wasm_file], transitive_files = wb_toolchain.all_test_files)),
188191
executable = wrapper,
189192
))
190193
else:

rust/private/rust.bzl

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ def _rust_library_common(ctx, crate_type):
218218
deps = transform_deps(ctx.attr.deps)
219219
proc_macro_deps = transform_deps(ctx.attr.proc_macro_deps + get_import_macro_deps(ctx))
220220

221-
return rustc_compile_action(
221+
return list(rustc_compile_action(
222222
ctx = ctx,
223223
attr = ctx.attr,
224224
toolchain = toolchain,
@@ -246,7 +246,7 @@ def _rust_library_common(ctx, crate_type):
246246
owner = ctx.label,
247247
cfgs = _collect_cfgs(ctx, toolchain, crate_root, crate_type, crate_is_test = False),
248248
),
249-
)
249+
).values())
250250

251251
def _rust_binary_impl(ctx):
252252
"""The implementation of the `rust_binary` rule
@@ -312,16 +312,16 @@ def _rust_binary_impl(ctx):
312312
),
313313
)
314314

315-
providers.append(RunEnvironmentInfo(
315+
providers["RunEnvironmentInfo"] = RunEnvironmentInfo(
316316
environment = expand_dict_value_locations(
317317
ctx,
318318
ctx.attr.env,
319319
ctx.attr.data,
320320
{},
321321
),
322-
))
322+
)
323323

324-
return providers
324+
return list(providers.values())
325325

326326
def get_rust_test_flags(attr):
327327
"""Determine the desired rustc flags for test targets.
@@ -520,19 +520,14 @@ def _rust_test_impl(ctx):
520520
# If sharding is enabled and we're using libtest harness, wrap the test binary
521521
# with a script that handles test enumeration and shard partitioning
522522
if ctx.attr.experimental_enable_sharding and ctx.attr.use_libtest_harness:
523-
# Find DefaultInfo and CrateInfo in the providers list
524-
# DefaultInfo is first, CrateInfo follows (or TestCrateInfo for staticlib/cdylib)
525-
default_info = providers[0]
526-
default_info_index = 0
527-
528-
# Get the test binary from CrateInfo - it's the output of the compiled test
529-
crate_info_provider = None
530-
for p in providers:
531-
if hasattr(p, "output") and hasattr(p, "is_test"):
532-
crate_info_provider = p
533-
break
523+
default_info = providers["DefaultInfo"]
534524

525+
# Get the test binary from CrateInfo (or TestCrateInfo for staticlib/cdylib)
526+
crate_info_provider = providers.get("crate_info") or providers.get("test_crate_info")
535527
if crate_info_provider:
528+
# TestCrateInfo wraps the actual CrateInfo
529+
if hasattr(crate_info_provider, "crate"):
530+
crate_info_provider = crate_info_provider.crate
536531
test_binary = crate_info_provider.output
537532

538533
# Select the appropriate wrapper template based on target OS
@@ -559,7 +554,7 @@ def _rust_test_impl(ctx):
559554
)
560555

561556
# Replace DefaultInfo with wrapper as executable
562-
providers[default_info_index] = DefaultInfo(
557+
providers["DefaultInfo"] = DefaultInfo(
563558
files = default_info.files,
564559
runfiles = new_runfiles,
565560
executable = wrapper,
@@ -593,12 +588,12 @@ def _rust_test_impl(ctx):
593588
env["RUST_LLVM_PROFDATA"] = llvm_profdata_path
594589
components = "{}/{}".format(ctx.label.workspace_root, ctx.label.package).split("/")
595590
env["CARGO_MANIFEST_DIR"] = "/".join([c for c in components if c])
596-
providers.append(RunEnvironmentInfo(
591+
providers["RunEnvironmentInfo"] = RunEnvironmentInfo(
597592
environment = env,
598593
inherited_environment = ctx.attr.env_inherit,
599-
))
594+
)
600595

601-
return providers
596+
return list(providers.values())
602597

603598
def _rust_library_group_impl(ctx):
604599
dep_variant_infos = []

rust/private/rustc.bzl

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,10 +1301,14 @@ def rustc_compile_action(
13011301
include_coverage (bool, optional): Whether to generate coverage information or not.
13021302
13031303
Returns:
1304-
list: A list of the following providers:
1305-
- (CrateInfo): info for the crate we just built; same as `crate_info` parameter.
1306-
- (DepInfo): The transitive dependencies of this crate.
1307-
- (DefaultInfo): The output file for this crate, and its runfiles.
1304+
dict: A dict mapping provider types to provider instances. Keys include:
1305+
- DefaultInfo: The output file for this crate, and its runfiles.
1306+
- CrateInfo: info for the crate we just built (or TestCrateInfo for staticlib/cdylib).
1307+
- DepInfo: The transitive dependencies of this crate.
1308+
- InstrumentedFilesInfo: Coverage information (if include_coverage is True).
1309+
- CcInfo: C/C++ interop info (if applicable).
1310+
- OutputGroupInfo: Additional output groups (if any).
1311+
Callers should convert to a list via `list(providers.values())` when returning from a rule.
13081312
"""
13091313
deps = crate_info_dict.pop("deps")
13101314
proc_macro_deps = crate_info_dict.pop("proc_macro_deps")
@@ -1695,25 +1699,24 @@ def rustc_compile_action(
16951699
"metadata_files": coverage_runfiles + [executable] if executable else [],
16961700
})
16971701

1698-
providers = [
1699-
DefaultInfo(
1702+
# Use string keys for providers since provider types are not hashable in all Bazel versions
1703+
providers = {
1704+
"DefaultInfo": DefaultInfo(
17001705
# nb. This field is required for cc_library to depend on our output.
17011706
files = depset(outputs),
17021707
runfiles = runfiles,
17031708
executable = executable,
17041709
),
1705-
]
1710+
}
17061711

17071712
# When invoked by aspects (and when running `bazel coverage`), the
17081713
# baseline_coverage.dat created here will conflict with the baseline_coverage.dat of the
17091714
# underlying target, which is a build failure. So we add an option to disable it so that this
17101715
# function can be invoked from aspects for rules that have its own InstrumentedFilesInfo.
17111716
if include_coverage:
1712-
providers.append(
1713-
coverage_common.instrumented_files_info(
1714-
ctx,
1715-
**instrumented_files_kwargs
1716-
),
1717+
providers["InstrumentedFilesInfo"] = coverage_common.instrumented_files_info(
1718+
ctx,
1719+
**instrumented_files_kwargs
17171720
)
17181721

17191722
if crate_info_dict != None:
@@ -1732,11 +1735,20 @@ def rustc_compile_action(
17321735
# as such they shouldn't provide a CrateInfo. However, one may still want to
17331736
# write a rust_test for them, so we provide the CrateInfo wrapped in a provider
17341737
# that rust_test understands.
1735-
providers.extend([rust_common.test_crate_info(crate = crate_info), dep_info])
1738+
providers["test_crate_info"] = rust_common.test_crate_info(crate = crate_info)
17361739
else:
1737-
providers.extend([crate_info, dep_info])
1740+
providers["crate_info"] = crate_info
1741+
1742+
providers["dep_info"] = dep_info
17381743

1739-
providers += establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_configuration, interface_library)
1744+
cc_info_providers = establish_cc_info(ctx, attr, crate_info, toolchain, cc_toolchain, feature_configuration, interface_library)
1745+
for cc_provider in cc_info_providers:
1746+
# establish_cc_info returns CcInfo and optionally AllocatorLibrariesImplInfo
1747+
if type(cc_provider) == "CcInfo":
1748+
providers["CcInfo"] = cc_provider
1749+
else:
1750+
# AllocatorLibrariesImplInfo
1751+
providers["AllocatorLibrariesImplInfo"] = cc_provider
17401752

17411753
output_group_info = {}
17421754

@@ -1752,12 +1764,12 @@ def rustc_compile_action(
17521764
output_group_info["rustc_output"] = depset([rustc_output])
17531765

17541766
if output_group_info:
1755-
providers.append(OutputGroupInfo(**output_group_info))
1767+
providers["OutputGroupInfo"] = OutputGroupInfo(**output_group_info)
17561768

17571769
# A bit unfortunate, but sidecar the lints info so rustdoc can access the
17581770
# set of lints from the target it is documenting.
17591771
if hasattr(ctx.attr, "lint_config") and ctx.attr.lint_config:
1760-
providers.append(ctx.attr.lint_config[LintsInfo])
1772+
providers["LintsInfo"] = ctx.attr.lint_config[LintsInfo]
17611773

17621774
return providers
17631775

test/unit/consistent_crate_name/with_modified_crate_name.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def _with_modified_crate_name_impl(ctx):
3131
) for dep in ctx.attr.deps]
3232

3333
rust_lib = ctx.actions.declare_file(rust_lib_name)
34-
return rustc_compile_action(
34+
return list(rustc_compile_action(
3535
ctx = ctx,
3636
attr = ctx.attr,
3737
toolchain = toolchain,
@@ -52,7 +52,7 @@ def _with_modified_crate_name_impl(ctx):
5252
is_test = False,
5353
),
5454
output_hash = output_hash,
55-
)
55+
).values())
5656

5757
with_modified_crate_name = rule(
5858
implementation = _with_modified_crate_name_impl,

test/unit/force_all_deps_direct/generator.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def _generator_impl(ctx):
4747
) for dep in ctx.attr.deps]
4848

4949
rust_lib = ctx.actions.declare_file(rust_lib_name)
50-
return rustc_compile_action(
50+
return list(rustc_compile_action(
5151
ctx = ctx,
5252
attr = ctx.attr,
5353
toolchain = toolchain,
@@ -69,7 +69,7 @@ def _generator_impl(ctx):
6969
),
7070
output_hash = output_hash,
7171
force_all_deps_direct = True,
72-
)
72+
).values())
7373

7474
generator = rule(
7575
implementation = _generator_impl,

test/unit/pipelined_compilation/wrap.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def _wrap_impl(ctx):
5959
rust_metadata = None
6060
if ctx.attr.generate_metadata:
6161
rust_metadata = ctx.actions.declare_file(rust_metadata_name)
62-
return rustc_compile_action(
62+
return list(rustc_compile_action(
6363
ctx = ctx,
6464
attr = ctx.attr,
6565
toolchain = toolchain,
@@ -83,7 +83,7 @@ def _wrap_impl(ctx):
8383
is_test = False,
8484
),
8585
output_hash = output_hash,
86-
)
86+
).values())
8787

8888
wrap = rule(
8989
implementation = _wrap_impl,

0 commit comments

Comments
 (0)