Factor out several utils, add `path_def_id`
changelog: none
This is generally an effort to reduce the total number of utils. `path_def_id` is added which I believe is more "cross-cutting" and also complements `path_to_local`. Best reviewed one commit at a time.
Added:
* `path_def_id`
* `path_res`
Removed:
* `is_qpath_def_path`
* `match_any_diagnostic_items`
* `expr_path_res`
* `single_segment_path`
* `differing_macro_contexts`
* `is_ty_param_lang_item`
* `is_ty_param_diagnostic_item`
* `get_qpath_generics`
Renamed:
* `path_to_res` to `def_path_res`
* `get_qpath_generic_tys` to `qpath_generic_tys`
CC `@Jarcho` since this relates to some of your work and you may have input.
warn if we find multiple clippy configs
Fixes#8323
---
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: warn if we find multiple clippy configs
Add lint `transmute_undefined_repr`
Partially implements #3999 and #546
This doesn't consider `enum`s at all right now as those are going to be a pain to deal with. This also allows `#[repr(Rust)]` structs with only one non-zero sized fields. I think those are technically undefined when transmuted.
changelog: Add lint `transmute_undefined_repr`
Add `explicit_write` suggestions for `write!`s with format args
changelog: Add [`explicit_write`] suggestions for `write!`s with format args
Fixes#4542
```rust
writeln!(std::io::stderr(), "macro arg {}", one!()).unwrap();
```
Now suggests:
```
error: use of `writeln!(stderr(), ...).unwrap()`
--> $DIR/explicit_write.rs:36:9
|
LL | writeln!(std::io::stderr(), "macro arg {}", one!()).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `eprintln!("macro arg {}", one!())`
```
---------
r? `@camsteffen` (again, sorry 😛) for the `FormatArgsExpn` change
Before this change `inputs_span` returned a span pointing to just `1` in
```rust
macro_rules! one {
() => { 1 };
}
`writeln!(std::io::stderr(), "macro arg {}", one!()).unwrap();`
```
And the `source_callsite` of that span didn't include the format string, it was just `one!()`
make unwrap_used also trigger on .get().unwrap()
fixes#8124
changelog: make the [unwrap_used] lint trigger for code of the form such as `.get(i).unwrap()` and `.get_mut(i).unwrap()`
[explicit_counter_loop] suggests `.into_iter()`, despite that triggering [into_iter_on_ref] in some cases
I have modified `fn make_iterator_snippet` in clippy_lints/src/loops/utils.rs ,so this change has some little influence on another lint [manual_flatten] .
fixes#8155
---
changelog: Fix that [`explicit_counter_loop`] suggests `into_iter()` despite that triggering [`into_iter_on_ref`] in some cases
Create `core::fmt::ArgumentV1` with generics instead of fn pointer
Split from (and prerequisite of) #90488, as this seems to have perf implication.
`@rustbot` label: +T-libs
single_match: Don't lint non-exhaustive matches; support tuples
`single_match` lint:
* Don't lint exhaustive enum patterns without a wild.
Rationale: The definition of the enum could be changed, so the user can get non-exhaustive match after applying the suggested lint (see https://github.com/rust-lang/rust-clippy/issues/8282#issuecomment-1013566068 for context).
* Lint `match` constructions with tuples (as suggested at https://github.com/rust-lang/rust-clippy/issues/8282#issuecomment-1015621148)
Closes#8282
---
changelog: [`single_match`]: Don't lint exhaustive enum patterns without a wild.
changelog: [`single_match`]: Lint `match` constructions with tuples
Fix underflow in `manual_split_once` lint
Hi, a friend found clippy started crashing on a suspiciously large allocation of `u64::MAX` memory on their code.
The mostly minimized repro is:
```rust
fn _f01(title: &str) -> Option<()> {
let _ = title[1..].splitn(2, '[').next()?;
Some(())
}
```
The underflow happens in this case on line 57 of the patch but I've changed the other substraction to saturating as well since it could potentially cause the same issue.
I'm not sure where to put a regression test, or if it's even worth for such a thing.
Aside, has it been considered before to build clippy with overflow checks enabled?
changelog: fix ICE of underflow in `manual_split_once` lint
Store a `Symbol` instead of an `Ident` in `AssocItem`
This is the same idea as #92533, but for `AssocItem` instead
of `VariantDef`/`FieldDef`.
With this change, we no longer have any uses of
`#[stable_hasher(project(...))]`
Fix `needless_borrow` causing mutable borrows to be moved
fixes#8191
changelog: Fix `needless_borrow` causing mutable borrows to be moved
changelog: Rename `ref_in_deref` to `needless_borrow`
changelog: Suggest removing the borrow on method call receivers in `needless_borrow`
Check usages in `ptr_arg`
fixes#214fixes#1981fixes#3381fixes#6406fixes#6964
This does not take into account the return type of the function currently, so `(&Vec<_>) -> &Vec<_>` functions may still be false positives.
The name given for the type also has to match the real type name, so `type Foo = Vec<u32>` won't trigger the lint, but `type Vec = Vec<u32>` will. I'm not sure if this is the best way to handle this, or if a note about the actual type should be added instead.
changelog: Check if the argument is used in a way which requires the original type in `ptr_arg`
changelog: Lint mutable references in `ptr_arg`
This commit changes the behavior of `single_match` lint.
After that, we won't lint non-exhaustive matches like this:
```rust
match Some(v) {
Some(a) => println!("${:?}", a),
None => {},
}
```
The rationale is that, because the type of `a` could be changed, so the
user can get non-exhaustive match after applying the suggested lint (see
https://github.com/rust-lang/rust-clippy/issues/8282#issuecomment-1013566068
for context).
We also will lint `match` constructions with tuples. When we see the
tuples on the both arms, we will check them both at the same time, and
if they form exhaustive match, we could display the warning.
Closes#8282
This is the same idea as #92533, but for `AssocItem` instead
of `VariantDef`/`FieldDef`.
With this change, we no longer have any uses of
`#[stable_hasher(project(...))]`
Add `msrv` config for `map_clone`
Just a small PR to have some fun with Clippy and to clear my head a bit 😅
---
changelog: [`map_clone`]: The suggestion takes `msrv` into account
changelog: Track `msrv` attribute for `manual_bits` and `borrow_as_prt`
fixes: #8276
Out of cycle Clippy update
I want to do an out-of-cycle sync for rust-lang/rust-clippy#8295, and possibly backport this to stable together with https://github.com/rust-lang/rust/issues/92938. If this doesn't get backported to stable, then I at least want to backport it to beta.
r? `@Manishearth`
fix op_ref false positive
fixes#7572
changelog: `op_ref` don't lint for unnecessary reference in BinOp impl if removing the reference will lead to unconditional recursion
Replace use of `ty()` on term and use it in more places. This will allow more flexibility in the
future, but slightly worried it allows items which are consts which only accept types.
ProjectionPredicate should be able to handle both associated types and consts so this adds the
first step of that. It mainly just pipes types all the way down, not entirely sure how to handle
consts, but hopefully that'll come with time.
Replace `NestedVisitorMap` with generic `NestedFilter`
This is an attempt to make the `intravisit::Visitor` API simpler and "more const" with regard to nested visiting.
With this change, `intravisit::Visitor` does not visit nested things by default, unless you specify `type NestedFilter = nested_filter::OnlyBodies` (or `All`). `nested_visit_map` returns `Self::Map` instead of `NestedVisitorMap<Self::Map>`. It panics by default (unreachable if `type NestedFilter` is omitted).
One somewhat trixty thing here is that `nested_filter::{OnlyBodies, All}` live in `rustc_middle` so that they may have `type Map = map::Map` and so that `impl Visitor`s never need to specify `type Map` - it has a default of `Self::NestedFilter::Map`.
issue #8239: Printed hint for lint or_fun_call is cropped and does no…
fixesrust-lang/rust-clippy#8239
changelog: [`or_fun_call`]: if suggestion contains more lines than MAX_SUGGESTION_HIGHLIGHT_LINES it is stripped to one line
Remove deprecated LLVM-style inline assembly
The `llvm_asm!` was deprecated back in #87590 1.56.0, with intention to remove
it once `asm!` was stabilized, which already happened in #91728 1.59.0. Now it
is time to remove `llvm_asm!` to avoid continued maintenance cost.
Closes#70173.
Closes#92794.
Closes#87612.
Closes#82065.
cc `@rust-lang/wg-inline-asm`
r? `@Amanieu`
Handle implicit named arguments in `useless_format`
fixes#8290
Ideally this would fix the macro parsing code to handle this, but this is a smaller change and easier to back port.
changelog: Handle implicit named arguments in `useless_format`
* Track the argument when used to initialize simple `let` bindings
* Check if the argument is passed to a function requiring the original type
* Use `multipart_suggestion` rather than multiple suggestions
* Check if the name given in the source code matches the name of the actual type
`manual_memcpy` fix
fixes#8160
Ideally this would work with `VecDeque`, but the current interface is unsuitable for it. At a minimum something like `range_as_slices` would be needed.
changelog: Don't lint `manual_memcpy` on `VecDeque`
changelog: Suggest `copy_from_slice` for `manual_memcpy` when applicable
Improve documentation for `borrowed-box` lint
fixes#8161
Updates documentation to elaborate more on how removing Box from a function parameter can generalize the function.
changelog: none
The field is also renamed from `ident` to `name. In most cases,
we don't actually need the `Span`. A new `ident` method is added
to `VariantDef` and `FieldDef`, which constructs the full `Ident`
using `tcx.def_ident_span()`. This method is used in the cases
where we actually need an `Ident`.
This makes incremental compilation properly track changes
to the `Span`, without all of the invalidations caused by storing
a `Span` directly via an `Ident`.
Downgrade mutex_atomic to nursery
See #1516 and #4295.
There are suggestions about removing this lint from the default warned lints in both issues.
Also, [`mutex_integer`](https://rust-lang.github.io/rust-clippy/master/index.html#mutex_integer) lint that has the same problems as this lint is in `nursery` group.
changelog: Moved [`mutex_atomic`] to `nursery`
new lint: `single_char_lifetime_names`
This pull request adds a lint against single character lifetime names, as they might not divulge enough information about the purpose of the lifetime. This can make code harder to understand. I placed this in `restriction` rather than `pedantic` (as suggested in #8233) since most of the Rust ecosystem already uses single character lifetime names (to my knowledge, at least) and since single character lifetime names aren't incorrect. I'd be happy to change this upon request, however. Fixes#8233.
- [x] Followed lint naming conventions
- [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`
changelog: new lint: [`single_char_lifetime_names`]
This pull request adds a lint against single character lifetime names, as they might not divulge enough information about the purpose of the lifetime. This can make code harder to understand. I placed this in `restriction` rather than `pedantic` (as suggested in #8233) since most of the Rust ecosystem already uses single character lifetime names (to my knowledge, at least) and since single character lifetime names aren't incorrect. I'd be happy to change this upon request, however. Fixes#8233.
- [x] Followed lint naming conventions
- [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`
changelog: new lint: [`single_char_lifetime_names`]
Change `unnecessary_to_owned` `into_iter` suggestions to `MaybeIncorrect`
I am having a hard time finding a good solution for #8148, so I am wondering if is enough to just change the suggestion's applicability to `MaybeIncorrect`?
I apologize, as I realize this is a bit of a cop out.
changelog: none
Better detect when a field can be moved from in `while_let_on_iterator`
fixes#8113
changelog: Better detect when a field can be moved from in `while_let_on_iterator`
Fix `type_repetition_in_bounds`
fixes#7360fixes#8162fixes#8056
changelog: Check for full equality in `type_repetition_in_bounds` rather than just equal hashes
Remove in_macro from clippy_utils
changelog: none
Previously done in #7897 but reverted in #8170. I'd like to keep `in_macro` out of utils because if a span is from expansion in any way (desugaring or macro), we should not proceed without understanding the nature of the expansion IMO.
r? `@llogiq`
changelog: none
Sorry, this is a big one. A lot of interrelated changes and I wanted to put the new utils to use to make sure they are somewhat battle-tested. We may want to divide some of the lint-specific refactoring commits into batches for smaller reviewing tasks. I could also split into more PRs.
Introduces a bunch of new utils at `clippy_utils::macros::...`. Please read through the docs and give any feedback! I'm happy to introduce `MacroCall` and various functions to retrieve an instance. It feels like the missing puzzle piece. I'm also introducing `ExpnId` from rustc as "useful for Clippy too". `@rust-lang/clippy`
Fixes#7843 by not parsing every node of macro implementations, at least the major offenders.
I probably want to get rid of `is_expn_of` at some point.
wrong_self_convention: Match `SelfKind::No` more restrictively
The `wrong_self_convention` lint uses a `SelfKind` type to decide
whether a method has the right kind of "self" for its name, or whether
the kind of "self" it has makes its name confusable for a method in
a common trait. One possibility is `SelfKind::No`, which is supposed
to mean "No `self`".
Previously, SelfKind::No matched everything _except_ Self, including
references to Self. This patch changes it to match Self, &Self, &mut
Self, Box<Self>, and so on.
For example, this kind of method was allowed before:
```
impl S {
// Should trigger the lint, because
// "methods called `is_*` usually take `self` by reference or no `self`"
fn is_foo(&mut self) -> bool { todo!() }
}
```
But since SelfKind::No matched "&mut self", no lint was triggered
(see #8142).
With this patch, the code above now gives a lint as expected.
fixes#8142
changelog: [`wrong_self_convention`] rejects `self` references in more cases
Inspired by a discussion in rust-lang/rust-clippy#8197
---
r? `@llogiq`
changelog: none
The lint is this on nightly, therefore no changelog entry for you xD
The `wrong_self_convention` lint uses a `SelfKind` type to decide
whether a method has the right kind of "self" for its name, or whether
the kind of "self" it has makes its name confusable for a method in
a common trait. One possibility is `SelfKind::No`, which is supposed
to mean "No `self`".
Previously, SelfKind::No matched everything _except_ Self, including
references to Self. This patch changes it to match Self, &Self, &mut
Self, Box<Self>, and so on.
For example, this kind of method was allowed before:
```
impl S {
// Should trigger the lint, because
// "methods called `is_*` usually take `self` by reference or no `self`"
fn is_foo(&mut self) -> bool { todo!() }
}
```
But since SelfKind::No matched "&mut self", no lint was triggered
(see #8142).
With this patch, the code above now gives a lint as expected.
Fixes#8142
changelog: [`wrong_self_convention`] rejects `self` references in more cases
This improves the quality of the genrated output and makes it
more in line with other lint messages.
changelog: [`unused_io_amount`]: Improve help text
Clippy helpfully warns about code like this, telling you that you
probably meant "write_all":
fn say_hi<W:Write>(w: &mut W) {
w.write(b"hello").unwrap();
}
This patch attempts to extend the lint so it also covers this
case:
async fn say_hi<W:AsyncWrite>(w: &mut W) {
w.write(b"hello").await.unwrap();
}
(I've run into this second case several times in my own programming,
and so have my coworkers, so unless we're especially accident-prone
in this area, it's probably worth addressing?)
This patch covers the Async{Read,Write}Ext traits in futures-rs,
and in tokio, since both are quite widely used.
changelog: [`unused_io_amount`] now supports AsyncReadExt and AsyncWriteExt.
Limit the ``[`identity_op`]`` lint to integral operands.
changelog: limit ``[`identity_op`]`` to integral operands
In the ``[`identity_op`]`` lint, if the operands are non-integers, then the lint is likely
wrong.
Fixed issues with to_radians and to_degrees lints
fixes#7651
I fixed the original problem as described in the issue, but the bug remains for complex expressions (the commented out TC I added is an example). I would also love some feedback on how to cleanup my code and reduce duplication. I hope it's not a problem that the issue has been claimed by someone else - that was over two months ago.
changelog: ``[`suboptimal_flops`]`` no longer proposes broken code with `to_radians` and `to_degrees`
Fix `enum_variants` FP on prefixes that are not camel-case
closes#8090
Fix FP on `enum_variants` when prefixes are only a substring of a camel-case word. Also adds some util helpers on `str_utils` to help parsing camel-case strings.
This changes how the lint behaves:
1. previously if the Prefix is only a length of 1, it's going to get ignored, i.e. these were previously ignored and now is warned
```rust
enum Foo {
cFoo,
cBar,
cBaz,
}
enum Something {
CCall,
CCreate,
CCryogenize,
}
```
2. non-ascii characters that doesn't have casing will not be split,
```rust
enum NonCaps {
PrefixXXX,
PrefixTea,
PrefixCake,
}
```
will be considered as `PrefixXXX`, `Prefix`, `Prefix`, so this won't lint as opposed to fired previously.
changelog: [`enum_variant_names`] Fix FP when first prefix are only a substring of a camel-case word.
---
(Edited by `@xFrednet` removed some non ascii characters)
closes#8177
previously, `needless_return` suggests an empty block `{}` to replace void `return` on match arms, this PR improve the suggestion by suggesting a unit instead.
changelog: `needless_return` suggests `()` instead of `{}` on match arms
`enum_variant_names` will consider characters with no case to be a part
of prefixes/suffixes substring that are compared. This means `Foo1` and
`Foo2` has different prefixes (`Foo1` and `Foo2` prefix respeectively).
This applies to all non-ascii characters with no casing.
fix an ICE on unwrapping a None
This very likely fixes#8166 though I wasn't able to meaningfully reduce a test case. This line is the only call to `unwrap` within that function, which was the one in the stack trace that triggered the ICE, so I think we'll be OK.
`@hackmad` can you pull and build this branch and check if it indeed fixes your problem?
---
changelog: Fixed ICE in [`unnecessary_cast`]