Migrate write.rs to a late pass
changelog: Migrates write.rs from a pre expansion pass to a late pass
changelog: [`positional_named_format_parameters`] is renamed in favour of the rustc lint `named_arguments_used_positionally`
- Macros are now identified by diagnostic items, so will no longer lint user defined macros named, e.g. a custom `print!`
- `print_literal`/`write_literal` no longer lint no longer lint literals that come from macro expansions, e.g. `env!("FOO")`
- `print_with_newline`/`write_with_newline` no longer lint strings with any internal `\r` or `\n`s
~~A false negative, `print_literal`/`write_literal` don't lint format strings that produce `FormatSpec`s, e.g. ones containing pretty print/width/align specifiers~~
Suggestion changes:
- ~~`print_literal`/`write_literal` no longer have suggestions, as the spans for the `{}`s were not easily obtainable~~
- `print_with_newline`/`write_with_newline` has a better suggestion for a sole literal newline, but no longer has suggestions for len > 1 strings that end in a literal newline
- ~~`use_debug` spans are less precise, now point to the whole format string~~
The diff for write.rs is pretty unwieldy, other than for the `declare_clippy_lint!`s I think you'd be better off viewing it as a brand new file rather than looking at the diff, as it's mostly written from scratch
cc #6610, fixes#5721, fixes#7195, fixes#8615
Fix `unused_peekable` closure and `f(&mut peekable)` false positives
changelog: Fix [`unused_peekable`] false positive when peeked in a closure or called as `f(&mut peekable)`
The `return`/`break` changes aren't part of the fix, they allow an earlier return in some cases. `break` is replaced with `return` for style purposes as they do the same thing in this case
Fixes#9456Fixes#9462
Fix `range_{plus,minus}_one` bad suggestions
Fixes#9431.
The current `range_plus_one` and `range_minus_one` suggestions are completely incorrect when macros are involved.
This commit resolves this by disabling the lints for any range expression that is expanded from a macro. The reasons for this are that it is very difficult to create a correct suggestion in this case and that false negatives are less important for pedantic lints.
changelog: Fix `range_{plus,minus}_one` bad suggestions
Fixes#9431.
The current `range_plus_one` and `range_minus_one` suggestions
are completely incorrect when macros are involved.
This commit resolves this by disabling the lints for any range
expression that is expanded from a macro. The reasons for this
are that it is very difficult to create a correct suggestion in
this case and that false negatives are less important for
pedantic lints.
[Arithmetic] Consider literals
Fixes https://github.com/rust-lang/rust-clippy/issues/9307 and makes the `arithmetic` lint behave like `integer_arithmetic`.
It is worth noting that literal integers of a binary operation (`1 + 1`, `i32::MAX + 1`), **regardless if they are in a constant environment**, won't trigger the lint. Assign operations also have similar reasoning.
changelog: Consider literals in the arithmetic lint
Suggest `unwrap_or_default` when closure returns `"".to_string`
Closes https://github.com/rust-lang/rust-clippy/issues/9420
changelog: [`unwrap_or_else_default`]: suggest `unwrap_or_default()` instead of `unwrap_or_else` with a closure that returns an empty `to_string`.
`BindingAnnotation` refactor
* `ast::BindingMode` is deleted and replaced with `hir::BindingAnnotation` (which is moved to `ast`)
* `BindingAnnotation` is changed from an enum to a tuple struct e.g. `BindingAnnotation(ByRef::No, Mutability::Mut)`
* Associated constants added for convenience `BindingAnnotation::{NONE, REF, MUT, REF_MUT}`
One goal is to make it more clear that `BindingAnnotation` merely represents syntax `ref mut` and not the actual binding mode. This was especially confusing since we had `ast::BindingMode`->`hir::BindingAnnotation`->`thir::BindingMode`.
I wish there were more symmetry between `ByRef` and `Mutability` (variant) naming (maybe `Mutable::Yes`?), and I also don't love how long the name `BindingAnnotation` is, but this seems like the best compromise. Ideas welcome.
Unlike past similar work done in #6228, expand the existing `or_fun_call`
lint to detect `or_insert` calls with a `T::new()` or `T::default()`
argument, much like currently done for `unwrap_or` calls. In that case,
suggest the use of `or_default`, which is more idiomatic.
Note that even with this change, `or_insert_with(T::default)` calls
aren't detected as candidates for `or_default()`, in the same manner
that currently `unwrap_or_else(T::default)` calls aren't detected as
candidates for `unwrap_or_default()`.
Also, as a nearby cleanup, change `KNOW_TYPES` from `static` to `const`,
since as far as I understand it's preferred (should Clippy have a lint
for that?).
Fixes#3812.
fix wording for `derivable_impls`
While looking at the explanation as to why this lint was not automatically applicable, found the explanation a bit clunky grammatically.
Feel free to close if you consider the wording was correct in the first place.
changelog: none
Fixes#9351.
Note that this commit reworks that fix for #9317. The change
is to check that the type implements `AsRef<str>` before regarding
`to_string` as an equivalent of `to_owned`. This was suggested
by Jarcho in the #9317 issue comments.
The benefit of this is that it moves some complexity out of
`check_other_call_arg` and simplifies the module as a whole.
Fix `mut_mutex_lock` when Mutex is behind immutable deref
I *think* the problem here is the `if let ty::Ref(_, _, Mutability::Mut) = cx.typeck_results().expr_ty(recv).kind()` line tries to check if the `Mutex` can be mutably borrowed (there already is a test for `Arc<Mutex<_>>`), but gets bamboozled by the `&mut Arc` indirection. And I *think* checking the deref-adjustment to filter immutable-adjust (the deref through the `Arc`, starting from `&mut Arc`) is the correct fix.
Fixes#9415
changelog: Fix `mut_mutex_lock` when Mutex is behind immutable deref
Don't use `hir_ty_to_ty` in `result_large_err`
fixes#9414
This occurs starting with 2022-09-01. I checked that this does fix the ICE on rust-lang/rust@9353538. Not sure which pr caused the late-bound region to leak through `hir_ty_to_ty`.
changelog: None
Fix `suboptimal_float` not linting on `{const}.powf({const})`
There used to be an early return if the receiver was an effective const but the method was not linted, not taking into account later cases where the receiver and the arguments are both effective consts for different methods. Removed the early return.
Fixes#9402Fixes#9201
changelog: Fix `suboptimal_flops`, `imprecise_flops` not linting on `{const}.powf({const})` et al
Fix the emission order of `trait_duplication_in_bounds`
Makes the lint emit in source order rather than whatever order the hash map happens to be in. This is currently blocking the sync into rustc.
changelog: None
Fix missing parens in `suboptimal_flops` suggestion
Fixes#9391. The problem is simple enough, I didn't check if the same problem occurs elsewhere, though.
changelog: fix missing parenthesis in `suboptimal_flops` suggestion
Ignore `match_like_matches_macro` when there is comment
Closes#9164
changelog: [`match_like_matches_macro`] is ignored when there is some comment inside the match block.
Also add `span_contains_comment` util to check if given span contains comments.
Implemented `suspicious_to_owned` lint to check if `to_owned` is called on a `Cow`
changelog: Add lint ``[`suspicious_to_owned`]``
-----------------
Hi,
posting this unsolicited PR as I've been burned by this issue :)
Being unsolicited, feel free to reject it or reassign a different lint level etc.
This lint checks whether `to_owned` is called on `Cow<'_, _>`. This is done because `to_owned` is very similarly named to `into_owned`, but the effect of calling those two methods is completely different (one makes the `Cow::Borrowed` into a `Cow::Owned`, the other just clones the `Cow`). If the cow is then passed to code for which the type is not checked (e.g. generics, closures, etc.) it might slip through and if the cow data is coming from an unsafe context there is the potential for accidentally cause undefined behavior.
Even if not falling into this painful case, there's really no reason to call `to_owned` on a `Cow` other than confusing people reading the code: either `into_owned` or `clone` should be called.
Note that this overlaps perfectly with `implicit_clone` as a warning, but `implicit_clone` is classified pedantic (while the consequences for `Cow` might be of a wider blast radius than just pedantry); given the overlap, I set-up the lint so that if `suspicious_to_owned` triggers `implicit_clone` will not trigger. I'm not 100% sure this is done in the correct way (I tried to copy what other lints were doing) so please provide feedback on it if it isn't.
### Checklist
- \[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`
This is done because `to_owned` is very similarly named to `into_owned`, but the
effect of calling those two methods is completely different. This creates
confusion (stemming from the ambiguity of the 'owned' term in the context of
`Cow`s) and might not be what the writer intended.
new lint
This fixes#6576
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`
---
changelog: add [`multi_assignments`] lint
Replace `contains_ty(..)` with `Ty::contains(..)`
This removes some code we don't need and the method syntax is
also more readable IMO.
changelog: none
feat(fix): Do not lint if the target code is inside a loop
close#8753
we consider the following code.
```rust
fn main() {
let vec = vec![1];
let w: Vec<usize> = vec.iter().map(|i| i * i).collect(); // <- once.
for i in 0..2 {
let _ = w.contains(&i);
}
}
```
and the clippy will issue the following warning.
```rust
warning: avoid using `collect()` when not needed
--> src/main.rs:3:51
|
3 | let w: Vec<usize> = vec.iter().map(|i| i * i).collect();
| ^^^^^^^
...
6 | let _ = w.contains(&i);
| -------------- the iterator could be used here instead
|
= note: `#[warn(clippy::needless_collect)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_collect
help: check if the original Iterator contains an element instead of collecting then checking
|
3 ~
4 |
5 | for i in 0..2 {
6 ~ let _ = vec.iter().map(|i| i * i).any(|x| x == i);
```
Rewrite the code as indicated.
```rust
fn main() {
let vec = vec![1];
for i in 0..2 {
let _ = vec.iter().map(|i| i * i).any(|x| x == i); // <- execute `map` every loop.
}
}
```
this code is valid in the compiler, but, it is different from the code before the rewrite.
So, we should not lint, If `collect` is outside of a loop.
Thank you in advance.
---
changelog: Do not lint if the target code is inside a loop in `needless_collect`
Lint `collapsible_str_replace`
fixes#6651
```
changelog: [`collapsible_str_replace`]: create new lint `collapsible_str_replace`
```
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
- \[ ] Executed `cargo dev update_lints`
- \[x] Added lint documentation
- \[x] Run `cargo dev fmt`