Overview

Clippy is a tool for catching common mistakes in Rust code and improving it. An expansive list of lints and the justification can be found in their documentation.

Setup

Simply add the following to the .bazelrc file in the root of your workspace:

build --aspects=@rules_rust//rust:defs.bzl%rust_clippy_aspect
build --output_groups=+clippy_checks

This will enable clippy on all Rust targets.

Note that targets tagged with no-clippy will not perform clippy checks

To use a local clippy.toml, add the following flag to your .bazelrc. Note that due to the upstream implementation of clippy, this file must be named either .clippy.toml or clippy.toml. Using a custom config file requires Rust 1.34.0 or newer.

build --@rules_rust//rust/settings:clippy.toml=//:clippy.toml

Rules

Aspects

rust_clippy

load("@rules_rust//rust:defs.bzl", "rust_clippy")

rust_clippy(name, deps)

Executes the clippy checker on a specific target.

Similar to rust_clippy_aspect, but allows specifying a list of dependencies within the build system.

For example, given the following example targets:

load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")

rust_library(
    name = "hello_lib",
    srcs = ["src/lib.rs"],
)

rust_test(
    name = "greeting_test",
    srcs = ["tests/greeting.rs"],
    deps = [":hello_lib"],
)

Rust clippy can be set as a build target with the following:

load("@rules_rust//rust:defs.bzl", "rust_clippy")

rust_clippy(
    name = "hello_library_clippy",
    testonly = True,
    deps = [
        ":hello_lib",
        ":greeting_test",
    ],
)

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
depsRust targets to run clippy on.List of labelsoptional[]

rust_clippy_test

load("@rules_rust//rust:defs.bzl", "rust_clippy_test")

rust_clippy_test(name, platform, targets, transitive)

A test rule that runs clippy over a set of Rust targets.

By default (transitive = False), only the exact targets listed are checked. Set transitive = True to walk deps, proc_macro_deps, and crate so that listing a top-level target checks its whole crate graph.

The clippy actions run during the build phase, so a clippy failure fails bazel test before the test executable is invoked. The rule also exposes the collected markers under the clippy_checks output group, so bazel build //x:my_clippy_test --output_groups=clippy_checks drives the clippy actions without running the test.

When capture_clippy_output or clippy_output_diagnostics is set globally clippy exits 0 even on real issues; in that case the runner inspects the captured stderr / JSON diagnostics and reports the verdict.

An optional platform attribute transitions targets to the given platform before running clippy.

Example:

load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_clippy_test", "rust_library")

rust_library(
    name = "lib",
    srcs = ["src/lib.rs"],
    edition = "2021",
)

rust_binary(
    name = "app",
    srcs = ["src/main.rs"],
    edition = "2021",
    deps = [":lib"],
)

rust_clippy_test(
    name = "clippy_app_only_test",
    targets = [":app"],
)

rust_clippy_test(
    name = "clippy_tree_test",
    targets = [":app"],
    transitive = True,
)

Targets tagged no_clippy, no_lint, nolint, or noclippy are skipped.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
platformOptional platform to transition targets to before running the aspect. When set, --platforms is switched to this label for the duration of this rule's aspect actions.LabeloptionalNone
targetsRust targets to run clippy on.List of labelsoptional[]
transitiveIf True, lint targets and every crate reachable via deps, proc_macro_deps, and crate. If False, lint only the exact targets listed.BooleanoptionalFalse

rust_clippy_aspect

load("@rules_rust//rust:defs.bzl", "rust_clippy_aspect")

rust_clippy_aspect()

Executes the clippy checker on specified targets.

This aspect applies to existing rust_library, rust_test, and rust_binary rules.

As an example, if the following is defined in examples/hello_lib/BUILD.bazel:

load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")

rust_library(
    name = "hello_lib",
    srcs = ["src/lib.rs"],
)

rust_test(
    name = "greeting_test",
    srcs = ["tests/greeting.rs"],
    deps = [":hello_lib"],
)

Then the targets can be analyzed with clippy using the following command:

$ bazel build --aspects=@rules_rust//rust:defs.bzl%rust_clippy_aspect               --output_groups=clippy_checks //hello_lib:all

ASPECT ATTRIBUTES

ATTRIBUTES