diff --git a/BUILD b/BUILD index 4c8e8f1e47..c344205802 100644 --- a/BUILD +++ b/BUILD @@ -1,4 +1,5 @@ load("@bazel_skylib//:bzl_library.bzl", "bzl_library") +load("@io_bazel_rules_rust//rust:private/rustc.bzl", "error_format") bzl_library( name = "rules", @@ -7,3 +8,10 @@ bzl_library( ], visibility = ["//visibility:public"], ) + +# This setting may be changed from the command line to generate machine readable errors. +error_format( + name = "error_format", + build_setting_default = "human", + visibility = ["//visibility:public"], +) diff --git a/rust/private/clippy.bzl b/rust/private/clippy.bzl index f1bc6dcd3c..b61f74df15 100644 --- a/rust/private/clippy.bzl +++ b/rust/private/clippy.bzl @@ -144,6 +144,7 @@ rust_clippy_aspect = aspect( allow_single_file = True, cfg = "exec", ), + "_error_format": attr.label(default = "//:error_format"), }, toolchains = [ "@io_bazel_rules_rust//rust:toolchain", diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl index a17ab9c4e4..8b354db8e9 100644 --- a/rust/private/rust.bzl +++ b/rust/private/rust.bzl @@ -472,6 +472,7 @@ _rust_common_attrs = { allow_single_file = True, cfg = "exec", ), + "_error_format": attr.label(default = "//:error_format"), } _rust_library_attrs = { diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index ff7ca979f2..8d0817fc21 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -76,6 +76,13 @@ DepInfo = provider( }, ) +_error_format_values = ["human", "json", "short"] + +ErrorFormatInfo = provider( + doc = "Set the --error-format flag for all rustc invocations", + fields = {"error_format": "(string) [" + ", ".join(_error_format_values) + "]"}, +) + def _get_rustc_env(ctx, toolchain): """Gathers rustc environment variables @@ -471,6 +478,8 @@ def construct_arguments( args.add(crate_info.root) args.add("--crate-name=" + crate_info.name) args.add("--crate-type=" + crate_info.type) + if hasattr(ctx.attr, "_error_format"): + args.add("--error-format=" + ctx.attr._error_format[ErrorFormatInfo].error_format) # Mangle symbols to disambiguate crates with the same name extra_filename = "-" + output_hash if output_hash else "" @@ -833,3 +842,15 @@ def _get_dirname(file): str: Directory name of `file` """ return file.dirname + +def _error_format_impl(ctx): + raw = ctx.build_setting_value + if raw not in _error_format_values: + fail(str(ctx.label) + " expected a value in [" + ", ".join(_error_format_values) + + "] but got " + raw) + return ErrorFormatInfo(error_format = raw) + +error_format = rule( + implementation = _error_format_impl, + build_setting = config.string(flag = True), +)