Expand internal lint `unnecessary_def_path`
This PR does essentially two things:
* Separates the internal lints into modules by pass. (`internal_lints.rs` was over 1400 lines, which is a little unruly IMHO.)
* ~Adds a new~ Expands the `unnecessary_def_path` internal lint to flag hardcoded paths to diagnostic and language items.
My understanding is that the latter is currently done by reviewers. Automating this process should make things easier for both reviewers and contributors.
I could make the first bullet a separate PR, or remove it entirely, if desired.
changelog: Add internal lint `diagnostic_item_path`
Add a suggestion and a note about orphan rules for `from_over_into`
Adds a machine applicable suggestion to convert the `Into` impl into a `From` one to `from_over_into`
Also adds a note explaining that `impl From<Local> for Foreign` is fine if the `Into` type is foreign
Closes#7444
Addresses half of #9638
changelog: [`from_over_into`] Add a suggestion and a note about orphan rules
add tests in `implicit_saturating_sub` lint
This adds more tests to the `implicit_saturating_sub` lint to rule out certain false positives that have appeared in the past.
Now with those false positives out of the equation, we can move the lint to `style`.
---
changelog: promote [`implicit-saturating-sub`] to the `style` category
Change uninlined_format_args into a style lint
As [previously discussed](https://github.com/rust-lang/rust-clippy/pull/9233#issuecomment-1256361205), the `uninlined_format_args` should probably be a part of the default style because `println!("{}", foo)` is not as concise or easy to understand as `println!("{foo}")`
changelog: [`uninlined_format_args`]: change to be the default `style`
Fix to_string_in_format_args in parens
Fix suggestions like
```
print!("error: something failed at {}", (Location::caller().to_string()));
```
where the parenthesis enclose some portion of the value.
Fixes#9540
changelog: [`to_string_in_format_args`]: fix incorrect fix when value is enclosed in parenthesis
Fix suggestions like
```
print!("error: something failed at {}", (Location::caller().to_string()));
```
where the parenthesis enclose some portion of the value.
Replace manual let else patterns with let else
Clears the codebase from places where the lint added by #8437 is firing, by adopting let else.
changelog: none
Previously the `clippy::allow_attributes_without_reason` lint would
apply to external crate macros. Many macros in the Rust ecosystem
include these `allow` attributes without adding a reason, making this
lint pretty much unusable in any sizable Rust project.
This commit fixes that by adding a check to the lint if the attribute is
from an external crate macro and returning early.
Uplift `clippy::for_loops_over_fallibles` lint into rustc
This PR, as the title suggests, uplifts [`clippy::for_loops_over_fallibles`] lint into rustc. This lint warns for code like this:
```rust
for _ in Some(1) {}
for _ in Ok::<_, ()>(1) {}
```
i.e. directly iterating over `Option` and `Result` using `for` loop.
There are a number of suggestions that this PR adds (on top of what clippy suggested):
1. If the argument (? is there a better name for that expression) of a `for` loop is a `.next()` call, then we can suggest removing it (or rather replacing with `.by_ref()` to allow iterator being used later)
```rust
for _ in iter.next() {}
// turns into
for _ in iter.by_ref() {}
```
2. (otherwise) We can suggest using `while let`, this is useful for non-iterator, iterator-like things like [async] channels
```rust
for _ in rx.recv() {}
// turns into
while let Some(_) = rx.recv() {}
```
3. If the argument type is `Result<impl IntoIterator, _>` and the body has a `Result<_, _>` type, we can suggest using `?`
```rust
for _ in f() {}
// turns into
for _ in f()? {}
```
4. To preserve the original behavior and clear intent, we can suggest using `if let`
```rust
for _ in f() {}
// turns into
if let Some(_) = f() {}
```
(P.S. `Some` and `Ok` are interchangeable depending on the type)
I still feel that the lint wording/look is somewhat off, so I'll be happy to hear suggestions (on how to improve suggestions :D)!
Resolves#99272
[`clippy::for_loops_over_fallibles`]: https://rust-lang.github.io/rust-clippy/master/index.html#for_loops_over_fallibles
rename `ImplItemKind::TyAlias` to `ImplItemKind::Type`
The naming of this variant seems inconsistent given that this is not really a "type alias", and the associated type variant for `TraitItemKind` is just called `Type`.
Further enhance `needless_borrow`, mildly refactor `redundant_clone`
This PR does the following:
* Moves some code from `redundant_clone` into a new `clippy_utils` module called `mir`, and wraps that code in a function called `dropped_without_further_use`.
* Relaxes the "is copyable" condition condition from #9136 by also suggesting to remove borrows from values dropped without further use. The changes involve the just mentioned function.
* Separates `redundant_clone` into modules.
Strictly speaking, the last bullet is independent of the others. `redundant_clone` is somewhat hairy, IMO. Separating it into modules makes it slightly less so, by helping to delineate what depends upon what.
I've tried to break everything up into digestible commits.
r? `@Jarcho`
(`@Jarcho` I hope you don't mind.)
changelog: continuation of #9136
Add `manual_filter` lint for `Option`
Share much of its implementation with `manual_map` and should greatly benefit from its previous feedback.
I'm sure it's possible to even more refactor both and would gladly take input on that as well as any clippy idiomatic usage, since this is my first lint addition.
I've added the lint to the complexity section for now, I don't know if every new lint needs to go in nursery first.
The matching could be expanded to more than `Some(<value>)` to lint on arbitrary struct matching inside the `Some` but I've left it like it was for `manual_map` for now. `needless_match::pat_same_as_expr` provides a more generic match example.
close https://github.com/rust-lang/rust-clippy/issues/8822
changelog: Add lint [`manual_filter`] for `Option`
extend `box-default` lint, add suggestion
This extends the recently added `box-default` lint to also cover `Box::new(vec![])`, `Box::new(String::from(""))` and `Box::new(Vec::from([]))`. Also the lint now suggests a suitable replacement. I did not find a simple way to check whether the type is fully determined by the outside, so I at least checked for some variations to remove the turbofish in those cases.
---
changelog: none
lint::unsafe_removed_from_name: fix false positive result when allowed
changelog: [`unsafe_removed_from_name`] Fix allowing on imports produces a false positive on `useless_attribute`.
Fixes: #9197
Signed-off-by: Andy-Python-Programmer <andypythonappdeveloper@gmail.com>
FormatArgsExpn: Find comma spans and ignore weird proc macro spans
Fixes the following cases:
A missing `, 1` from the `expect_fun_call` suggestion:
```rust
Some(()).expect(&format!("{x} {}", 1));
```
```
warning: use of `expect` followed by a function call
--> t.rs:7:14
|
7 | Some(()).expect(&format!("{x} {}", 1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("{x} {}"))`
```
The suggestion removing from the comma in the comment rather than the one after the format string:
```rust
println!(
"{}",
// a comment, with a comma in it
x
);
```
```
warning: variables can be used directly in the `format!` string
--> t.rs:9:5
|
9 | / println!(
10 | | "{}",
11 | | // a comment, with a comma in it
12 | | x
13 | | );
| |_____^
|
help: change this to
|
10 ~ "{x}",
11 ~ // a comment
|
```
It also no longer accepts expansions where a format string or argument has a "weird" proc macro span, that is one where the literal/expression it outputs has the span of one of its inputs. Kind of like a `format_args` specific `clippy_utils::is_from_proc_macro`, e.g. `format!(indoc! {" ... "})`
changelog: [`expect_fun_call`]: Fix suggestion for `format!` using captured variables
changelog: [`print_literal`], [`write_literal`], [`uninlined_format_args`]: Fix suggestion when following a comment including a comma
Fix and improve `match_type_on_diagnostic_item`
This extracts the fix for the lint out of #7647. There's still a couple of other functions to check, but at least this will get lint working again.
The two added util functions (`is_diagnostic_item` and `is_lang_item`) are needed to handle `DefId` for unit and tuple struct/variant constructors. The `rustc_diagnostic_item` and `lang` attributes are attached to the struct/variant `DefId`, but most of the time they are used through their constructors which have a different `DefId`. The two utility functions will check if the `DefId` is for a constructor and switch to the associated struct/variant `DefId`.
There does seem to be a bug on rustc's side where constructor `DefId`s from external crates seem to be returning `DefKind::Variant` instead of `DefKind::Ctor()`. There's a workaround put in right.
changelog: None
Remove unused `.fixed` files, only run asm_syntax doctests on x86
Two small changes, removes some unused `.fixed` and makes `clippy_lints` doctests pass on non x86 arches
changelog: none
* Check for `const`s and `static`s from external crates
* Check for `LangItem`s
* Handle inherent functions which have the same name as a field
* Also check the following functions:
* `match_trait_method`
* `match_def_path`
* `is_expr_path_def_path`
* `is_qpath_def_path`
* Handle checking for a constructor to a diagnostic item or `LangItem`
let unnecessary_cast work for trivial non_literal expressions
Signed-off-by: TennyZhuang <zty0826@gmail.com>
---
changelog: [`unnecessary_cast`]: fix for trivial non_literal expressions
Fixes#9562
[`unnecessary_cast`] add parenthesis when negative number uses a method
fix#9563
The issue was probably introduced by 90fe3bea52
changelog: [`unnecessary_cast`] add parenthesis when negative number uses a method
r? llogiq
use `is_integer_literal` more
I noticed that we have the `is_integer_literal` function in our `clippy_utils`, yet almost everywhere people still match int literal expressions manually. So I searched for instances to replace and shorten the code a bit.
---
changelog: none
Implement `manual_clamp` lint
Fixes#9477Fixes#6751
Identifies common patterns where usage of the `clamp` function would be more succinct and clear, and suggests using the `clamp` function instead.
changelog: [`manual_clamp`]: Implement manual_clamp lint
This lint detects calls to a `&self`-taking `as_ptr` method, where
the result is then immediately cast to a `*mut T`. Code like this
is probably invalid, as that pointer will not have write permissions,
and `*mut T` is usually used to write through.
Move lint level source explanation to the bottom
So, uhhhhh
r? `@estebank`
## User-facing change
"note: `#[warn(...)]` on by default" and such are moved to the bottom of the diagnostic:
```diff
- = note: `#[warn(unsupported_calling_conventions)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
+ = note: `#[warn(unsupported_calling_conventions)]` on by default
```
Why warning is enabled is the least important thing, so it shouldn't be the first note the user reads, IMO.
## Developer-facing change
`struct_span_lint` and similar methods have a different signature.
Before: `..., impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>)`
After: `..., impl Into<DiagnosticMessage>, impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>) -> &'b mut DiagnosticBuilder<'a, ()>`
The reason for this is that `struct_span_lint` needs to edit the diagnostic _after_ `decorate` closure is called. This also makes lint code a little bit nicer in my opinion.
Another option is to use `impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>) -> DiagnosticBuilder<'a, ()>` altough I don't _really_ see reasons to do `let lint = lint.build(message)` everywhere.
## Subtle problem
By moving the message outside of the closure (that may not be called if the lint is disabled) `format!(...)` is executed earlier, possibly formatting `Ty` which may call a query that trims paths that crashes the compiler if there were no warnings...
I don't think it's that big of a deal, considering that we move from `format!(...)` to `fluent` (which is lazy by-default) anyway, however this required adding a workaround which is unfortunate.
## P.S.
I'm sorry, I do not how to make this PR smaller/easier to review. Changes to the lint API affect SO MUCH 😢
`Res::SelfTy` currently has two `Option`s. When the second one is `Some`
the first one is never consulted. So we can split it into two variants,
`Res::SelfTyParam` and `Res::SelfTyAlias`, reducing the size of `Res`
from 24 bytes to 12. This then shrinks `hir::Path` and
`hir::PathSegment`, which are the HIR types that take up the most space.
fix [`needless_borrow`], [`explicit_auto_deref`] FPs on unions
fix https://github.com/rust-lang/rust-clippy/issues/9383
changelog: fix [`needless_borrow`] false positive on unions
changelog: fix [`explicit_auto_deref`] false positive on unions
Left a couple debug derived impls on purpose I needed to debug as I don't think it's noise
Don't lint unstable moves in `std_instead_of_core`
Fixes#9515
changelog: [`std_instead_of_core`]: No longer suggests unstable modules such as `core::error`
add `box-default` lint
This adds a `box-default` lint to suggest using `Box::default()` instead of `Box::new(Default::default())`, which offers less moving parts and potentially better performance according to [the perf book](https://nnethercote.github.io/perf-book/standard-library-types.html#box).
---
changelog: add [`box_default`] lint
[`needless_return`] Recursively remove unneeded semicolons
fix#8336,
fix#8156,
fix https://github.com/rust-lang/rust-clippy/issues/7358,
fix#9192,
fix https://github.com/rust-lang/rust-clippy/issues/9503
changelog: [`needless_return`] Recursively remove unneeded semicolons
For now the suggestion about removing the semicolons are hidden because they would be very noisy and should be obvious if the user wants to apply the lint manually instead of using `--fix`. This could be an issue for beginner, but haven't found better way to display it.
[arithmetic-side-effects] Consider references
Takes into consideration integer references like `&i32::MAX` because currently things like `let _ = &1 + 0` trigger the lint.
changelog: FP: [`arithmetic_side_effects`]: Now ignores references
[9507](https://github.com/rust-lang/rust-clippy/pull/9507)
Don't lint `*_interior_mutable_const` on unions due to potential ICE.
fixes#9445
cc rust-lang/rust#101113
This started ICE'ing sometime last month due to stricter UB checks. I'm not sure how we could check the value of a union as MIRI doesn't seem to store which field is currently active.
changelog: Don't ICE on const unions containing a `!Freeze` type.
Silence [`question_mark`] in const context
fix https://github.com/rust-lang/rust-clippy/issues/9175
When `const_try` is stabilised can be turned into a MSRV
changelog: Silence [`question_mark`] in const context
Implement https://github.com/rust-lang/rust-clippy/issues/8368 - a new
lint to inline format arguments such as `print!("{}", var)` into
`print!("{var}")`.
code | suggestion | comment
---|---|---
`print!("{}", var)` | `print!("{var}")` | simple variables
`print!("{0}", var)` | `print!("{var}")` | positional variables
`print!("{v}", v=var)` | `print!("{var}")` | named variables
`print!("{0} {0}", var)` | `print!("{var} {var}")` | aliased variables
`print!("{0:1$}", var, width)` | `print!("{var:width$}")` | width
support
`print!("{0:.1$}", var, prec)` | `print!("{var:.prec$}")` | precision
support
`print!("{:.*}", prec, var)` | `print!("{var:.prec$}")` | asterisk
support
code | suggestion | comment
---|---|---
`print!("{0}={1}", var, 1+2)` | `print!("{var}={0}", 1+2)` | Format
string uses an indexed argument that cannot be inlined. Supporting this
case requires re-indexing of the format string.
changelog: [`uninlined_format_args`]: A new lint to inline format
arguments, i.e. `print!("{}", var)` into `print!("{var}")`
fix a ui test
use `into`
fix clippy ui test
fix a run-make-fulldeps test
implement `IntoQueryParam<DefId>` for `OwnerId`
use `OwnerId` for more queries
change the type of `ParentOwnerIterator::Item` to `(OwnerId, OwnerNode)`
[`never_loop`]: Fix FP with let..else statements.
Fixes#9356
This has been bugging me for a while, so I thought I'd take a stab at it! I'm completely uncertain about the quality of my code, but I think it's an alright start, so opening this PR to get some feedback from more experienced clippy people :)
changelog: [`never_loop`]: Fix FP with let..else statements
Introduce mir::Unevaluated
Previously the distinction between unevaluated constants in the type-system and in mir was not explicit and a little confusing. Probably better to introduce its own type for that.
r? `@lcnr`
Changelog for Rust 1.64 🍎
The normal release preparation dance. I've written the changelog like the version has already been released. The PR can be approved and then merged by anyone after the release of Rust 1.64 🙃
---
changelog: none
Fixes#9504
Compiler generated call `into_iter` nodes return empty substs
which we need when checking it's predicates. Handle this by
simply exitting when we encounter one. This change introduces
false negatives in place of the ICEs.
[arithmetic-side-effects] Finish non-overflowing ops
Extends https://github.com/rust-lang/rust-clippy/pull/9474 to also take into consideration "raw" binary operations. For example, `let a = b / 2` and `let a = 1 * b` won't trigger the lint.
changelog: [arithmetic-side-effects] Finish non-overflowing ops
Clippy pre beta branch fix
Before beta is branched on Friday, I want to move the `unused_peekable` lint that was added in this release cycle (1.65) to `nursery`. This lint was already reported twice (https://github.com/rust-lang/rust-clippy/issues/9456, https://github.com/rust-lang/rust-clippy/issues/9462) in a short time, so it is probably a good idea to fix it before it hits beta and then stable.
r? `@Manishearth`
Make module-style lints resilient to --remap-path-prefix
changelog: [`self_named_module_files`], [`mod_module_files`]: Make module-style lints resilient to `--remap-path-prefix`
Without this if a user has configured `--remap-path-prefix` to be used for a prefix containing the current source directory the lints would silently fail to generate a warning.
Initial implementation of dyn*
This PR adds extremely basic and incomplete support for [dyn*](https://smallcultfollowing.com/babysteps//blog/2022/03/29/dyn-can-we-make-dyn-sized/). The goal is to get something in tree behind a flag to make collaboration easier, and also to make sure the implementation so far is not unreasonable. This PR does quite a few things:
* Introduce `dyn_star` feature flag
* Adds parsing for `dyn* Trait` types
* Defines `dyn* Trait` as a sized type
* Adds support for explicit casts, like `42usize as dyn* Debug`
* Including const evaluation of such casts
* Adds codegen for drop glue so things are cleaned up properly when a `dyn* Trait` object goes out of scope
* Adds codegen for method calls, at least for methods that take `&self`
Quite a bit is still missing, but this gives us a starting point. Note that this is never intended to become stable surface syntax for Rust, but rather `dyn*` is planned to be used as an implementation detail for async functions in dyn traits.
Joint work with `@nikomatsakis` and `@compiler-errors.`
r? `@bjorn3`
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
Use `DisplayBuffer` for socket addresses.
Continuation of https://github.com/rust-lang/rust/pull/100625 for socket addresses.
Renames `net::addr` to `net::addr::socket`, `net::ip` to `net::addr::ip` and `net::ip::display_buffer::IpDisplayBuffer` to `net::addr::display_buffer::DisplayBuffer`.
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.
Rollup of 7 pull requests
Successful merges:
- #98933 (Opaque types' generic params do not imply anything about their hidden type's lifetimes)
- #101041 (translations(rustc_session): migrates rustc_session to use SessionDiagnostic - Pt. 2)
- #101424 (Adjust and slightly generalize operator error suggestion)
- #101496 (Allow lower_lifetime_binder receive a closure)
- #101501 (Allow lint passes to be bound by `TyCtxt`)
- #101515 (Recover from typo where == is used in place of =)
- #101545 (Remove unnecessary `PartialOrd` and `Ord`)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Allow lint passes to be bound by `TyCtxt`
This will allow storing things like `Ty<'tcx>` inside late lint passes. It's already possible to store various id types so they're already implicitly bound to a specific `TyCtxt`.
r? rust-lang/compiler
rustc: Parameterize `ty::Visibility` over used ID
It allows using `LocalDefId` instead of `DefId` when possible, and also encode cheaper `Visibility<DefIndex>` into metadata.
[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`
Rework `only_used_in_recursion`
fixes#8782fixes#8629fixes#8560fixes#8556
This is a complete rewrite of the lint. This loses some capabilities of the old implementation. Namely the ability to track through tuple and slice patterns, as well as the ability to trace through assignments.
The two reported bugs are fixed with this. One was caused by using the name of the method rather than resolving to the `DefId` of the called method. The second was cause by using the existence of a cycle in the dependency graph to determine whether the parameter was used in recursion even though there were other ways to create a cycle in the graph.
Implementation wise this switches from using a visitor to walking up the tree from every use of each parameter until it has been determined the parameter is used for something other than recursion. This is likely to perform better as it avoids walking the entire function a second time, and it is unlikely to walk up the HIR tree very much. Some cases would perform worse though.
cc `@buttercrab`
changelog: Scale back `only_used_in_recursion` to fix false positives
changelog: Move `only_used_in_recursion` back to `complexity`
Enhance `needless_borrow` to consider trait implementations
The proposed enhancement causes `needless_borrow` to suggest removing `&` from `&e` when `&e` is an argument position requiring trait implementations, and `e` implements the required traits. Example:
```
error: the borrowed expression implements the required traits
--> $DIR/needless_borrow.rs:131:51
|
LL | let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
| ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]`
```
r? `@Jarcho`
changelog: Enhance `needless_borrow` to consider trait implementations
unwrap_used and expect_used: trigger on uses of their _err variants
changelog: [`unwrap_used`]: lint uses of `unwrap_err`
changelog: [`expect_used`]: lint uses of `expect_err`
fixes#9331
`transmute_undefined_repr` fix
changelog: Don't lint `transmute_undefined_repr` when the the first field of a `repr(C)` type is compatible with the other type
suggest map_or in case_sensitive_file_extension_comparisons
changelog: [`case_sensitive_file_extension_comparisons `]: updated suggestion in the example to use `map_or`
Currently, case_sensitive_file_extension_comparisons suggests using `map(..).unwrap_or(..)` which trips up the `map_unwrap_or` lint. This updates the suggestion to use `map_or`.
Fix [`non_ascii_literal`] in tests
changelog: Don't lint [`non_ascii_literal`] when using non-ascii comments in tests
changelog: Don't lint [`non_ascii_literal`] when `allow`ed on tests
closes: #7739closes: #8263
Currently, case_sensitive_file_extension_comparisons suggests using
`map(..).unwrap_or(..)` which trips up `map_unwrap_or`. This updates
the suggestion to use map_or.
Add new lint [`positional_named_format_parameters`]
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: Add new lint [`positional_named_format_parameters`] to warn when named parameters in format strings are used as positional arguments.
- Rename `ast::Lit::token` as `ast::Lit::token_lit`, because its type is
`token::Lit`, which is not a token. (This has been confusing me for a
long time.)
reasonable because we have an `ast::token::Lit` inside an `ast::Lit`.
- Rename `LitKind::{from,to}_lit_token` as
`LitKind::{from,to}_token_lit`, to match the above change and
`token::Lit`.
Fix if_let_mutex not checking Mutexes behind refs
Fixes#9193
We can always peel references because we are looking for a method-call, for which autoderef applies.
---
changelog: [`if_let_mutex`]: detect calls to `Mutex::lock()` if mutex is behind a ref
changelog: [`if_let_mutex`]: Add labels to the two instances of the same Mutex that will deadlock
Visit attributes in more places.
This adds 3 loosely related changes (I can split PRs if desired):
- Attribute checking on pattern struct fields.
- Attribute checking on struct expression fields.
- Lint level visiting on pattern struct fields, struct expression fields, and generic parameters.
There are still some lints which ignore lint levels in various positions. This is a consequence of how the lints themselves are implemented. For example, lint levels on associated consts don't work with `unused_braces`.
Add lint recommending using `std::iter::once` and `std::iter::empty`
```
changelog: [`iter_once`]: add new lint
changelog: [`iter_empty`]: add new lint
```
fixes#9186
- \[ ] 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
The lint doesn't really follow the naming conventions. I don't have any better idea so I'm open to suggestions.
Extend `if_then_some_else_none` to also suggest `bool::then_some`
Closes#9094.
changelog: Extend `if_then_some_else_none` to also suggest `bool::then_some`
Add partialeq_to_none lint
Initial implementation of #9275, adding lint `partialeq_to_none`. This is my first time working on `clippy`, so please review carefully.
I'm unsure especially about the `Sugg`, as it covers the entire `BinOp`, instead of just covering one of the sides and the operator (see the multi-line example). I was unsure if pinpointing the suggestion wouldn't be brittle...
changelog: [`PARTIALEQ_TO_NONE`]: Initial commit
`explicit_auto_deref` changes
fixes#9123fixes#9109fixes#9143fixes#9101
This avoid suggesting code which hits a rustc bug. Basically `&{x}` won't use auto-deref if the target type is `Sized`.
changelog: Don't suggest using auto deref for block expressions when the target type is `Sized`
changelog: Include the borrow in the suggestion for `explicit_auto_deref`
changelog: Don't lint `explicit_auto_deref` on `dyn Trait` return
changelog: Don't lint `explicit_auto_deref` when other adjustments are required
changelog: Lint `explicit_auto_deref` in implicit return positions for closures
More proc-macro detection
fixes#6514fixes#8683fixes#6858fixes#6594
This is a more general way of checking if an expression comes from a macro and could be trivially applied to other lints. Ideally this would be fixed in rustc's proc-macro api, but I don't see that happening any time soon.
changelog: FPs: [`unit_arg`] [`default_trait_access`] [`missing_docs_in_private_items`]: No longer trigger in code generated from proc-macros.
move [`assertions_on_result_states`] to restriction
"Backports" the first commit of https://github.com/rust-lang/rust-clippy/pull/9273, so that the lint doesn't go into beta as a warn-by-default lint.
The other changes in the linked PR can ride the train as usual.
r? ``@xFrednet`` (only Clippy changes, so we don't need to bother compiler people)
---
For Clippy:
changelog: none
Always include a position span in `rustc_parse_format::Argument`
Moves the spans from the `Position` enum to always be included in the `Argument` struct. Doesn't make any changes to use it in rustc, but it will be useful for some upcoming Clippy lints
Fix suggestions for `async` closures in redundant_closure_call
Fixes#9052
changelog: Fix suggestions given by [`redundant_closure_call`] for async closures
- only compare where predicates to trait bounds when generating where
clause specific message to fix#9151
- use comparable_trait_ref to account for trait bound generics to fix#8757
Move [`assertions_on_result_states`] to restriction
Close#9263
This lint causes regression on readability of code and log output. And printing runtime values is not particularly useful for majority of tests which should be reproducible.
changelog: Move [`assertions_on_result_states`] to restriction and don't lint it for unit type
Signed-off-by: tabokie <xy.tao@outlook.com>
unwrap_used: Don't recommend using `expect` when the `expect_used` lint is not allowed
Fixes#9222
```
changelog: [`unwrap_used`]: Don't recommend using `expect` when the `expect_used` lint is not allowed
```
From 72 bytes to 12 bytes (on x86-64).
There are two parts to this:
- Changing various source code offsets from 64-bit to 32-bit. This is
not a problem because the rest of rustc also uses 32-bit source code
offsets. This means `Token` is no longer `Copy` but this causes no
problems.
- Removing the `RawStrError` from `LiteralKind`. Raw string literal
invalidity is now indicated by a `None` value within
`RawStr`/`RawByteStr`, and the new `validate_raw_str` function can be
used to re-lex an invalid raw string literal to get the `RawStrError`.
There is one very small change in behaviour. Previously, if a raw string
literal matched both the `InvalidStarter` and `TooManyHashes` cases,
the latter would override the former. This has now changed, because
`raw_double_quoted_string` now uses `?` and so returns immediately upon
detecting the `InvalidStarter` case. I think this is a slight
improvement to report the earlier-detected error, and it explains the
change in the `test_too_many_hashes` test.
The commit also removes a couple of comments that refer to #77629 and
say that the size of these types don't affect performance. These
comments are wrong, though the performance effect is small.
Rollup of 5 pull requests
Successful merges:
- #99311 (change maybe_body_owned_by to take local def id)
- #99862 (Improve type mismatch w/ function signatures)
- #99895 (don't call type ascription "cast")
- #99900 (remove some manual hash stable impls)
- #99903 (Add diagnostic when using public instead of pub)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Remove `TreeAndSpacing`.
A `TokenStream` contains a `Lrc<Vec<(TokenTree, Spacing)>>`. But this is
not quite right. `Spacing` makes sense for `TokenTree::Token`, but does
not make sense for `TokenTree::Delimited`, because a
`TokenTree::Delimited` cannot be joined with another `TokenTree`.
This commit fixes this problem, by adding `Spacing` to `TokenTree::Token`,
changing `TokenStream` to contain a `Lrc<Vec<TokenTree>>`, and removing the
`TreeAndSpacing` typedef.
The commit removes these two impls:
- `impl From<TokenTree> for TokenStream`
- `impl From<TokenTree> for TreeAndSpacing`
These were useful, but also resulted in code with many `.into()` calls
that was hard to read, particularly for anyone not highly familiar with
the relevant types. This commit makes some other changes to compensate:
- `TokenTree::token()` becomes `TokenTree::token_{alone,joint}()`.
- `TokenStream::token_{alone,joint}()` are added.
- `TokenStream::delimited` is added.
This results in things like this:
```rust
TokenTree::token(token::Semi, stmt.span).into()
```
changing to this:
```rust
TokenStream::token_alone(token::Semi, stmt.span)
```
This makes the type of the result, and its spacing, clearer.
These changes also simplifies `Cursor` and `CursorRef`, because they no longer
need to distinguish between `next` and `next_with_spacing`.
r? `@petrochenkov`
The expect_used lint is allow-by-default, so it would be better to show the case where this is enabled.
Co-authored-by: Takayuki Nakata <f.seasons017@gmail.com>
A `TokenStream` contains a `Lrc<Vec<(TokenTree, Spacing)>>`. But this is
not quite right. `Spacing` makes sense for `TokenTree::Token`, but does
not make sense for `TokenTree::Delimited`, because a
`TokenTree::Delimited` cannot be joined with another `TokenTree`.
This commit fixes this problem, by adding `Spacing` to `TokenTree::Token`,
changing `TokenStream` to contain a `Lrc<Vec<TokenTree>>`, and removing the
`TreeAndSpacing` typedef.
The commit removes these two impls:
- `impl From<TokenTree> for TokenStream`
- `impl From<TokenTree> for TreeAndSpacing`
These were useful, but also resulted in code with many `.into()` calls
that was hard to read, particularly for anyone not highly familiar with
the relevant types. This commit makes some other changes to compensate:
- `TokenTree::token()` becomes `TokenTree::token_{alone,joint}()`.
- `TokenStream::token_{alone,joint}()` are added.
- `TokenStream::delimited` is added.
This results in things like this:
```rust
TokenTree::token(token::Semi, stmt.span).into()
```
changing to this:
```rust
TokenStream::token_alone(token::Semi, stmt.span)
```
This makes the type of the result, and its spacing, clearer.
These changes also simplifies `Cursor` and `CursorRef`, because they no longer
need to distinguish between `next` and `next_with_spacing`.
Generate correct suggestion with named arguments used positionally
Address issue #99265 by checking each positionally used argument
to see if the argument is named and adding a lint to use the name
instead. This way, when named arguments are used positionally in a
different order than their argument order, the suggested lint is
correct.
For example:
```
println!("{b} {}", a=1, b=2);
```
This will now generate the suggestion:
```
println!("{b} {a}", a=1, b=2);
```
Additionally, this check now also correctly replaces or inserts
only where the positional argument is (or would be if implicit).
Also, width and precision are replaced with their argument names
when they exists.
Since the issues were so closely related, this fix for issue #99265
also fixes issue #99266.
Fixes#99265Fixes#99266
Read and use deprecated configuration (as well as emitting a warning)
Original change written by `@flip1995` I've simply rebased to master and fixed up the formatting/tests. This change teaches the configuration parser which config key replaced a deprecated key and attempts to populate the latter from the former. If both keys are provided this fails with a duplicate key error (rather than attempting to guess which the user intended).
Currently this on affects `cyclomatic-complexity-threshold` -> `cognitive-complexity-threshold` but will also be used in #8974 to handle `blacklisted-names` -> `disallowed-names`.
```
changelog: deprecated configuration keys are still applied as if they were provided as their non-deprecated name.
```
- [x] `cargo test` passes locally
- [x] Run `cargo dev fmt`
Address issue #99265 by checking each positionally used argument
to see if the argument is named and adding a lint to use the name
instead. This way, when named arguments are used positionally in a
different order than their argument order, the suggested lint is
correct.
For example:
```
println!("{b} {}", a=1, b=2);
```
This will now generate the suggestion:
```
println!("{b} {a}", a=1, b=2);
```
Additionally, this check now also correctly replaces or inserts
only where the positional argument is (or would be if implicit).
Also, width and precision are replaced with their argument names
when they exists.
Since the issues were so closely related, this fix for issue #99265
also fixes issue #99266.
Fixes#99265Fixes#99266
Add new lint `obfuscated_if_else`
part of #9100, additional commits could make it work with `then` and `unwrap_or_else` as well
changelog: Add new lint `obfuscated_if_else`
unused_self: respect avoid-breaking-exported-api
```
changelog: [`unused_self`]: Now respects the `avoid-breaking-exported-api` config option
```
Fixes#9195.
I mostly copied the implementation from `unnecessary_wraps`, since I don't have much understanding of rustc internals.
[`box_collection`]: raise warn for all std collections
So far, only [`Vec`, `String`, `HashMap`] were considered.
Extend collection checklist for this lint with:
- `HashSet`
- `VecDeque`
- `LinkedList`
- `BTreeMap`
- `BTreeSet`
- `BinaryHeap`
changelog: [`box_collection`]: raise warn for all std collections
Move format_push_string to restriction
Fixes#9077 (kinda) by moving the lint to the restriction group. As I noted in that issue, I think the suggested change is too much and as the OP of the issue points out, the ramifications of the change are not necessarily easily understood. As such I don't think the lint should be enabled by default.
changelog: [`format_push_string`]: moved to restriction (see #9077).
Implement `for<>` lifetime binder for closures
This PR implements RFC 3216 ([TI](https://github.com/rust-lang/rust/issues/97362)) and allows code like the following:
```rust
let _f = for<'a, 'b> |a: &'a A, b: &'b B| -> &'b C { b.c(a) };
// ^^^^^^^^^^^--- new!
```
cc ``@Aaron1011`` ``@cjgillot``
Always create elided lifetime parameters for functions
Anonymous and elided lifetimes in functions are sometimes (async fns) --and sometimes not (regular fns)-- desugared to implicit generic parameters.
This difference of treatment makes it some downstream analyses more complicated to handle. This step is a pre-requisite to perform lifetime elision resolution on AST.
There is currently an inconsistency in the treatment of argument-position impl-trait for functions and async fns:
```rust
trait Foo<'a> {}
fn foo(t: impl Foo<'_>) {} //~ ERROR missing lifetime specifier
async fn async_foo(t: impl Foo<'_>) {} //~ OK
fn bar(t: impl Iterator<Item = &'_ u8>) {} //~ ERROR missing lifetime specifier
async fn async_bar(t: impl Iterator<Item = &'_ u8>) {} //~ OK
```
The current implementation reports "missing lifetime specifier" on `foo`, but **accepts it** in `async_foo`.
This PR **proposes to accept** the anonymous lifetime in both cases as an extra generic lifetime parameter.
This change would be insta-stable, so let's ping t-lang.
Anonymous lifetimes in GAT bindings keep being forbidden:
```rust
fn foo(t: impl Foo<Assoc<'_> = Bar<'_>>) {}
^^ ^^
forbidden ok
```
I started a discussion here: https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Anonymous.20lifetimes.20in.20universal.20impl-trait/near/284968606
r? ``@petrochenkov``
fix [`manual_flatten`] help texts order
fixes #8948
Whenever suggestion for this lint does not fit in one line,
legacy solution has some unexpected/unhandled behavior:
lint will then generate two help messages which seem to be shown in the wrong order.
The second help message in that case will contain the suggestion.
The first help message always refers to a suggestion message,
and **it should adapt** depending on the location of the suggestion:
- inline suggestion within the error/warning message
- suggestion separated into a second help text
This is my first contribution here, so I hope I didn't miss anything for creating this PR.
changelog: fix [`manual_flatten`] help texts order
Whenever suggestion for this lint does not fit in one line,
lint will generate two help messages. The second help message
will always contain the suggestion.
The first help message refers to suggestion message,
and it should adapt depending on the location of the suggestion:
- inline suggestion within the error/warning message
- suggestion separated into second help text
Add `repeated_where_clause_or_trait_bound` lint
I thought I would try and scratch my own itch for #8674.
1. Is comparing the `Res` the correct way for ensuring we have the same trait?
2. Is there a way to get the spans for the bounds and clauses for suggestions?
I tried to use `GenericParam::bounds_span_for_suggestions` but it only gave me an empty span at the end of the spans.
I tried `WhereClause::span_for_predicates_or_empty_place` and it included the comma.
3. Is there a simpler way to get the trait names? I have used the spans of the traits because I didn't see a way to get it off the `Res` or `Def`.
changelog: Add ``[`repeated_where_clause_or_trait_bound`]`` lint.
change applicability type to MaybeIncorrect in `explicit_counter_loop`
close#9013
This PR changes applicability type to `MaybeIncorrect`, because the suggestion is not `MachineApplicable`.
changelog: change applicability type to MaybeIncorrect in `explicit_counter_loop`
Fixes for `branches_sharing_code`
fixes#7198fixes#7452fixes#7555fixes#7589
changelog: Don't suggest moving modifications to locals used in any of the condition expressions in `branches_sharing_code`
changelog: Don't suggest moving anything after a local with a significant drop in `branches_sharing_code`
Fix span for or_fun_call
Closes#9033
changelog: [`or_fun_call`]: span points to the `unwrap_or` only instead of through the entire method chain expression
* Don't suggest moving modifications to locals used in any of the condition expressions
* Don't suggest moving anything after a local with a significant drop
Simplify if let statements
fixes: #8288
---
changelog: Allowing [`qustion_mark`] lint to check `if let` expressions that immediatly return unwrapped value
Lint simple expressions in `manual_filter_map`, `manual_find_map`
changelog: Lint simple expressions in [`manual_filter_map`], [`manual_find_map`]
The current comparison rules out `.find(|a| a.is_some()).map(|b| b.unwrap())` because `a` being a reference can effect more complicated expressions, this adds a simple check for that case and adds the necessary derefs
There's some overlap with `option_filter_map` so `lint_filter_some_map_unwrap` now returns a `bool` to indicate it linted
Make MIR basic blocks field public
This makes it possible to mutably borrow different fields of the MIR
body without resorting to methods like `basic_blocks_local_decls_mut_and_var_debug_info`.
To preserve validity of control flow graph caches in the presence of
modifications, a new struct `BasicBlocks` wraps together basic blocks
and control flow graph caches.
The `BasicBlocks` dereferences to `IndexVec<BasicBlock, BasicBlockData>`.
On the other hand a mutable access requires explicit `as_mut()` call.
Finishing touches for `#[expect]` (RFC 2383)
This PR adds documentation and some functionality to rustc's lint passes, to manually fulfill expectations. This is needed for some lints in Clippy. Hopefully, it should be one of the last things before we can move forward with stabilizing this feature.
As part of this PR, I've also updated `clippy::duplicate_mod` to showcase how this new functionality can be used and to ensure that it works correctly.
---
changelog: [`duplicate_mod`]: Fixed lint attribute interaction
r? `@wesleywiser`
cc: https://github.com/rust-lang/rust/issues/97660, https://github.com/rust-lang/rust/issues/85549
And I guess that's it. Here have a magical unicorn 🦄
the two loops did practically the same, only the type were different (&&
vs &), so I used `copied` to convert `&&` and chained them together.
Instead of parsing the trait info manually, I use the already provided
method `get_trait_info_from_bound`.
Also, instead of using manual string writing, I used `join` by
`itertools`.
Fix `undocumented_unsafe_blocks` in closures
fixes#9114
changelog: Fix `undocumented_unsafe_blocks` not checking for comments before the start of a closure
Add `invalid_utf8_in_unchecked`
changelog: Add [`invalid_utf8_in_unchecked`]
closes: #629
Don't know how useful of a lint this is, just saw this was a really old issue 😄.
Correct lint version for `format_push_string`
Closes#9081
changelog: none
IDK what else to say. Look I can draw an ascii penguin =D:
```
(^v^)
<( )>
w w
```
Add details about how significant drop in match scrutinees can cause deadlocks
Adds more details about how a significant drop in a match scrutinee can cause a deadlock and include link to documentation.
changelog: Add more details to significant drop lint to explicitly show how temporaries in match scrutinees can cause deadlocks.
Fix `#[expect]` for most clippy lints
This PR fixes most `#[expect]` - lint interactions listed in rust-lang/rust#97660. [My comment in the issue](https://github.com/rust-lang/rust/issues/97660#issuecomment-1147269504) shows the current progress (Once this is merged). I plan to work on `duplicate_mod` and `multiple_inherent_impl` and leave the rest for later. I feel like stabilizing the feature is more important than fixing the last few nits, which currently also don't work with `#[allow]`.
---
changelog: none
r? `@Jarcho`
cc: rust-lang/rust#97660
Add lint `explicit_auto_deref` take 2
fixes: #234fixes: #8367fixes: #8380
Still things to do:
* ~~This currently only lints `&*<expr>` when it doesn't trigger `needless_borrow`.~~
* ~~This requires a borrow after a deref to trigger. So `*<expr>` changing `&&T` to `&T` won't be caught.~~
* The `deref` and `deref_mut` trait methods aren't linted.
* Neither ~~field accesses~~, nor method receivers are linted.
* ~~This probably shouldn't lint reborrowing.~~
* Full slicing to deref should probably be handled here as well. e.g. `&vec[..]` when just `&vec` would do
changelog: new lint `explicit_auto_deref`
try reading rust-version from Cargo.toml
Cargo.toml can contain a field `rust-version`, that acts like a MSRV of
clippy.toml file: https://doc.rust-lang.org/cargo/reference/manifest.html#the-rust-version-field
This will try to read that field and use it, if the clippy.toml config
has no `msrv` entry
changelog: respect `rust-version` from `Cargo.toml`
closes#8746closes#7765
`trivially_copy_pass_by_ref` fixes
fixes#5953fixes#2961
The fix for #5953 is overly aggressive, but the suggestion is so bad that it's worth the false negatives. Basically three things together:
* It's not obviously wrong
* It compiles
* It may actually work when tested
changelog: Don't lint `trivially_copy_pass_by_ref` when unsafe pointers are used.
changelog: Better track lifetimes when linting `trivially_copy_pass_by_ref`.
add [`manual_find`] lint for function return case
part of the implementation discussed in #7143
changelog: add [`manual_find`] lint for function return case
feat(new lint): new lint `manual_retain`
close#8097
This PR is a new lint implementation.
This lint checks if the `retain` method is available.
Thank you in advance.
changelog: add new ``[`manual_retain`]`` lint
Suggest `pointer::cast` when possible in `transmute_ptr_to_ref`
fixes#8924
changelog: Suggest casting the pointer for any type containing lifetimes in `transmute_ptr_to_ref`.
changelog: Suggest `pointer::cast` when possible in `transmute_ptr_to_ref`.
enum_variant_names should ignore when all prefixes are _
close#9018
When Enum prefix is only an underscore, we should not issue warnings.
changelog: fix false positive in enum_variant_names
Lint `[single_match]` on `Option` matches
fixes#8928
changelog: did some cleanup of the logic for ``[`single_match`]`` and ``[`single_match_else`]`` which fixes the bug where `Option` matches were not linted unless a wildcard was used for one of the arms.
ignore item in `thread_local!` macro
close#8493
This PR ignores `thread_local` macro in `declare_interior_mutable_const`.
changelog: ignore `thread_local!` macro in `declare_interior_mutable_const`
Fix `extra_unused_lifetimes` false positive
This PR fixes#9014.
I confirmed the FP on the `crates.io` source as `@JohnTitor` mentioned, and confirmed that the FP is no longer present following this change.
I did not include a test in this PR because I think constructing one would be complicated, and the fix is pretty simple. But please let me know if this is unacceptable.
changelog: fix `extra_unused_lifetimes` FP
add vec.capacity() to [`slow_vec_initialization`] detection
fix#8800
for example
```rust
let mut vec1 = Vec::with_capacity(len);
vec1.resize(vec1.capacity(), 0);
let mut vec2 = Vec::with_capacity(len);
vec2.extend(repeat(0).take(vec2.capacity()));
```
will trigger the lint
---
changelog: add `vec.capacity()` to [`slow_vec_initialization`] detection
confirm using chain in collapsible_span_lint_calls
close#8798
This PR fixes false positive when using chain in `collapsible_span_lint_calls`.
changelog: None
put parentheses around neg_multiply suggestion if needed
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: [`neg_multiply`]: put parentheses around suggestion if needed
`For` example should be used instead `while` in WHILE_LET_ON_ITERATOR
For example should be used instead while in WHILE_LET_ON_ITERATOR
Revert some changes
Fix cargo dev fmt
Adds more details about how a significant drop in a match scrutinee can
cause a deadlock and include link to documentation. Emits messages
indicating temporaries with significant drops in arms of matches and
message about possible deadlocks/unexpected behavior.
changelog: Add more details to significant drop lint to explicitly show
how temporaries in match scrutinees can cause deadlocks/unexpected
behavior.
feat(lint): add default_iter_empty
close#8915
This PR adds `default_iter_empty` lint.
This lint checks `std::iter::Empty::default()` and replace with `std::iter::empty()`.
Thank you in advance.
---
changelog: add `default_instead_of_iter_empty` lint.
Update description in clippy_lints/src/default_iter_empty.rs
Co-authored-by: Fridtjof Stoldt <xFrednet@gmail.com>
Update clippy_lints/src/default_iter_empty.rs
Co-authored-by: Alex Macleod <alex@macleod.io>
Update clippy_lints/src/default_iter_empty.rs
Co-authored-by: Alex Macleod <alex@macleod.io>
renamed default_iter_empty to default_instead_of_iter_empty
Avoid duplicate messages
add tests for regression
rewrite 'Why is this bad?'
cargo dev fmt
delete default_iter_empty lint in renamed_lint.rs
rewrite a message in the suggestion
cargo dev update_lints --check
Make `ExprKind::Closure` a struct variant.
Simple refactor since we both need it to introduce additional fields in `ExprKind::Closure`.
r? ``@Aaron1011``
Rework `branches_sharing_code`
fixes#7378
This changes the lint from checking pairs of blocks, to checking all the blocks at the same time. As such there's almost none of the original code left.
changelog: Don't lint `branches_sharing_code` when using different binding names
And likewise for the `Const::val` method.
Because its type is called `ConstKind`. Also `val` is a confusing name
because `ConstKind` is an enum with seven variants, one of which is
called `Value`. Also, this gives consistency with `TyS` and `PredicateS`
which have `kind` fields.
The commit also renames a few `Const` variables from `val` to `c`, to
avoid confusion with the `ConstKind::Value` variant.
Fix some `#[expect]` lint interaction
Fixing the first few lints that aren't caught by `#[expect]`. The root cause of these examples was, that the lint was emitted at the wrong location.
---
changelog: none
r? `@Jarcho`
cc: rust-lang/rust#97660
Improve lint doc consistency
changelog: none
This is a continuation of #8908.
Notable changes:
- Removed empty `Known Problems` sections
- Removed "Good"/"Bad" language (replaced with "Use instead")
- Removed (and added some 😄) duplication
- Ignored the [`create_dir`] example so it doesn't create `clippy_lints/foo` 😄
fix(lint): check const context
close: https://github.com/rust-lang/rust-clippy/issues/8898
This PR fixes a bug in checked_conversions.
Thank you in advance.
changelog: check const context in checked_conversions.
This commit makes type folding more like the way chalk does it.
Currently, `TypeFoldable` has `fold_with` and `super_fold_with` methods.
- `fold_with` is the standard entry point, and defaults to calling
`super_fold_with`.
- `super_fold_with` does the actual work of traversing a type.
- For a few types of interest (`Ty`, `Region`, etc.) `fold_with` instead
calls into a `TypeFolder`, which can then call back into
`super_fold_with`.
With the new approach, `TypeFoldable` has `fold_with` and
`TypeSuperFoldable` has `super_fold_with`.
- `fold_with` is still the standard entry point, *and* it does the
actual work of traversing a type, for all types except types of
interest.
- `super_fold_with` is only implemented for the types of interest.
Benefits of the new model.
- I find it easier to understand. The distinction between types of
interest and other types is clearer, and `super_fold_with` doesn't
exist for most types.
- With the current model is easy to get confused and implement a
`super_fold_with` method that should be left defaulted. (Some of the
precursor commits fixed such cases.)
- With the current model it's easy to call `super_fold_with` within
`TypeFolder` impls where `fold_with` should be called. The new
approach makes this mistake impossible, and this commit fixes a number
of such cases.
- It's potentially faster, because it avoids the `fold_with` ->
`super_fold_with` call in all cases except types of interest. A lot of
the time the compile would inline those away, but not necessarily
always.
* Don't lint on `.cloned().flatten()` when `T::Item` doesn't implement `IntoIterator`
* Reduce verbosity of lint message
* Narrow down the scope of the replacement range
List configuration values can now be extended instead of replaced
I've seen some `clippy.toml` files, that have a few additions to the default list of a configuration and then a copy of our default. The list will therefore not be updated, when we add new names. This change should make it simple for new users to append values instead of replacing them.
I'm uncertain if the documentation of the `".."` is apparent. Any suggestions are welcome. I've also check that the lint list displays the examples correctly.
<details>
<summary>Lint list screenshots</summary>
![image](https://user-images.githubusercontent.com/17087237/171999434-393f2f83-09aa-4bab-8b05-bd4973150f27.png)
![image](https://user-images.githubusercontent.com/17087237/171999401-e6942b53-25e6-4b09-89e5-d867c7463156.png)
</details>
---
changelog: enhancement: [`doc_markdown`]: Users can now indicate, that the `doc-valid-idents` should extend the default and not replace it
changelog: enhancement: [`blacklisted-name`]: Users can now indicate, that the `blacklisted-names` should extend the default and not replace it
Closes: #8877
That's it. Have a fantastic weekend to everyone reading this. Here is a cookie 🍪
Add new lint [`needless_parens_on_range_literals`]
changelog: Adds a new lint [`needless_parens_on_range_literals`] to warn on needless braces on literals in a range statement
For example, the lint would catch
```log
error: needless parenthesis on range literals can be removed
--> $DIR/needless_parens_on_range_literals.rs:8:13
|
LL | let _ = ('a')..=('z');
| ^^^^^ help: try: `'a'`
|
= note: `-D clippy::needless-parens-on-range-literals` implied by `-D warnings`
```
improve [`for_loops_over_fallibles`] to detect the usage of iter, iter_mut and into_iterator
fix#6762
detects code like
```rust
for _ in option.iter() {
//..
}
```
changelog: Improve [`for_loops_over_fallibles`] to detect `for _ in option.iter() {}` or using `iter_mut()` or `into_iterator()`.
Remove the unneeded wrapping and unwrapping in suggestion creation.
Collecting to Option<Vec<_>> only returns None if one of the elements is
None and that is never the case here.
fix(manual_find_map and manual_filter_map): check clone method
close#8920
Added conditional branching when the clone method is used.
Thank you in advance.
---
changelog: check `clone()` and other variant preserving methods in [`manual_find_map`] and [`manual_filter_map`]
When setting suggestion for significant_drop_in_scrutinee, add suggestion for MoveAndClone for non-ref
When trying to set the current suggestion, if the type of the expression
is not a reference and it is not trivially pure clone copy, we should still
trigger and emit a lint message. Since this fix may require cloning an
expensive-to-clone type, do not attempt to offer a suggested fix.
This change means that matches generated from TryDesugar and AwaitDesugar
would normally trigger a lint, but they are out of scope for this lint,
so we will explicitly ignore matches with sources of TryDesugar or
AwaitDesugar.
changelog: Update for ``[`significant_drop_in_scrutinee`]`` to correctly
emit lint messages for cases where the type is not a reference *and*
not trivially pure clone copy.
changelog: [`significant_drop_in_scrutinee`]: No longer lint on Try `?`
and `await` desugared expressions.
remove `large_enum_variant` suggestion for `Copy` types
Replaces the (erroneous) suggestion on `large_enum_variant` for `Copy` types by a note. This fixes#8894.
---
changelog: none
[1/N] Implement Arithmetic lint
Assuming that https://github.com/rust-lang/rust-clippy/issues/8903 is OK, this PR starts the creation of the `Arithmetic` lint with configurable types.
My current struggle to get a rustc review inspired me to create smaller PRs in order to easy review and make merges as fast as possible. So the first step here only moves the `arithmetic.rs` file to `numeric_arithmetic.rs` to make room for the new lint.
--
changelog: none
Make docs more consistent
changelog: none
This just fixes some docs to make them more consistent. I mostly just changed `// Good`, `// Bad`, etc to `Use instead:`.
Set correct `ParamEnv` for `derive_partial_eq_without_eq`
fixes#8867
changelog: Handle differing predicates applied by `#[derive(PartialEq)]` and `#[derive(Eq)]` in `derive_partial_eq_without_eq`
new lint: `borrow_deref_ref`
changelog: ``[`borrow_deref_ref`]``
Related pr: #6837#7577
`@Jarcho` Could you please give a review?
`cargo lintcheck` gives no false negative (but tested crates are out-of-date).
TODO:
1. Not sure the name. `deref_on_immutable_ref` or some others?
`SourceFile::lines` is a big part of metadata. It's stored in a compressed form
(a difference list) to save disk space. Decoding it is a big fraction of
compile time for very small crates/programs.
This commit introduces a new type `SourceFileLines` which has a `Lines`
form and a `Diffs` form. The latter is used when the metadata is first
read, and it is only decoded into the `Lines` form when line data is
actually needed. This avoids the decoding cost for many files,
especially in `std`. It's a performance win of up to 15% for tiny
crates/programs where metadata decoding is a high part of compilation
costs.
A `Lock` is needed because the methods that access lines data (which can
trigger decoding) take `&self` rather than `&mut self`. To allow for this,
`SourceFile::lines` now takes a `FnMut` that operates on the lines slice rather
than returning the lines slice.
Fix `manual_range_contains` false negative with chains of `&&` and `||`
Fixes#8745
Since the precedence for `&&` is the same as itself the HIR for a chain of `&&` ends up with a right skewed tree like:
```
&&
/ \
&& c2
/ \
... c1
```
So only the leftmost `&&` was actually "fully" checked, the top level was just `c2` and `&&` so the `manual_range_contains` lint won't apply. This change makes it also check `c2` with `c1`.
There's a bit of a hacky solution in the [second commit](257f09776a) to check if the number of open/closing parens in the snippet match. This is to prevent a case like `((x % 2 == 0) || (x < 0)) || (x >= 10)` from offering a suggestion like `((x % 2 == 0) || !(0..10).contains(&x)` which now won't compile.
Any suggestions for that paren hack welcome, kinda new to working on this so not too sure about possible solutions :) it's weird because I don't know how else to check for parens in HIR considering they're removed when lowering AST.
changelog: Fix [`manual_range_contains`] false negative with chains of `&&` and `||`
Don't lint `useless_transmute` on types with erased regions
fixes#6356fixes#3340fixes#2906
This should get a proper fix at some point, but this at least gets the lint running on some types.
cc #5343
changelog: Don't lint `useless_transmute` on types with erased regions
`cast_abs_to_unsigned`: do not remove cast if it's required
Fixes#8873
If `iX` is not cast to `uX` then keep the cast rather than removing it
changelog: [`cast_abs_to_unsigned`]: do not remove cast if it's required
needless_late_init: fix ICE when all branches return the never type
Fixes#8911
When the assignment is done in a match guard or the if condition and all of the branches return the never type `assignment_suggestions` would return an empty `Vec` which caused the ICE. It now returns `None` in that scenario
Also moves some tests to the top of the file
changelog: ICE Fixes: [`needless_late_init`] #8911
Fix `[use_self]` false negative with on struct and tuple struct patterns
fixes#8845
changelog: Triggered the warning for ``[`use_self`]`` on `TupleStruct` and `Struct` patterns, whereas currently it's only triggered for `Path` patterns
Fix `empty_line_after_outer_attribute` false positive
This PR fixes a false positive in `empty_line_after_outer_attribute`.
Here is a minimal example that trigger the FP:
```rust
#[derive(clap::Parser)]
#[clap(after_help = "This ia a help message.
You're welcome.
")]
pub struct Args;
```
changelog: PF: [`empty_line_after_outer_attribute`]: No longer lints empty lines in inner string values.
Introduce `allow-dbg-in-tests` config value
related to: Issue #8758, PR https://github.com/rust-lang/rust-clippy/pull/8838
changelog: Introduced `allow-dbg-in-tests` config value. [dbg_macro] does not allow `dbg!` in test code by default.
When trying to set the current suggestion, if the type of the expression
is not a reference and it is not trivially pure clone copy, we should still
trigger and emit a lint message. Since this fix may require cloning an
expensive-to-clone type, do not attempt to offer a suggested fix.
This change means that matches generated from TryDesugar and AwaitDesugar
would normally trigger a lint, but they are out of scope for this lint,
so we will explicitly ignore matches with sources of TryDesugar or
AwaitDesugar.
changelog: Update for [`significant_drop_in_scrutinee`] to correctly
emit lint messages for cases where the type is not a reference and
not trivially pure clone copy.
`get_last_with_len`: lint `VecDeque` and any deref to slice
changelog: [`get_last_with_len`]: lint `VecDeque` and any deref to slice
Previously only `Vec`s were linted, this will now catch any usages on slices, arrays, etc. It also suggests `.back()` for `VecDeque`s
Also moves the lint into `methods/`
`identity_op`: add parenthesis to suggestions where required
changelog: [`identity_op`]: add parenthesis to suggestions where required
Follow up to #8730, wraps the cases we can't lint as-is in parenthesis rather than ignoring them
Catches a couple new FPs with mixed operator precedences and `as` casts
```rust
// such as
0 + { a } * 2;
0 + a as usize;
```
The suggestions are now applied using `span_lint_and_sugg` rather than appearing in just the message and have a `run-rustfix` test
Refactor call terminator to always include destination place
In #71117 people seemed to agree that call terminators should always have a destination place, even if the call was guaranteed to diverge. This implements that. Unsurprisingly, the diff touches a lot of code, but thankfully I had to do almost nothing interesting. The only interesting thing came up in const prop, where the stack frame having no return place was also used to indicate that the layout could not be computed (or similar). I replaced this with a ZST allocation, which should continue to do the right things.
cc `@RalfJung` `@eddyb` who were involved in the original conversation
r? rust-lang/mir-opt
Lifetime variance fixes for clippy
#97287 migrates rustc to a `Ty` type that is invariant over its lifetime `'tcx`, so I need to fix a bunch of places that assume that `Ty<'a>` and `Ty<'b>` can be shortened to some common lifetime.
This is doable, since everything is already `'tcx`, so all this PR does is be a bit more explicit that elided lifetimes are actually `'tcx`.
Split out from #97287 so the clippy team can review independently.
Drop Tracking: Implement `fake_read` callback
This PR updates drop tracking's use of `ExprUseVisitor` so that we treat `fake_read` events as borrows. Without doing this, we were not handling match expressions correctly, which showed up as a breakage in the `addassign-yield.rs` test. We did not previously notice this because we still had rather large temporary scopes that we held borrows for, which changed in #94309.
This PR also includes a variant of the `addassign-yield.rs` test case to make sure we continue to have correct behavior here with drop tracking.
r? `@nikomatsakis`
Rustup
`@rust-lang/clippy,` `@Jarcho,` `@dswij,` `@Alexendoo.` Could someone review this? It should be pretty straight forward since it's just a sync. I think it's also fine if either one of `@Jarcho,` `@dswij,` `@Alexendoo` approves this, as these are usually not reviewed. I just want to make sure that I didn't break something obvious 🙃
It should be enough to look at the merge commit 🙃
changelog: none
changelog: move [`significant_drop_in_scrutinee`] to `suspicious`
[dbg_macro] tolerates use of `dbg!` in items which have `#[cfg(test)]` attribute
fix: #8758
changelog: [dbg_macro] tolerates use of `dbg!` in items with `#[cfg(test)]` attribute
Improve "unknown field" error messages
Fixes#8806
Sample output:
```
error: error reading Clippy's configuration file `/home/smoelius/github/smoelius/rust-clippy/clippy.toml`: unknown field `foobar`, expected one of
allow-expect-in-tests enable-raw-pointer-heuristic-for-send standard-macro-braces
allow-unwrap-in-tests enforced-import-renames third-party
allowed-scripts enum-variant-name-threshold too-large-for-stack
array-size-threshold enum-variant-size-threshold too-many-arguments-threshold
avoid-breaking-exported-api literal-representation-threshold too-many-lines-threshold
await-holding-invalid-types max-fn-params-bools trivial-copy-size-limit
blacklisted-names max-include-file-size type-complexity-threshold
cargo-ignore-publish max-struct-bools unreadable-literal-lint-fractions
cognitive-complexity-threshold max-suggested-slice-pattern-length upper-case-acronyms-aggressive
cyclomatic-complexity-threshold max-trait-bounds vec-box-size-threshold
disallowed-methods msrv verbose-bit-mask-threshold
disallowed-types pass-by-value-size-limit warn-on-all-wildcard-imports
doc-valid-idents single-char-binding-names-threshold
at line 1 column 1
```
You can test this by (say) adding `foobar = 42` to Clippy's root `clippy.toml` file, and running `cargo run --bin cargo-clippy`.
Note that, to get the terminal width, this PR adds `termize` as a dependency to `cargo-clippy`. However, `termize` is also [how `rustc_errors` gets the terminal width](481db40311/compiler/rustc_errors/src/emitter.rs (L1607)). So, hopefully, this is not a dealbreaker.
r? `@xFrednet`
changelog: Enhancements: the "unknown field" error messages for config files now wraps the field names.
add suggestions to rc_clone_in_vec_init
A followup to https://github.com/rust-lang/rust-clippy/pull/8769
I also switch the order of the 2 suggestions, since the loop initialization one is probably the common case.
`@xFrednet` I'm not letting you guys rest for a minute 😅
changelog: add suggestions to [`rc_clone_in_vec_init`]
`undocumented_unsafe_blocks` does not trigger on unsafe trait impls
Closes#8505
changelog: This lint checks unsafe impls NOT from macro expansions and checks ones in macro declarations.
~~`unsafe impl`s from macro invocations don't trigger the lint for now.~~
~~This lint checks unsafe impls from/not from macro expansions~~
Don't lint `vec_init_then_push` when further extended
fixes#7071
This will still lint when a larger number of pushes are done (four currently). The exact number could be debated, but this is more readable then a sequence of pushes so it shouldn't be too large.
changelog: Don't lint `vec_init_then_push` when further extended.
changelog: Remove `mut` binding from `vec_init_then_push` when possible.
Add EarlyBinder
Chalk has no concept of `Param` (e0ade19d13/chalk-ir/src/lib.rs (L579)) or `ReEarlyBound` (e0ade19d13/chalk-ir/src/lib.rs (L1308)). Everything is just "bound" - the equivalent of rustc's late-bound. It's not completely clear yet whether to move everything to the same time of binder in rustc or add `Param` and `ReEarlyBound` in Chalk.
Either way, tracking when we have or haven't already substituted out these in rustc can be helpful.
As a first step, I'm just adding a `EarlyBinder` newtype that is required to call `subst`. I also add a couple "transparent" `bound_*` wrappers around a couple query that are often immediately substituted.
r? `@nikomatsakis`
Fix redundant_allocation warning for Rc<Box<str>>
changelog: [`redundant_allocation`] Fixes#8604
Fixes false positives where a fat pointer with `str` type was made thin by another allocation, but that thinning allocation was marked as redundant
This PR has implemented improved representation.
- Use "lib" instead of "lifb"
- Use "triggered" instead of "triggere"
- Use "blacklisted_name" instead of "blackisted_name"
- Use "stabilization" instead of "stabilisation"
- Use "behavior" instead of "behaviour"
- Use "target" instead of "tartet"
- Use "checked_add" instead of "chcked_add"
- Use "anti-pattern" instead of "antipattern"
- Use "suggestion" instead of "suggesttion"
- Use "example" instead of "exampel"
- Use "Cheat Sheet" instead of "Cheatsheet"
New lint: [`derive_partial_eq_without_eq`]
Introduces a new lint, [`derive_partial_eq_without_eq`].
See: #1781 (doesn't close it though).
changelog: add lint [`derive_partial_eq_without_eq`]
Replace `#[allow]` with `#[expect]` in Clippy
Hey `@rust-lang/clippy,` `@Alexendoo,` `@dswij,` I'm currently working on the expect attribute as defined in [Rust RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html). With that, an `#[allow]` attribute can be replaced with a `#[expect]` attribute that suppresses the lint, but also emits a warning, if the lint isn't emitted in the expected scope.
With this PR I would like to test the attribute on a project scale and Clippy obviously came to mind. This PR replaces (almost) all `#[allow]` attributes in `clippy_utils` and `clippy_lints` with the `#[expect]` attribute. I was also able to remove some allows since, the related FPs have been fixed 🎉.
My question is now, are there any concerns regarding this? It's still okay to add normal `#[allow]` attributes, I see the need to nit-pick about that in new PRs, unless it's actually a FP. Also, I would not recommend using `#[expect]` in tests, as changes to a lint could the trigger the expect attribute in other files.
Additionally, I've noticed that Clippy has a bunch of `#[allow(clippy::too_many_lines)]` attributes. Should we maybe allow the lint all together or increase the threshold setting? To me, it seems like we mostly just ignore it in our code. 😅🙃
---
changelog: none
r? `@flip1995` (I've requested you for now, since you're also helping with reviewing the expect implementation. You are welcome to delegate this PR, even if it should be a simple review 🙃 )
Track if a where bound comes from a impl Trait desugar
With https://github.com/rust-lang/rust/pull/93803 `impl Trait` function arguments get desugared to hidden where bounds. However, Clippy needs to know if a bound was originally a `impl Trait` or an actual bound. This adds a field to the `WhereBoundPredicate` struct to keep track of this information during AST->HIR lowering.
r? `@cjgillot`
cc `@estebank` (as the reviewer of #93803)
Create clippy lint against unexpectedly late drop for temporaries in match scrutinee expressions
A new clippy lint for issue 93883 (https://github.com/rust-lang/rust/issues/93883). Relies on a new trait in `marker` (called `SignificantDrop` to enable linting), which is why this PR is for the rust-lang repo and not the clippy repo.
changelog: new lint [`significant_drop_in_scrutinee`]
With #93803 `impl Trait` function arguments get desugared to hidden
where bounds. However, Clippy needs to know if a bound was originally a
impl Trait or an actual bound. This adds a field to the
`WhereBoundPredicate` struct to keep track of this information during
HIR lowering.
Address `unnecessary_to_owned` false positive
My proposed fix for #8759 is to revise the conditions that delineate `redundant_clone` and `unnecessary_to_owned`:
```rust
// Only flag cases satisfying at least one of the following three conditions:
// * the referent and receiver types are distinct
// * the referent/receiver type is a copyable array
// * the method is `Cow::into_owned`
// This restriction is to ensure there is no overlap between `redundant_clone` and this
// lint. It also avoids the following false positive:
// https://github.com/rust-lang/rust-clippy/issues/8759
// Arrays are a bit of a corner case. Non-copyable arrays are handled by
// `redundant_clone`, but copyable arrays are not.
```
This change causes a few cases that were previously flagged by `unnecessary_to_owned` to no longer be flagged. But one could argue those cases would be better handled by `redundant_clone`.
Closes#8759
changelog: none
Support negative ints in manual_range_contains
fixes: #8721
changelog: Fixes issue where ranges containing ints with different signs would be
incorrect due to comparing as unsigned.
Fix `cast_lossless` to avoid warning on `usize` to `f64` conversion.
Previously, the `cast_lossless` lint would issue a warning on code that
converted a `usize` value to `f64`, on 32-bit targets.
`usize` to `f64` is a lossless cast on 32-bit targets, however there is
no corresponding `f64::from` that takes a `usize`, so `cast_lossless`'s
suggested replacement does not compile.
This PR disables the lint in the case of casting from `usize` or `isize`.
Fixes#3689.
changelog: [`cast_lossless`] no longer gives wrong suggestion on usize,isize->f64
Lint `empty_lint_after_outer_attr` on argumentless macros
Reverts the change from 034c81b761 as it's no longer needed. The test is left just in case. Original issue is #2475.
changelog: Lint `empty_lint_after_outer_attr` on argumentless macros again
Those lints are trait_duplication_in_bounds and
type_repetition_in_bounds. I don't think those can be fixed on the
Clippy side alone, but need changes in the compiler. So let's move them
to nursery to get the sync through and then fix them on the rustc side.
Also adds a regression test that has to be fixed before they can be
moved back to pedantic.
Easier readability for `needless_late_init` message
Closes#8530
Updated the lint to use a `MultiSpan`, showing where the `let` statement was first used and where the initialisation statement was done, as in the format described, for easier readability.
Was wondering why, when pushing the span label for the initialisation statement, that sometimes the prior statement above the initialisation statement gets pulled into the output as well - any insight is appreciated!
---
changelog: [`needless_late_init`]: Now shows the `let` statement where it was first initialized
[FP] identity_op in front of if
fix#8724
changelog: FP: [`identity_op`]: is now allowed in front of if statements, blocks and other expressions where the suggestion would be invalid.
Resolved simular problems with blocks, mathces, and loops.
identity_op always does NOT suggest reducing `0 + if b { 1 } else { 2 } + 3` into `if b { 1 } else { 2 } + 3` even in the case that the expression is in `f(expr)` or `let x = expr;` for now.
Previously, the `cast_lossless` lint would issue a warning on code that
converted a `usize` value to `f64`, on 32-bit targets.
`usize` to `f64` is a lossless cast on 32-bit targets, however there is
no corresponding `f64::from` that takes a `usize`, so `cast_lossless`'s
suggested replacement does not compile.
This PR disables the lint in the case of casting from `usize` or `isize`.
Fixes#3689.
changelog: [`cast_lossless`] no longer gives wrong suggestion on usize->f64
Only crate root def-ids don't have a parent, and in majority of cases the argument of `DefIdTree::parent` cannot be a crate root.
So we now panic by default in `parent` and introduce a new non-panicing function `opt_parent` for cases where the argument can be a crate root.
Same applies to `local_parent`/`opt_local_parent`.
Change `span_suggestion` (and variants) to take `impl ToString` rather
than `String` for the suggested code, as this simplifies the
requirements on the diagnostic derive.
Signed-off-by: David Wood <david.wood@huawei.com>
ignore `redundant_pub_crate` in `useless_attribute`
changelog: [`useless_attribute`] no longer lints [`redundant_pub_crate`]
As mentioned in https://github.com/rust-lang/rust-clippy/issues/8732#issuecomment-1106489634
> And it turns out I can't even explicitly allow it at the usage site, because then `clippy::useless_attribute` fires (which would also be a FP?), which is deny-by-default.
>
> Though it does work if I then allow `clippy::useless_attribute`. 😂
>
> ```rust
> #[allow(clippy::useless_attribute)]
> #[allow(clippy::redundant_pub_crate)]
> pub(crate) use bit;
> ```
>
> The originally-reported warning now no longer occurs.
`needless_late_init`: ignore `if let`, `let mut` and significant drops
No longer lints `if let`, personal taste on this one is pretty split, so it probably shouldn't be warning by default. Fixes#8613
```rust
let x = if let Some(n) = y {
n
} else {
1
}
```
No longer lints `let mut`, things like the following are not uncommon and look fine as they are
b169c16d86/src/sixty_four.rs (L88-L93)
Avoids changing the drop order in an observable way, where the type of `x` has a drop with side effects and something between `x` and the first use also does, e.g.
48cc6cb791/tests/test_api.rs (L159-L167)
The implementation of `type_needs_ordered_drop_inner` was changed a bit, it now uses `Ty::has_significant_drop` and reordered the ifs to check diagnostic name before checking the implicit drop impl
changelog: [`needless_late_init`]: No longer lints `if let` statements, `let mut` bindings and no longer significantly changes drop order
mistyped_literal_suffix: improve integer suggestions, avoid wrong float suggestions
This PR fixes 2 things:
- The known problem that integer types are always suggested as signed, by suggesting an unsigned suffix for literals that wouldnt fit in the signed type, and ignores any literals too big for the corresponding unsigned type too.
- The lint would only look at the integer part of any floating point literals without an exponent, this causing #6129. This just ignores those literals.
Examples:
```rust
let _ = 2_32; // still 2_i32
let _ = 234_8; // would now suggest 234_u8
// these are now ignored
let _ = 500_8;
let _ = 123_32.123;
```
changelog: suggest correct integer types in [`mistyped_literal_suffix`], ignore float literals without an exponent
fixes#6129
Previously this lint would only look at the integer part of floating
point literals without an exponent, giving wrong suggestions like:
```
|
8 | let _ = 123_32.123;
| ^^^^^^^^^^ help: did you mean to write: `123.123_f32`
|
```
Instead, it now ignores these literals.
Fixes#6129
Instead of just always suggesting signed suffixes regardless of size
of the value, it now suggests an unsigned suffix when the value wouldn't
fit into the corresponding signed type, and ignores the literal entirely
if it is too big for the unsigned type as well.
wrong_self_convention allows `is_*` to take `&mut self`
fix#8480 and #8513
Allowing `is_*` to take `&self` or none is too restrictive.
changelog: FPs: [`wrong_self_convention`] now allows `&mut self` and no self as arguments for `is_*` methods
`manual_split_once`: lint manual iteration of `SplitN`
changelog: `manual_split_once`: lint manual iteration of `SplitN`
Now lints:
```rust
let mut iter = "a.b.c".splitn(2, '.');
let first = iter.next().unwrap();
let second = iter.next().unwrap();
let mut iter = "a.b.c".splitn(2, '.');
let first = iter.next()?;
let second = iter.next()?;
let mut iter = "a.b.c".rsplitn(2, '.');
let first = iter.next().unwrap();
let second = iter.next().unwrap();
let mut iter = "a.b.c".rsplitn(2, '.');
let first = iter.next()?;
let second = iter.next()?;
```
It suggests (minus leftover whitespace):
```rust
let (first, second) = "a.b.c".split_once('.').unwrap();
let (first, second) = "a.b.c".split_once('.')?;
let (second, first) = "a.b.c".rsplit_once('.').unwrap();
let (second, first) = "a.b.c".rsplit_once('.')?;
```
Currently only lints if the statements are next to each other, as detecting the various kinds of shadowing was tricky, so the following won't lint
```rust
let mut iter = "a.b.c".splitn(2, '.');
let something_else = 1;
let first = iter.next()?;
let second = iter.next()?;
```
Less authoritative stable_sort_primitive message
fixes#8241
Hey all - first contribution here so I'm deciding to start with something small.
Updated the linked message to be less authoritative as well as moved the lint grouping from `perf` to `pedantic` as suggested by `@camsteffen` under the issue.
changelog: [`stable_sort_primitive`]: emit less authoritative message and move to `pedantic`
Fix needless_match false positive for if-let when the else block doesn't match to given expr
<!--
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. Also, it's helpful for us that
the lint name is put into brackets `[]` and backticks `` ` ` ``,
e.g. ``[`lint_name`]``.
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.
- \[ ] Followed [lint naming conventions][lint_naming]
- \[ ] Added passing UI tests (including committed `.stderr` file)
- \[x] `cargo test` passes locally
- \[x] Executed `cargo dev update_lints`
- \[ ] 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.
--->
fix#8695
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: Fixed ``[`needless_match`]`` false positive when else block expression differs.
Take over: New lint bytes count to len
take over #8375close#8083
This PR adds new lint about considering replacing `.bytes().count()` with `.len()`.
Thank you in advance.
---
r! `@Manishearth`
changelog: adds new lint [`bytes_count_to_len`] to consider replacing `.bytes().count()` with `.len()`
Stop using CRATE_DEF_INDEX outside of metadata encoding.
`CRATE_DEF_ID` and `CrateNum::as_def_id` are almost always what we want. We should not manipulate raw `DefIndex` outside of metadata encoding.
adding test patterns
cargo dev bless
fix comment
add ;
delete :
fix suggestion code
and update stderr in tests.
use match_def_path when checking method name
Add `await_holding_invalid_type` lint
changelog: [`await_holding_invalid_type`]
This lint allows users to create a denylist of types which are not allowed to be
held across await points. This is essentially a re-implementation of the
language-level [`must_not_suspend`
lint](https://github.com/rust-lang/rust/issues/83310). That lint has a lot of
work still to be done before it will reach Rust stable, and in the meantime
there are a lot of types which can trip up developers if they are used
improperly.
I originally implemented this specifically for `tracing::span::Entered`, until I discovered #8434 and read the commentary on that PR. Given this implementation is fully user configurable, doesn't tie clippy to any one particular crate, and introduces no additional dependencies, it seems more appropriate.
Refactor HIR item-like traversal (part 1)
Issue #95004
- Create hir_crate_items query which traverses tcx.hir_crate(()).owners to return a hir::ModuleItems
- use tcx.hir_crate_items in tcx.hir().items() to return an iterator of hir::ItemId
- use tcx.hir_crate_items to introduce a tcx.hir().par_items(impl Fn(hir::ItemId)) to traverse all items in parallel;
Signed-off-by: Miguel Guarniz <mi9uel9@gmail.com>
cc `@cjgillot`
Fix formatting of `cast_abs_to_unsigned` docs
The "use instead" section of the example was not being formatted as Rust code, and the "configuration" documentation was being formatted as Rust code.
changelog: `[cast_abs_to_unsigned]` Fix example/configuration formatting
Implement sym operands for global_asm!
Tracking issue: #93333
This PR is pretty much a complete rewrite of `sym` operand support for inline assembly so that the same implementation can be shared by `asm!` and `global_asm!`. The main changes are:
- At the AST level, `sym` is represented as a special `InlineAsmSym` AST node containing a path instead of an `Expr`.
- At the HIR level, `sym` is split into `SymStatic` and `SymFn` depending on whether the path resolves to a static during AST lowering (defaults to `SynFn` if `get_early_res` fails).
- `SymFn` is just an `AnonConst`. It runs through typeck and we just collect the resulting type at the end. An error is emitted if the type is not a `FnDef`.
- `SymStatic` directly holds a path and the `DefId` of the `static` that it is pointing to.
- The representation at the MIR level is mostly unchanged. There is a minor change to THIR where `SymFn` is a constant instead of an expression.
- At the codegen level we need to apply the target's symbol mangling to the result of `tcx.symbol_name()` depending on the target. This is done by calling the LLVM name mangler, which handles all of the details.
- On Mach-O, all symbols have a leading underscore.
- On x86 Windows, different mangling is used for cdecl, stdcall, fastcall and vectorcall.
- No mangling is needed on other platforms.
r? `@nagisa`
cc `@eddyb`
changelog: [`await_holding_invalid_type`]
This lint allows users to create a denylist of types which are not allowed to be
held across await points. This is essentially a re-implementation of the
language-level [`must_not_suspend`
lint](https://github.com/rust-lang/rust/issues/83310). That lint has a lot of
work still to be done before it will reach Rust stable, and in the meantime
there are a lot of types which can trip up developers if they are used
improperly.