rust-lang / rust-clippy

A bunch of lints to catch common mistakes and improve your Rust code. Book: https://doc.rust-lang.org/clippy/
https://rust-lang.github.io/rust-clippy/
Other
11.34k stars 1.53k forks source link

Feature request: custom library-specific lints #6872

Open alice-i-cecile opened 3 years ago

alice-i-cecile commented 3 years ago

Over at Bevy we've been discussing building a linter for Bevy code bases, to catch common errors and style issues.

We'd love to be able to integrate with Clippy in some way, but obviously, almost all of these will be completely useless to Rustaceans who aren't using Bevy. Furthermore, we'd want to maintain our own lints, without bogging down the rust-clippy team directly.

What would be the best way to go about this?

llogiq commented 3 years ago

I had a discussion with the maintainer of shipyard, who asked if we could somehow change the too_many_arguments lint to avoid systems. In general we have no qualms about crate specific lints (see e.g. the regex lints).

If it helps you to get up to speed, you might want to start lints in our nursery and later move them to another project if you deem that the best course of action.

Also perhaps some of the lints you want may be generalizable. What is it that you want to have linted?

bjorn3 commented 3 years ago

From bevyengine/bevy#1602:

These are highly specific lints to bevy for which generalization doesn't make any sense.

llogiq commented 3 years ago
bjorn3 commented 3 years ago

Bevy uses it's own ECS. Systems are ordinary functions on which .system() from the IntoSystem trait is called. This would be a good entry point for Bevy.

Michael-J-Ward commented 3 years ago

A second use case that I just asked about on tracing discord would be a lint to warns you whenever a task is spawned without being instrumented.

alice-i-cecile commented 3 years ago

I've been pointed to this issue, asking about a replacement for now deprecated functionality that seems like it would have met our goals: Alternatives to rustc_plugin::registry for (Servo’s) custom lints?.

spacejam commented 3 years ago

I have a list of Rust features that I usually consider inappropriate to use in my projects due to compile time/correctness/usability hazards, but probably would be viewed as overly conservative by most clippy users. I would love to be able to ban various things using a custom lint such as:

I've recently come across the Ravenscar ADA Profile which grants significant safety properties to concurrent hard real-time systems, and I've really been jealous about how that community is able to opt into a restricted feature set to significantly reduce the cost of building safer systems.

llogiq commented 3 years ago

Most of those seem easy to implement and all of the fit nicely into our restriction lint category. The "threads spawned dynamically" lint would be quite hard, because we only perform local analysis and threads could be spawned in functions from other crates. However, we could still lint calls to std::thread::spawn if that helps. Same goes for "internal async usage"; this can be done locally, but not transitively in all dependencies.

shepmaster commented 3 years ago

I'd love to be able to create some lints for non-ideal usages of SNAFU!

we have no qualms about crate specific lints

It certainly seems odd to have those be a part of Clippy proper — will people really be happy with increased Clippy build times / size / code complexity for a crate they might never use?

I also wonder about how versioning would work: if Regex substantially changed its API, would Clippy be able to know which version(s) were in play and offer appropriate suggestions?

I guess I was thinking of some wild process where Clippy dlopens a shared library that exports some data structures (I suppose like dylint or something like inventory. Then people could have something in their Cargo.toml that lets Clippy know of these:

[package.metadata.clippy]
plugin = ["snafu-clippy"]
abonander commented 3 years ago

I recently posted a proposal for proc-macro based lints: https://internals.rust-lang.org/t/proposal-stabilizable-proc-macro-based-lints/15022/19

jhpratt commented 3 years ago

@shepmaster is already aware of this, but I plan on writing up some of my thoughts for a plugin-based lint system. I'll probably start doing this Tuesday evening and hope to have something to post on Wednesday on IRLO. It'll be a lot of work but long-term I think it will be worth it. @flip1995 has also expressed interest in helping out in this manner.

xmo-odoo commented 2 years ago

I also wonder about how versioning would work: if Regex substantially changed its API, would Clippy be able to know which version(s) were in play and offer appropriate suggestions?

Definitely a non-trivial issue, but also something which seems like it would be extremely valuable to libraries for exactly these situations: per the rustfix readme,

The magic of rustfix is entirely dependent on the diagnostics implemented in the Rust compiler (and external lints, like clippy).

I interpret this as meaning that clippy support would be necessary for libraries to be able to use rustfix for their API changes. Such a thing would make iterating on 0.x a lot easier, especially if a library gains significantly in popularity before it reaches 1.0: while 0.x is for development, having tons of users makes BC breaks more wasteful even while you're supposedly allowed to.

xFrednet commented 2 years ago

Hey everyone, in response to this, a new project was set up to implement a general stable linting interface for Rust. As part of the designing process, I would like to collect some user stories. If you have the time, it would be appreciated if you could create an issue detailing your custom lint idea: https://github.com/rust-linting/design/issues/new?assignees=&labels=A-user-story&template=user-story.md

This can be in the form of a short and simple list (like this), or a detailed lint with example code (like this). With these user stories, I'm especially interested in the role of macros when it comes to linting. Any feedback is highly appreciated :)