Skip to content

Commit a1ade7f

Browse files
committed
Bind Dylint checks to named Rust toolchain families
Dylint requires its checked graph, lint libraries, and driver to agree on the same nightly compiler family. Model that family explicitly so rust_dylint can select an exact generated rules_rs toolchain repo rather than any registered nightly toolchain.\n\nKeep ordinary toolchain resolution unchanged when no family is requested, and make dylint_toolchain declare the matching Bazel toolchain wrapper for users.\n\nCo-authored-by: Codex <noreply@openai.com>
1 parent 7e7b596 commit a1ade7f

10 files changed

Lines changed: 210 additions & 41 deletions

docs/dylint.md

Lines changed: 13 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rs/private/dylint.bzl

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,18 @@ def _dylint_transition_impl(_settings, _attr):
4646
# its dependency metadata stays compatible with the compiler that runs the
4747
# lints. Transition only the explicit Dylint subtree; ordinary Rust builds
4848
# keep using the caller's regular toolchain selection.
49-
return {"@rules_rust//rust/toolchain/channel:channel": "nightly"}
49+
return {
50+
"@rules_rust//rust/toolchain/channel:channel": "nightly",
51+
"@rules_rs//rs/toolchains/family:family": _attr.toolchain_family,
52+
}
5053

5154
_dylint_transition = transition(
5255
implementation = _dylint_transition_impl,
5356
inputs = [],
54-
outputs = ["@rules_rust//rust/toolchain/channel:channel"],
57+
outputs = [
58+
"@rules_rust//rust/toolchain/channel:channel",
59+
"@rules_rs//rs/toolchains/family:family",
60+
],
5561
)
5662

5763
def _empty_lints_info():
@@ -154,7 +160,7 @@ def _dylint_toolchain_impl(ctx):
154160
),
155161
]
156162

