Skip to content

Commit a3bb997

Browse files
authored
Add require_explicit_unstable_features option (#3710)
This new flag can be used to disallow unstable features by default, with the possibility to opt back in to using them by explicitly adding `-Zallow-features=...` to `rustc_flags`.
1 parent 769b584 commit a3bb997

File tree

6 files changed

+232
-33
lines changed

6 files changed

+232
-33
lines changed

rust/private/rust.bzl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,16 @@ _common_attrs = {
753753
cfg = "exec",
754754
providers = [[CrateInfo], [CrateGroupInfo]],
755755
),
756+
"require_explicit_unstable_features": attr.int(
757+
doc = (
758+
"Whether to require all unstable features to be explicitly opted in to using " +
759+
"`-Zallow-features=...`. Possible values: [-1, 0, 1]. -1 means delegate to the " +
760+
"toolchain.require_explicit_unstable_features boolean build setting; 0 means False; " +
761+
"1 means True."
762+
),
763+
values = [-1, 0, 1],
764+
default = -1,
765+
),
756766
"rustc_env": attr.string_dict(
757767
doc = dedent("""\
758768
Dictionary of additional `"key": "value"` environment variables to set for rustc.

rust/private/rustc.bzl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,7 @@ def construct_arguments(
835835
build_metadata = False,
836836
force_depend_on_objects = False,
837837
skip_expanding_rustc_env = False,
838+
require_explicit_unstable_features = False,
838839
error_format = None):
839840
"""Builds an Args object containing common rustc flags
840841
@@ -867,6 +868,7 @@ def construct_arguments(
867868
build_metadata (bool): Generate CLI arguments for building *only* .rmeta files. This requires use_json_output.
868869
force_depend_on_objects (bool): Force using `.rlib` object files instead of metadata (`.rmeta`) files even if they are available.
869870
skip_expanding_rustc_env (bool): Whether to skip expanding CrateInfo.rustc_env_attr
871+
require_explicit_unstable_features (bool): Whether to require all unstable features to be explicitly opted in to using `-Zallow-features=...`.
870872
error_format (str, optional): Error format to pass to the `--error-format` command line argument. If set to None, uses the "_error_format" entry in `attr`.
871873
872874
Returns:
@@ -895,6 +897,9 @@ def construct_arguments(
895897

896898
process_wrapper_flags.add_all(build_flags_files, before_each = "--arg-file")
897899

900+
if require_explicit_unstable_features:
901+
process_wrapper_flags.add("--require-explicit-unstable-features", "true")
902+
898903
# Certain rust build processes expect to find files from the environment
899904
# variable `$CARGO_MANIFEST_DIR`. Examples of this include pest, tera,
900905
# asakuma.
@@ -1289,6 +1294,16 @@ def rustc_compile_action(
12891294
if experimental_use_cc_common_link:
12901295
emit = ["obj"]
12911296

1297+
# Determine whether to pass `--require-explicit-unstable-features true` to the process wrapper:
1298+
require_explicit_unstable_features = False
1299+
if hasattr(ctx.attr, "require_explicit_unstable_features"):
1300+
if ctx.attr.require_explicit_unstable_features == 0:
1301+
require_explicit_unstable_features = False
1302+
elif ctx.attr.require_explicit_unstable_features == 1:
1303+
require_explicit_unstable_features = True
1304+
elif ctx.attr.require_explicit_unstable_features == -1:
1305+
require_explicit_unstable_features = toolchain.require_explicit_unstable_features
1306+
12921307
args, env_from_args = construct_arguments(
12931308
ctx = ctx,
12941309
attr = attr,
@@ -1311,6 +1326,7 @@ def rustc_compile_action(
13111326
stamp = stamp,
13121327
use_json_output = bool(build_metadata) or bool(rustc_output) or bool(rustc_rmeta_output),
13131328
skip_expanding_rustc_env = skip_expanding_rustc_env,
1329+
require_explicit_unstable_features = require_explicit_unstable_features,
13141330
)
13151331

13161332
args_metadata = None
@@ -1337,6 +1353,7 @@ def rustc_compile_action(
13371353
stamp = stamp,
13381354
use_json_output = True,
13391355
build_metadata = True,
1356+
require_explicit_unstable_features = require_explicit_unstable_features,
13401357
)
13411358

13421359
env = dict(ctx.configuration.default_shell_env)

rust/settings/BUILD.bazel

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ load(
3131
"no_std",
3232
"pipelined_compilation",
3333
"rename_first_party_crates",
34+
"require_explicit_unstable_features",
3435
"rustc_output_diagnostics",
3536
"rustfmt_toml",
3637
"third_party_dir",
@@ -119,6 +120,8 @@ pipelined_compilation()
119120

120121
rename_first_party_crates()
121122

123+
require_explicit_unstable_features()
124+
122125
rustc_output_diagnostics()
123126

124127
rustfmt_toml()

rust/settings/settings.bzl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,19 @@ def rename_first_party_crates():
7878
build_setting_default = False,
7979
)
8080

81+
def require_explicit_unstable_features():
82+
"""A flag controlling whether unstable features should be disallowed by default
83+
84+
If true, an empty `-Zallow-features=` will be added to the rustc command line whenever no other
85+
`-Zallow-features=` is present in the rustc flags. The effect is to disallow all unstable
86+
features by default, with the possibility to explicitly re-enable them selectively using
87+
`-Zallow-features=...`.
88+
"""
89+
bool_flag(
90+
name = "require_explicit_unstable_features",
91+
build_setting_default = False,
92+
)
93+
8194
def third_party_dir():
8295
"""A flag specifying the location of vendored third-party rust crates within this \
8396
repository that must not be renamed when `rename_first_party_crates` is enabled.

rust/toolchain.bzl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,9 @@ def _generate_sysroot(
538538
def _experimental_use_cc_common_link(ctx):
539539
return ctx.attr.experimental_use_cc_common_link[BuildSettingInfo].value
540540

541+
def _require_explicit_unstable_features(ctx):
542+
return ctx.attr.require_explicit_unstable_features[BuildSettingInfo].value
543+
541544
def _expand_flags(ctx, attr_name, targets, make_variables):
542545
targets = deduplicate(targets)
543546
expanded_flags = []
@@ -753,6 +756,7 @@ def _rust_toolchain_impl(ctx):
753756
target_json = target_json,
754757
target_os = target_os,
755758
target_triple = target_triple,
759+
require_explicit_unstable_features = _require_explicit_unstable_features(ctx),
756760

757761
# Experimental and incompatible flags
758762
_rename_first_party_crates = rename_first_party_crates,
@@ -904,6 +908,13 @@ rust_toolchain = rule(
904908
"per_crate_rustc_flags": attr.string_list(
905909
doc = "Extra flags to pass to rustc in non-exec configuration",
906910
),
911+
"require_explicit_unstable_features": attr.label(
912+
default = Label(
913+
"//rust/settings:require_explicit_unstable_features",
914+
),
915+
doc = ("Label to a boolean build setting that controls whether all uses of unstable " +
916+
"Rust features must be explicitly opted in to using `-Zallow-features=...`."),
917+
),
907918
"rust_doc": attr.label(
908919
doc = "The location of the `rustdoc` binary. Can be a direct source or a filegroup containing one item.",
909920
allow_single_file = True,

0 commit comments

Comments
 (0)