I have an application split into several crates. I want to deny or allow a specific lint in all crates. For example:
#![deny(clippy::print_stdout)]
It seems I have to add this to lib.rs in each of the crates.
There is an ticket with Cargo to allow configuring this somehow, but it has been open for several years with no clear conclusion.
Is there a workaround to avoid having these allow/deny/warn lines duplicated per crate?
One idea I had was to include!
the lines by creating a clippy_config.rs
at the workspace root, then in each crate's lib.rs adding
include!("../../clippy_config.rs");
However this fails with
error: an inner attribute is not permitted in this context
--> app/src/../../clippy_config.rs:1:1
|
1 | #![deny(clippy::print_stdout)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.
My other thought to use a macro also does not work for much the same reason.
Is there a simple way to do this, except writing an external script to modify the Rust files to automate the duplication? (as mentioned in this comment describing Embark Studio's setup).
Rust and Clippy lints can be configured:
#[deny(clippy::print_stdout)]
.-Dclippy::print-stdout
.The configuration in Cargo.toml
can be done in several ways.
For an individual crate, using the [lints]
section:
[lints.rust]
unsafe_code = "forbid"
[lints.clippy]
enum_glob_use = "deny"
For a workspace crate, using the [lints]
table:
[workspace]
members = [...]
[workspace.lints.rust]
unsafe_code = "forbid"
Then in each crate in the workspace which wishes to inherit:
[lints]
workspace = true
Note: when using cargo new
to create a new crate in an existing workspace, the [lints]
section is automatically added.
Attributes are best used for one-off situations. For example, I regularly use #[allow(clippy::too_many_arguments)]
on internal functions, but I wouldn't want it on public API functions.
Cargo.toml is best used for project wide settings which accommodate both the development workflow and CI. For example, I encourage the use of unsafe_ops_in_unsafe_fn = "forbid"
so each unsafe operation safety pre-conditions are clearly documented, rather than a hand-wavy "trust me".
Flags are best used for workflow specific settings. For example, I would encourage -Drust::dead-code
in CI, but it would be a pain during development.
(Also works in Rust 1.74 onwards, just possibly less convenient)
Clippy offers 3 configuration modes:
#[deny(clippy::print_stdout)]
-Dclippy::print-stdout
clippy.toml
, though restricted to a subset of configurable lints.For project-wide configuration, across crates, the configuration file is the best option if it works.
Otherwise, the second best (hacky) option is to use flags indirectly. That is, rather than specifying RUSTFLAGS=-Dclippy::print-stdout
in front of your compiler invocation, you can let Cargo do it, and configure Cargo project-wide.
At the root of your project, create a .cargo/config.toml
file with the following content:
[build]
rustflags = ["-Dclippy::print-stdout"]
Cargo will then pass this flag to clippy when it invokes it.
Note: in a workspace setting, .cargo/config.toml
in individual crate folders is ignored when invoking Cargo from the root of the workspace, so best place this in the .cargo
at the root.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With