157-
dylint_toolchain = rule(
163+
_dylint_toolchain = rule(
158164
implementation = _dylint_toolchain_impl,
159165
attrs = {
160166
"driver": attr.label(
@@ -167,6 +173,56 @@ dylint_toolchain = rule(
167173
doc = "Defines the host-side dylint-driver executable used by `rust_dylint`.",
168174
)
169175

176+
def dylint_toolchain(
177+
name,
178+
*,
179+
driver,
180+
toolchain_family,
181+
exec_compatible_with = [],
182+
target_compatible_with = [],
183+
visibility = None,
184+
tags = []):
185+
"""Declares one Dylint driver toolchain bound to a Rust toolchain family.
186+
187+
`toolchain_family` must match the `name` of the `toolchains.toolchain(...)`
188+
tag that provisions the nightly Rust toolchains this driver was built with.
189+
"""
190+
191+
if not toolchain_family:
192+
fail("`toolchain_family` must name the nightly rules_rs toolchain family used by this Dylint driver")
193+
194+
impl_name = name + "_impl"
195+
family_setting_name = name + "_family"
196+
197+
_dylint_toolchain(
198+
name = impl_name,
199+
driver = driver,
200+
tags = tags,
201+
visibility = ["//visibility:private"],
202+
)
203+
204+
native.config_setting(
205+
name = family_setting_name,
206+
flag_values = {
207+
"@rules_rs//rs/toolchains/family:family": toolchain_family,
208+
},
209+
visibility = ["//visibility:private"],
210+
)
211+
212+
toolchain_kwargs = dict(
213+
name = name,
214+
exec_compatible_with = exec_compatible_with,
215+
target_compatible_with = target_compatible_with,
216+
target_settings = [":" + family_setting_name],
217+
toolchain = ":" + impl_name,
218+
toolchain_type = "@rules_rs//rs/dylint:toolchain_type",
219+
tags = tags,
220+
)
221+
if visibility != None:
222+
toolchain_kwargs["visibility"] = visibility
223+
224+
native.toolchain(**toolchain_kwargs)
225+
170226
def _crate_info(target):
171227
if rust_common.crate_info in target:
172228
return target[rust_common.crate_info]
@@ -372,6 +428,10 @@ rust_dylint = rule(
372428
],
373429
aspects = [rust_dylint_aspect],
374430
),
431+
"toolchain_family": attr.string(
432+
doc = "Name of the nightly rules_rs toolchain family used for this Dylint check.",
433+
mandatory = True,
434+
),
375435
"_allowlist_function_transition": attr.label(
376436
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
377437
),

rs/private/toolchains_repository.bzl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,33 @@ load("@rules_rs//rs/toolchains:declare_rust_analyzer_toolchains.bzl", "declare_r
66
load("@rules_rs//rs/toolchains:declare_rustc_toolchains.bzl", "declare_rustc_toolchains")
77
load("@rules_rs//rs/toolchains:declare_rustfmt_toolchains.bzl", "declare_rustfmt_toolchains")
88
9+
config_setting(
10+
name = "selected_family",
11+
flag_values = {{
12+
"@rules_rs//rs/toolchains/family:family": {toolchain_family},
13+
}},
14+
)
15+
916
declare_rustc_toolchains(
1017
version = {version},
1118
edition = {edition},
1219
include_rustc_dev = {include_rustc_dev},
1320
extra_rustc_flags = {extra_rustc_flags},
1421
extra_exec_rustc_flags = {extra_exec_rustc_flags},
22+
toolchain_family_setting = ":selected_family",
1523
)
1624
1725
declare_rustfmt_toolchains(
1826
version = {version},
1927
rustfmt_version = {rustfmt_version},
2028
edition = {edition},
29+
toolchain_family_setting = ":selected_family",
2130
)
2231
2332
declare_rust_analyzer_toolchains(
2433
version = {version},
2534
rust_analyzer_version = {rust_analyzer_version},
35+
toolchain_family_setting = ":selected_family",
2636
)
2737
""".format(
2838
version = repr(rctx.attr.version),
@@ -32,6 +42,7 @@ declare_rust_analyzer_toolchains(
3242
include_rustc_dev = repr(rctx.attr.include_rustc_dev),
3343
extra_rustc_flags = repr(rctx.attr.extra_rustc_flags),
3444
extra_exec_rustc_flags = repr(rctx.attr.extra_exec_rustc_flags),
45+
toolchain_family = repr(rctx.attr.toolchain_family),
3546
),
3647
)
3748

@@ -47,5 +58,6 @@ toolchains_repository = repository_rule(
4758
"include_rustc_dev": attr.bool(),
4859
"extra_rustc_flags": attr.string_list_dict(),
4960
"extra_exec_rustc_flags": attr.string_list_dict(),
61+
"toolchain_family": attr.string(mandatory = True),
5062
},
5163
)

rs/toolchains/declare_rust_analyzer_toolchains.bzl

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def declare_rust_analyzer_toolchains(
2323
*,
2424
version,
2525
rust_analyzer_version,
26+
toolchain_family_setting = None,
2627
execs = SUPPORTED_EXEC_TRIPLES):
2728
version_key = sanitize_version(version)
2829
rust_analyzer_version_key = sanitize_version(rust_analyzer_version)
@@ -56,17 +57,38 @@ def declare_rust_analyzer_toolchains(
5657

5758
rust_analyzer_toolchain(**rust_analyzer_toolchain_kwargs)
5859

60+
target_settings = [
61+
"@rules_rust//rust/toolchain/channel:" + channel,
62+
]
63+
if toolchain_family_setting != None:
64+
target_settings.append("@rules_rs//rs/toolchains/family:unspecified")
65+
5966
native.toolchain(
6067
name = "{}_{}_rust_analyzer_{}".format(exec_triple.system, exec_triple.arch, version_key),
6168
exec_compatible_with = [
6269
"@platforms//os:" + exec_triple.system,
6370
"@platforms//cpu:" + exec_triple.arch,
6471
],
6572
target_compatible_with = [],
66-
target_settings = [
67-
"@rules_rust//rust/toolchain/channel:" + channel,
68-
],
73+
target_settings = target_settings,
6974
toolchain = rust_analyzer_toolchain_name,
7075
toolchain_type = "@rules_rust//rust/rust_analyzer:toolchain_type",
7176
visibility = ["//visibility:public"],
7277
)
78+
79+
if toolchain_family_setting != None:
80+
native.toolchain(
81+
name = "{}_{}_rust_analyzer_{}_selected_family".format(exec_triple.system, exec_triple.arch, version_key),
82+
exec_compatible_with = [
83+
"@platforms//os:" + exec_triple.system,
84+
"@platforms//cpu:" + exec_triple.arch,
85+
],
86+
target_compatible_with = [],
87+
target_settings = [
88+
"@rules_rust//rust/toolchain/channel:" + channel,
89+
toolchain_family_setting,
90+
],
91+
toolchain = rust_analyzer_toolchain_name,
92+
toolchain_type = "@rules_rust//rust/rust_analyzer:toolchain_type",
93+
visibility = ["//visibility:public"],
94+
)

rs/toolchains/declare_rustc_toolchains.bzl

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def declare_rustc_toolchains(
2323
include_rustc_dev = False,
2424
extra_rustc_flags = {},
2525
extra_exec_rustc_flags = {},
26+
toolchain_family_setting = None,
2627
execs = SUPPORTED_EXEC_TRIPLES,
2728
targets = SUPPORTED_TARGET_TRIPLES):
2829
"""Declare toolchains for all supported target platforms."""
@@ -141,6 +142,17 @@ def declare_rustc_toolchains(
141142

142143
for target_triple in targets:
143144
target_key = sanitize_triple(target_triple)
145+
bootstrapped_target_settings = [
146+
"@rules_rust//rust/private:bootstrapped",
147+
"@rules_rust//rust/toolchain/channel:" + channel,
148+
]
149+
bootstrapping_target_settings = [
150+
"@rules_rust//rust/private:bootstrapping",
151+
"@rules_rust//rust/toolchain/channel:" + channel,
152+
]
153+
if toolchain_family_setting != None:
154+
bootstrapped_target_settings.append("@rules_rs//rs/toolchains/family:unspecified")
155+
bootstrapping_target_settings.append("@rules_rs//rs/toolchains/family:unspecified")
144156

145157
native.toolchain(
146158
name = "{}_{}_to_{}_{}".format(exec_triple.system, exec_triple.arch, target_key, version_key),
@@ -149,10 +161,7 @@ def declare_rustc_toolchains(
149161
"@platforms//cpu:" + exec_triple.arch,
150162
],
151163
target_compatible_with = triple_to_constraint_set(target_triple),
152-
target_settings = [
153-
"@rules_rust//rust/private:bootstrapped",
154-
"@rules_rust//rust/toolchain/channel:" + channel,
155-
],
164+
target_settings = bootstrapped_target_settings,
156165
toolchain = rust_toolchain_name,
157166
toolchain_type = "@rules_rust//rust:toolchain_type",
158167
visibility = ["//visibility:public"],
@@ -165,11 +174,43 @@ def declare_rustc_toolchains(
165174
"@platforms//cpu:" + exec_triple.arch,
166175
],
167176
target_compatible_with = triple_to_constraint_set(target_triple),
168-
target_settings = [
169-
"@rules_rust//rust/private:bootstrapping",
170-
"@rules_rust//rust/toolchain/channel:" + channel,
171-
],
177+
target_settings = bootstrapping_target_settings,
172178
toolchain = rust_toolchain_name + "_bootstrap",
173179
toolchain_type = "@rules_rust//rust:toolchain_type",
174180
visibility = ["//visibility:public"],
175181
)
182+
183+
if toolchain_family_setting != None:
184+
native.toolchain(
185+
name = "{}_{}_to_{}_{}_selected_family".format(exec_triple.system, exec_triple.arch, target_key, version_key),
186+
exec_compatible_with = [
187+
"@platforms//os:" + exec_triple.system,
188+
"@platforms//cpu:" + exec_triple.arch,
189+
],
190+
target_compatible_with = triple_to_constraint_set(target_triple),
191+
target_settings = [
192+
"@rules_rust//rust/private:bootstrapped",
193+
"@rules_rust//rust/toolchain/channel:" + channel,
194+
toolchain_family_setting,
195+
],
196+
toolchain = rust_toolchain_name,
197+
toolchain_type = "@rules_rust//rust:toolchain_type",
198+
visibility = ["//visibility:public"],
199+
)
200+
201+
native.toolchain(
202+
name = "{}_{}_to_{}_{}_bootstrap_selected_family".format(exec_triple.system, exec_triple.arch, target_key, version_key),
203+
exec_compatible_with = [
204+
"@platforms//os:" + exec_triple.system,
205+
"@platforms//cpu:" + exec_triple.arch,
206+
],
207+
target_compatible_with = triple_to_constraint_set(target_triple),
208+
target_settings = [
209+
"@rules_rust//rust/private:bootstrapping",
210+
"@rules_rust//rust/toolchain/channel:" + channel,
211+
toolchain_family_setting,
212+
],
213+
toolchain = rust_toolchain_name + "_bootstrap",
214+
toolchain_type = "@rules_rust//rust:toolchain_type",
215+
visibility = ["//visibility:public"],
216+
)

rs/toolchains/declare_rustfmt_toolchains.bzl

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def declare_rustfmt_toolchains(
1515
version,
1616
rustfmt_version,
1717
edition,
18+
toolchain_family_setting = None,
1819
execs = SUPPORTED_EXEC_TRIPLES):
1920
version_key = sanitize_version(version)
2021
rustfmt_version_key = sanitize_version(rustfmt_version)
@@ -42,17 +43,38 @@ def declare_rustfmt_toolchains(
4243
tags = ["rust_version={}".format(version)],
4344
)
4445

46+
target_settings = [
47+
"@rules_rust//rust/toolchain/channel:" + channel,
48+
]
49+
if toolchain_family_setting != None:
50+
target_settings.append("@rules_rs//rs/toolchains/family:unspecified")
51+
4552
native.toolchain(
4653
name = "{}_{}_rustfmt_{}".format(exec_triple.system, exec_triple.arch, version_key),
4754
exec_compatible_with = [
4855
"@platforms//os:" + exec_triple.system,
4956
"@platforms//cpu:" + exec_triple.arch,
5057
],
5158
target_compatible_with = [],
52-
target_settings = [
53-
"@rules_rust//rust/toolchain/channel:" + channel,
54-
],
59+
target_settings = target_settings,
5560
toolchain = rustfmt_toolchain_name,
5661
toolchain_type = "@rules_rust//rust/rustfmt:toolchain_type",
5762
visibility = ["//visibility:public"],
5863
)
64+
65+
if toolchain_family_setting != None:
66+
native.toolchain(
67+
name = "{}_{}_rustfmt_{}_selected_family".format(exec_triple.system, exec_triple.arch, version_key),
68+
exec_compatible_with = [
69+
"@platforms//os:" + exec_triple.system,
70+
"@platforms//cpu:" + exec_triple.arch,
71+
],
72+
target_compatible_with = [],
73+
target_settings = [
74+
"@rules_rust//rust/toolchain/channel:" + channel,
75+
toolchain_family_setting,
76+
],
77+
toolchain = rustfmt_toolchain_name,
78+
toolchain_type = "@rules_rust//rust/rustfmt:toolchain_type",
79+
visibility = ["//visibility:public"],
80+
)

0 commit comments

Comments
 (0)