(Big performance change) Do not run lints that cannot emit
Before this change, adding a lint was a difficult matter because it always had some overhead involved. This was because all lints would run, no matter their default level, or if the user had `#![allow]`ed them. This PR changes that. This change would improve both the Rust lint infrastructure and Clippy, but Clippy will see the most benefit, as it has about 900 registered lints (and growing!)
So yeah, with this little patch we filter all lints pre-linting, and remove any lint that is either:
- Manually `#![allow]`ed in the whole crate,
- Allowed in the command line, or
- Not manually enabled with `#[warn]` or similar, and its default level is `Allow`
As some lints **need** to run, this PR also adds **loadbearing lints**. On a lint declaration, you can use the ``@eval_always` = true` marker to label it as loadbearing. A loadbearing lint will never be filtered (it will always run)
Fixes#106983
- removed extra bits from predicates queries that are no longer needed in the new system
- removed the need for `non_erasable_generics` to take in tcx and DefId, removed unused arguments in callers
docs: Fix too_long_first_doc_paragraph: line -> paragraph
The documentation for too_long_first_doc_paragraph incorrectly says "line" where it should say "paragraph".
Fix a minor typo: doscstring -> docstring.
Also do a few tiny edits to attempt to make the wording slightly shorter and clearer.
changelog: [`too_long_first_doc_paragraph`]: Edit documentation
The documentation for too_long_first_doc_paragraph incorrectly says
"line" where it should say "paragraph".
Fix a minor typo: doscstring -> docstring.
Also do a few tiny edits to attempt to make the wording slightly
shorter and clearer.
changelog: Edit documentation for [`too_long_first_doc_paragraph`]
Add debug assertions for empty replacements and overlapping spans
rustc has debug assertions [^1] [^2] that check that a substitution doesn't have an empty suggestion string and an empty span at the same time, as well as that spans in multipart suggestions don't overlap.
However, since we link to the rustc-dev distributed compiler, these debug assertions are always disabled and so we never actually run them.
This leads to the problem that the debug ICE is not necessarily caught in the PR and only triggered in the rust repo sync, and in one of the last syncs this was a blocker and delayed the sync by several weeks because the fix was not obvious.
So this PR essentially copies the checks over and runs them in clippy debug builds as well, so that we can catch these errors in PRs directly.
-----
As for the second commit, this also *did* cause an ICE in a sync before and was fixed in the sync PR (see https://github.com/rust-lang/rust/pull/120345#issuecomment-1911005554), but it seems like that commit didn't make it back into the clippy repo (cc `@flip1995),` so the fixed code is in the rust repo but not in the clippy repo.
changelog: none
[^1]: https://doc.rust-lang.org/1.82.0/nightly-rustc/src/rustc_errors/diagnostic.rs.html#1019
[^2]: https://doc.rust-lang.org/1.82.0/nightly-rustc/src/rustc_errors/diagnostic.rs.html#932
Rollup of 4 pull requests
Successful merges:
- #126588 (Added more scenarios where comma to be removed in the function arg)
- #131728 (bootstrap: extract builder cargo to its own module)
- #131968 (Rip out old effects var handling code from traits)
- #131981 (Remove the `BoundConstness::NotConst` variant)
r? `@ghost`
`@rustbot` modify labels: rollup
The expansion of `asm!()` and `line!()` is not marked as from an expansion, in which case `SourceMap::stmt_span` returns the input span unchanged. So instead of using `stmt_span`, use `mac_call_stmt_semi_span` directly
Before this change, adding a lint was a difficult matter
because it always had some overhead involved. This was
because all lints would run, no matter their default level,
or if the user had #![allow]ed them. This PR changes that
Changelog for Clippy 1.82 ✈️
```
Roses are red,
Violets are blue,
EuroRust in Austria,
RustConf in Canada.
```
---
### The cat of this release is *Racka*:
<img height=500 src="https://github.com/user-attachments/assets/e5e3cc95-6fc3-4214-aab0-4f26e0967ae5" alt="The cats of this Clippy release" />
Cats for the next release can be nominated in the comments :D
---
changelog: none
Use correct std/core prefix in lint output
changelog: none
I was waiting for #13452 to be merged before sending this one. `std` is used instead of `core` when appropriate in messages.
Move `clippy::module_name_repetitions` to `restriction` (from `pedantic`)
Rational:
- Too pedantic IMO, I use `#[warn(pedantic)]` in my personal projects, but then always allow this lint. The fact that we had a few `#[expect(clippy::module_name_repetitions)]` also underlines this point IMO
- STD doesn't do this either. Examples:
- std::vec::Vec
- std::collections::vec_deque::VecDequeue
- #7666 commonly ignored
---
changelog: Move [`module_name_repetitions`] to `restriction` (from `pedantic`)
[#13541](https://github.com/rust-lang/rust-clippy/pull/13541)
Fix lint `manual_slice_size_calculation` when a slice is ref more than once
When a slice is ref more than once, current suggestion given by `manual_slice_size_calculation` is wrong. For example:
```rs
let s: &[i32] = &[1, 2][..];
let ss: &&[i32] = &s; // <-----
let _ = size_of::<i32>() * ss.len();
```
clippy now suggests:
```patch
- let _ = size_of::<i32>() * ss.len();
+ let _ = size_of_val(ss);
```
However, this can result in calculating the size of `&[i32]`, instead of `[i32]` (this wrong suggestion also leads to `size_of_ref` warning: https://rust-lang.github.io/rust-clippy/master/index.html#/size_of_ref )
Now I am sending this PR to fix this bug, so that clippy will suggest (some deref added):
```patch
- let _ = size_of::<i32>() * ss.len();
+ let _ = size_of_val(*ss);
```
As I am not familiar with current clippy code-base, please correct me if I am not doing well or I can do it better :)
changelog: [`manual_slice_size_calculation`]: fix a bug when a slice is ref more than once.
[`implicit_saturating_sub`] Fix suggestion with a less volatile approach
Related to #13533, such and obvious mistake got pass my watch, quite embarassing :/
Revert #13533 and implement a more robust solution.
Revert "Fix span issue on `implicit_saturating_sub`
This reverts commit 140a1275f2.
changelog: [`lint_name`]: Fix suggestion for `if {} else if {} else {}` cases
r? `@y21`
Check MethodCall/Call arg count earlier or at all
This gets rid of a bunch of possible panic spots, as well as bailing out earlier for optimisation reasons.
I started doing this because I saw that a significant amount of time was being spent in the `create_dir` restriction lint when running clippy with `perf`, but this also helps with robustness.
changelog: none
Rational:
- Too pedantic IMO, it's often better to have fine grained modules and
then rexport stuff instead of one gigantic file
- STD doesn't do this either. Examples:
- std::vec::Vec
- std::collections::vec_deque::VecDequeue
- rust-clippy#7666 commonly ignored
Improved wording of or_fun_call lint
The current wording (e.g. ``use of `ok_or` followed by a function call``) is potentially confusing (at least it confused me) by suggesting that the function that follows the (in this case) `ok_or` is the problem and not the function that is an argument to it.
The code in my program that triggered the confusing message is the following:
```rust
let file_id = buf
.lines()
.next()
.ok_or((
InternalError::ProblemReadingFromInbox,
anyhow!("No first line in inbox response ({file:?}): {buf:?}"),
))
.html_context(stream, lang)?;
```
I thought that `html_context` was the problem and that I should do something along the following lines:
```rust
let file_id = buf
.lines()
.next()
.ok_or_else(
(
InternalError::ProblemReadingFromInbox,
anyhow!("No first line in inbox response ({file:?}): {buf:?}"),
),
html_context(stream, lang),
)?
```
This is of course wrong. My confusion was only cleared up through the help message indicating what I should try instead.
If someone has a better idea of a replacement wording (currently e.g. ``` function call inside of `ok_or` ```), I'm all ears.
changelog: none
Turn declare_clippy_lint into a declarative macro
Ease of development, and hopefully compile times (the dependencies are still there because of ui-test). The procedural macro was doing just some very basic processing (like assigning a lint level to each category), so it didn't have a reason to stay IMO
changelog: None
Fix large_stack_arrays triggering when nesting const items
Fixes#13529.
r? `@flip1995`
changelog: [`large_stack_arrays`]: No longer triggers in static/const context when using nested items
Don't warn on proc macro generated code in `needless_return`
Fixes#13458Fixes#13457Fixes#13467Fixes#13479Fixes#13481Fixes#13526Fixes#13486
The fix is unfortunately a little more convoluted than just simply adding a `is_from_proc_macro`. That check *does* fix the issue, however it also introduces a bunch of false negatives in the tests, specifically when the returned expression is in a different syntax context, e.g. `return format!(..)`.
The proc macro check builds up a start and end pattern based on the HIR nodes and compares it to a snippet of the span, however that would currently fail for `return format!(..)` because we would have the patterns `("return", <something inside of the format macro>)`, which doesn't compare equal. So we now return an empty string pattern for when it's in a different syntax context.
"Hide whitespace" helps a bit for reviewing the proc macro detection change
changelog: none
Don't warn on proc macro generated code in `needless_return`
Fixes#13458Fixes#13457Fixes#13467Fixes#13479Fixes#13481Fixes#13526Fixes#13486
The fix is unfortunately a little more convoluted than just simply adding a `is_from_proc_macro`. That check *does* fix the issue, however it also introduces a bunch of false negatives in the tests, specifically when the returned expression is in a different syntax context, e.g. `return format!(..)`.
The proc macro check builds up a start and end pattern based on the HIR nodes and compares it to a snippet of the span, however that would currently fail for `return format!(..)` because we would have the patterns `("return", <something inside of the format macro>)`, which doesn't compare equal. So we now return an empty string pattern for when it's in a different syntax context.
"Hide whitespace" helps a bit for reviewing the proc macro detection change
changelog: none
Check for needless raw strings in `format_args!()` template as well
changelog: [`needless_raw_strings`, `needless_raw_string_hashes`]: check `format_args!()` template as well
Fix#13503
Show interior mutability chain in `mutable_key_type`
Fixes#10619
Just ran into this myself and I definitely agree it's not very nice to have to manually go through all the types involved to figure out why this happens and to evaluate if this is really a problem (knowing if the field of a struct is something that a hash impl relies on), so this changes the lint to emit notes for each step involved.
changelog: none
Style: do not defensively use `saturating_sub()`
Using `saturating_sub()` here in code which cannot fail brings a false sense of security. If for any reason a logic error was introduced and caused `self.loop_depth` to reach 0 before being decremented, using `saturating_sub(1)` would silently mask the programming error instead of panicking loudly as it should (at least in dev profile).
changelog: none
Using `saturating_sub()` here in code which cannot fail brings a false
sense of security. If for any reason a logic error was introduced and
caused `self.loop_depth` to reach 0 before being decremented, using
`saturating_sub(1)` would silently mask the programming error instead of
panicking loudly as it should (at least in dev profile).
Reduce default 'large array' threshold
As-is this threshold is `512kb`, but as #9449 points out this is way too high for most people to consider sensible (why would you want to copy `256kb` of data around on the stack or duplicate it via `const`) and didn't get any discussion when originally added. This PR reduces it the threshold to `1kb`, which is higher than the issue says ("a few cpu words") but helps out for actual codebases.
While reducing this, I found that `large_stack_arrays` was triggering for statically promoted arrays in constants/statics, so I also fixed that up as seen in the difference to [array_size_threshold.stderr](https://github.com/rust-lang/rust-clippy/compare/master...GnomedDev:rust-clippy:reduce-large-threshold?expand=1#diff-4c2a2a855d9ff7777f1d385be0c1bede2a3fc8aaab94837cde27a35235233fc7).
Closes#9449.
changelog: [`large_stack_arrays`]: No longer triggers in `static`/`const` context
changelog: [`large_const_arrays`]: Changed the default of [`array-size-threshold`] from `512kb` to `16kb`
Implement lint for regex::Regex compilation inside a loop
Closes#598.
Seems like a pretty simple one, I'm not sure if I sorted out all the lint plumbing correctly because I was adding it to the existing regex pass, but seems to work. The name is a bit jank and I'm super open to suggestions for changing it.
changelog: [`regex_creation_in_loops`]: Added lint for Regex compilation inside loops.
Make opaque types regular HIR nodes
Having opaque types as HIR owner introduces all sorts of complications. This PR proposes to make them regular HIR nodes instead.
I haven't gone through all the test changes yet, so there may be a few surprises.
Many thanks to `@camelid` for the first draft.
Fixes https://github.com/rust-lang/rust/issues/129023Fixes#129099Fixes#125843Fixes#119716Fixes#121422
Stabilize the `map`/`value` methods on `ControlFlow`
And fix the stability attribute on the `pub use` in `core::ops`.
libs-api in https://github.com/rust-lang/rust/issues/75744#issuecomment-2231214910 seemed reasonably happy with naming for these, so let's try for an FCP.
Summary:
```rust
impl<B, C> ControlFlow<B, C> {
pub fn break_value(self) -> Option<B>;
pub fn map_break<T>(self, f: impl FnOnce(B) -> T) -> ControlFlow<T, C>;
pub fn continue_value(self) -> Option<C>;
pub fn map_continue<T>(self, f: impl FnOnce(C) -> T) -> ControlFlow<B, T>;
}
```
Resolves#75744
``@rustbot`` label +needs-fcp +t-libs-api -t-libs
---
Aside, in case it keeps someone else from going down the same dead end: I looked at the `{break,continue}_value` methods and tried to make them `const` as part of this, but that's disallowed because of not having `const Drop`, so put it back to not even unstably-const.
Compare trait references in `trait_duplication_in_bounds` correctly
Fixes#13476Fixes#11067Fixes#9915Fixes#9626
Currently, the `trait_duplication_in_bounds` lints has a helper type for a trait reference that can be used for comparison and hashing, represented as `{trait: Res, generic_args: Vec<Res>}`. However, there are a lot of issues with this. For one, a `Res` can't represent e.g. references, slices, or lots of other types, as well as const generics and associated type equality. In those cases, the lint simply ignores them and has no way of checking if they're actually the same.
So, instead of using `Res` for this, use `SpanlessEq` and `SpanlessHash` for comparisons with the trait path for checking if there are duplicates.
However, using `SpanlessEq` as is alone lead to a false negative in the test. `std::clone::Clone` + `foo::Clone` wasn't recognized as a duplicate, because it has different segments. So this also adds a new "mode" to SpanlessEq which compares by final resolution. (I've been wondering if this can't just be the default but it's quite a large scale change as it affects a lot of lints and I haven't yet looked at all uses of it to see if there are lints that really do care about having exactly the same path segments).
Maybe an alternative would be to turn the hir types/consts into middle types/consts and compare them instead but I'm not sure there's really a good way to do that
changelog: none
Refactoring to `OpaqueTyOrigin`
Pulled out of a larger PR that uses these changes to do cross-crate encoding of opaque origin, so we can use them for edition 2024 migrations. These changes should be self-explanatory on their own, tho 😄