Compare empty blocks for equality based on tokens
fixes: #1390
This only considers empty blocks for now, though we should also catch something like this:
```rust
match 0 {
0 => {
do_something();
trace!(0);
0
}
1 => {
do_something();
trace!(1);
1
}
x => x,
}
```
As far as I can tell there aren't any negative effects on other lints. These blocks only happen to be the same for a given compilation, not all compilations.
changelog: Fix `match_on_same_arms` and others. Only consider empty blocks equal if the tokens contained are the same.
Fix `manual_map` false positives
fixes: #6795fixes: #6797fixes: #6811fixes: #6819
changelog: Fix false positives for `manual_map` when `return`, `break`, `continue`, `yield`, `await`, and partially moved values are used.
changelog: Don't expand macros in suggestions for `manual_map`
Fix false positive for unit_arg lint
Fixes#6447
To avoid false positives don't complain about unit args when they come from a path expression, e.g. a local variable.
**Note:** This is my first contribution to Clippy, so I might have messed up somewhere. Any feedback is welcome and I'm happy to work out any kinks.
---
changelog: Do not lint unit arguments when they come from a path expression.
or_fun_call: fix suggestion for `or_insert(vec![])`
fixes#6748
changelog: or_fun_call: fix suggestion for `or_insert(vec![])` on `std::collections::hash_map::Entry` or `std::collections::btree_map::Entry`
Applies for `std::collections::hash_map::Entry` and `std::collections::btree_map::Entry`
Example:
Previously, for the following code:
`let _ = hash_map.entry("test".to_owned()).or_insert(vec![]);`
clippy would suggest to use:
`or_insert_with(vec![])`, which causes a compiler error (E0277).
Now clippy suggests:
`or_insert_with(Vec::new)`
move upper_case_acronyms back to style, but make the default behaviour less aggressive by default (can be unleashed via config option)
Previous discussion in the bi-weekly clippy meeting for reference: https://rust-lang.zulipchat.com/#narrow/stream/257328-clippy/topic/Meeting.202021-02-23/near/227458019
Move the `upper_case_acronyms` lint back to the style group.
Only warn on fully-capitalized names by default.
Add add a clippy-config option `upper-case-acronyms-aggressive: true/false` to enabled more aggressive linting on
all substrings that could be capitalized acronyms.
---
changelog: reenable upper_case_acronyms by default but make the more aggressive linting opt-in via config option
Inconsistent struct constructor
fixes: #6352
r? `@matthiaskrgr`
I added the lint that checks for the struct constructors where the order of the field init shorthands is inconsistent with that in the struct definition.
changelog: Add style lint: `inconsistent_struct_constructor`
Fix FP in inherent_to_string when the function has generic parameters
Minimal example of the false positive:
````
struct G;
impl G {
fn to_string<const _N: usize>(&self) -> String {
"G.to_string()".to_string()
}
}
fn main() {
let g = G;
g.to_string::<1>();
}
````
Clippy emits an `inherent_to_string` warning, and suggests that we implement `Display` for `G` instead. However, this is not possible, since the generic parameter _N only exists in this function, not in `G` itself. This particular example uses const generics, which is where the issue is most likely to come up, but this PR skips the lint if the `to_string` function has any kind of generic parameters.
changelog: Fix FP in `inherent_to_string`
Teach SpanlessEq binding IDs
changelog: Fix collapsible_match false positive
Fixes#6740
This PR changes the way `SpanlessEq` determines whether two local variables are the same. Instead of checking that the names match, it checks that the `HirId`s match. If local bindings are declared within the expressions that are being compared, `SpanlessEq` will remember bindings that correspond to each other in a `FxHashMap<HirId, HirId>`. This makes `SpanlessEq` more flexible while also fixing false positives.
Example: `{ let x = 1; x + 2 }` is equal to `{ let y = 1; y + 2 }`.
CC `@xFrednet` I think this will resolve some concerns in #6463
Add the from_str_radix_10 lint
changelog: added the new `from_str_radix_10` which sometimes replaces calls to `primitive::from_str_radix` to `str::parse`
This is ready to be merged, although maybe the category should be `pedantic` instead of `style`? I'm not sure where it fits better.
Closes#6713.
Fix for issue 6640
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: unnecessary_wraps will now suggest to remove unnecessary wrapped return unit type, like Option<()>
fixes#6640
New lint: default_numeric_fallback
fixes#6064
r? `@flip1995`
As we discussed in [here](https://rust-lang.zulipchat.com/#narrow/stream/257328-clippy/topic/Issue.20.236064/near/224647188) and [here](https://rust-lang.zulipchat.com/#narrow/stream/257328-clippy/topic/Issue.20clippy.236064/near/224746333), I start implementing this lint from the strictest version.
In this PR, I'll allow the below two cases to pass the lint to reduce FPs.
1. Appearances of unsuffixed numeric literals in `Local` if `Local` has a type annotation, for example:
```rust
// Good.
let x: i32 = 1;
// Also good.
let x: (i32, i32) = if cond {
(1, 2)
} else {
(2, 3)
};
```
2. Appearances of unsuffixed numeric literals in args of `Call` or `MethodCall` if corresponding arguments of their signature have concrete types, for example:
```rust
fn foo_mono(x: i32) -> i32 {
x
}
fn foo_poly<T>(t: T) -> t {
t
}
// Good.
let x = foo_mono(13);
// Still bad.
let x: i32 = foo_poly(13);
```
changelog: Added restriction lint: `default_numeric_fallback`
Do not lint when the closure is called using an iterator
Fix FP when the closure is used in an iterator for `blocks_in_if_conditions` lint
FIxes: #1141
changelog: none
Rework use_self impl based on ty::Ty comparison #3410 | Take 2
This builds on top of #5531
I already reviewed and approved the commits by `@montrivo.` So only the review of my commits should be necessary.
I would also appreciate your review `@montrivo,` since you are familiar with the challenges here.
Fixes#3410 and Fixes#4143 (same problem)
Fixes#2843Fixes#3859Fixes#4734 and fixes#6221Fixes#4305Fixes#5078 (even at expression level now 🎉)
Fixes#3881 and Fixes#4887 (same problem)
Fixes#3909
Not yet: #4140 (test added)
All the credit for the fixes goes to `@montrivo.` I only refactored and copy and pasted his code.
changelog: rewrite [`use_self`] lint and fix multiple (8) FPs. One to go.
Fix suggestions that need parens in `from_iter_instead_of_collect` lint
Fixes broken suggestions that need parens (i.e.: range)
Fixes: #6648
changelog: none
This renames the variants in HIR UnOp from
enum UnOp {
UnDeref,
UnNot,
UnNeg,
}
to
enum UnOp {
Deref,
Not,
Neg,
}
Motivations:
- This is more consistent with the rest of the code base where most enum
variants don't have a prefix.
- These variants are never used without the `UnOp` prefix so the extra
`Un` prefix doesn't help with readability. E.g. we don't have any
`UnDeref`s in the code, we only have `UnOp::UnDeref`.
- MIR `UnOp` type variants don't have a prefix so this is more
consistent with MIR types.
- "un" prefix reads like "inverse" or "reverse", so as a beginner in
rustc code base when I see "UnDeref" what comes to my mind is
something like "&*" instead of just "*".
Add new lint `filter_map_identity`
<!--
Thank you for making Clippy better!
We're collecting our changelog from pull request descriptions.
If your PR only includes internal changes, you can just write
`changelog: none`. Otherwise, please write a short comment
explaining your change.
If your PR fixes an issue, you can add "fixes #issue_number" into this
PR description. This way the issue will be automatically closed when
your PR is merged.
If you added a new lint, here's a checklist for things that will be
checked during review or continuous integration.
- \[x] Followed [lint naming conventions][lint_naming]
- \[x] Added passing UI tests (including committed `.stderr` file)
- \[x] `cargo test` passes locally
- \[x] Executed `cargo dev update_lints`
- \[x] Added lint documentation
- \[x] Run `cargo dev fmt`
[lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
Note that you can skip the above if you are just opening a WIP PR in
order to get feedback.
Delete this line and everything above before opening your PR.
-->
This commit adds a new lint named filter_map_identity.
This lint is the same as `flat_map_identity` except that it checks for the usage of `filter_map`.
---
Closes#6643
changelog: Added a new lint: `filter_map_identity`
Adds a new lint that checks if there is a semicolon on the last block statement if it returns nothing
changelog: Added a new lint: `SEMICOLON_IF_NOTHING_RETURNED`
fixes#6467
Adds the `SEMICOLON_IF_NOTHING_RETURNED` lint and therefore closes#6467.
This commit adds a new lint named `filter_map_identity`. This lint is
the same as `flat_map_identity` except that it checks for `filter_map`.
Closes#6643
New Lint: Manual Flatten
This is a draft PR for [Issue 6564](https://github.com/rust-lang/rust-clippy/issues/6564).
r? `@camsteffen`
- \[x] Followed [lint naming conventions][lint_naming]
- \[x] Added passing UI tests (including committed `.stderr` file)
- \[x] `cargo test` passes locally
- \[x] Executed `cargo dev update_lints`
- \[x] Added lint documentation
- \[x] Run `cargo dev fmt`
---
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: Add new lint [`manual_flatten`] to check for loops over a single `if let` expression with `Result` or `Option`.
Fix file names of flat_map_identity test
This patch fixes the file names of the `flat_map_identity` test.
Previously, their names were started with `unnecessary_flat_map` even though the lint rule name is `flat_map_identity`. This inconsistency happened probably because the rule name was changed during the discussion in the PR where this rule was introduced.
ref: https://github.com/rust-lang/rust-clippy/pull/4231
changelog: none
This commit fixes the file names of the `flat_map_identity` test.
Previously, their names were started with `unnecessary_flat_map` even
though the lint rule name is `flat_map_identity`. This inconsistency
happened probably because the rule name was changed during the
discussion in the PR where this rule was introduced.
ref: https://github.com/rust-lang/rust-clippy/pull/4231
Fix let_and_return false positive
The issue:
See this Rust playground link: https://play.rust-lang.org/?edition=2018&gist=12cb5d1e7527f8c37743b87fc4a53748
Run the above with clippy to see the following warning:
```
warning: returning the result of a `let` binding from a block
--> src/main.rs:24:5
|
23 | let value = Foo::new(&x).value();
| --------------------------------- unnecessary `let` binding
24 | value
| ^^^^^
|
= note: `#[warn(clippy::let_and_return)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return
help: return the expression directly
|
23 |
24 | Foo::new(&x).value()
|
```
Implementing the suggested fix, removing the temporary let binding,
yields a compiler error:
```
error[E0597]: `x` does not live long enough
--> src/main.rs:23:14
|
23 | Foo::new(&x).value()
| ---------^^-
| | |
| | borrowed value does not live long enough
| a temporary with access to the borrow is created here ...
24 | }
| -
| |
| `x` dropped here while still borrowed
| ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `Foo`
|
= note: the temporary is part of an expression at the end of a block;
consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block
|
23 | let x = Foo::new(&x).value(); x
| ^^^^^^^ ^^^
```
The fix:
Of course, clippy looks like it should already handle this edge case;
however, it appears `utils::fn_def_id` is not returning a `DefId` for
`Foo::new`. Changing the `qpath_res` lookup to use the child Path
`hir_id` instead of the parent Call `hir_id` fixes the issue.
changelog: none
Implement Rust 2021 panic
This implements the Rust 2021 versions of `panic!()`. See https://github.com/rust-lang/rust/issues/80162 and https://github.com/rust-lang/rfcs/pull/3007.
It does so by replacing `{std, core}::panic!()` by a bulitin macro that expands to either `$crate::panic::panic_2015!(..)` or `$crate::panic::panic_2021!(..)` depending on the edition of the caller.
This does not yet make std's panic an alias for core's panic on Rust 2021 as the RFC proposes. That will be a separate change: c5273bdfb2 That change is blocked on figuring out what to do with https://github.com/rust-lang/rust/issues/80846 first.
Do not lint when range is completely included into another one
This fix has been developed following this [comment](https://github.com/rust-lang/rust-clippy/issues/5986#issuecomment-703313548).
So this will be linted:
```
|----------|
|-----------|
```
Now this won't be linted:
```
|---|
|--------------------|
```
and this will still lint:
```
|--------|
|--------------|
```
Fixes: #5986
changelog: Fix FPs in match_overlapping_arm, when first arm is completely included in second arm
The issue:
See this Rust playground link: https://play.rust-lang.org/?edition=2018&gist=12cb5d1e7527f8c37743b87fc4a53748
Run the above with clippy to see the following warning:
```
warning: returning the result of a `let` binding from a block
--> src/main.rs:24:5
|
23 | let value = Foo::new(&x).value();
| --------------------------------- unnecessary `let` binding
24 | value
| ^^^^^
|
= note: `#[warn(clippy::let_and_return)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return
help: return the expression directly
|
23 |
24 | Foo::new(&x).value()
|
```
Implementing the suggested fix, removing the temporary let binding,
yields a compiler error:
```
error[E0597]: `x` does not live long enough
--> src/main.rs:23:14
|
23 | Foo::new(&x).value()
| ---------^^-
| | |
| | borrowed value does not live long enough
| a temporary with access to the borrow is created here ...
24 | }
| -
| |
| `x` dropped here while still borrowed
| ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `Foo`
|
= note: the temporary is part of an expression at the end of a block;
consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block
|
23 | let x = Foo::new(&x).value(); x
| ^^^^^^^ ^^^
```
The fix:
Of course, clippy looks like it should already handle this edge case;
however, it appears `utils::fn_def_id` is not returning a `DefId` for
`Foo::new`. Changing the `qpath_res` lookup to use the child Path
`hir_id` instead of the parent Call `hir_id` fixes the issue.
Similar names ignore underscore prefixed names
changelog: Ignore underscore-prefixed names for similar_names
IMO, this lint is not very helpful for underscore-prefixed variables. Usually they are unused or are just there to ignore part of a destructuring.
Fix formatting for removed lints
- Don't add backticks for the reason a lint was removed. This is almost
never a code block, and when it is the backticks should be in the reason
itself.
- Don't assume clippy is the only tool that needs to be checked for
backwards compatibility
I split this out of https://github.com/rust-lang/rust/pull/80527/ because it kept causing tests to fail, and it's a good change to have anyway.
r? `@flip1995`
Doc markdown
I added "WebGL" along the lines of the existing "OpenGL" to the whitelist of `doc_markdown` as I found this to be a pretty common term.
(this is a follow-up of the now closed https://github.com/rust-lang/rust-clippy/pull/6388)
changelog: Whitelist "WebGL" in `doc_markdown`.
Fix false positive in write_literal and print_literal (numeric literals)
changelog: No longer lint numeric literals in [`write_literal`] and [`print_literal`].
Fixes#6335
It is fairly common to divide some length in bytes by the byte-size of a
single element before creating a `from_raw_parts` slice or similar
operation. This lint would erroneously disallow such expressions.
Just in case, instead of simply disabling this lint in the RHS of a
division, keep track of the inversion and enable it again on recursive
division.
An upcoming test case for new expresssion variants make the stderr file
go over 200 lines. Split this test case in two to have a clear
distinction between checking whether the lint is still applying on
all the functions with member counts as argument, versus validating
various member-count expressions that may or may not be invalid.