clippy::suboptimal_flops used to not check if the second parameter to f32/f64.mul_add() was float. Since the method is
only defined to take `Self` as paremters, the suggestion was wrong.
Fixes#11831
teach `eager_or_lazy` about panicky arithmetic operations
Fixes#9422Fixes#9814Fixes#11793
It's a bit sad that we have to do this because arithmetic operations seemed to me like the prime example where a closure would not be necessary, but this has "side effects" (changes behavior when going from lazy to eager) as some of these panic on overflow/underflow if compiled with `-Coverflow-checks` (which is the default in debug mode).
Given the number of backlinks in the mentioned issues, this seems to be a FP that is worth fixing, probably.
changelog: [`unnecessary_lazy_evaluations`]: don't lint if closure has panicky arithmetic operations
Extend `maybe_misused_cfg` lint over `cfg(test)`
Fixes#11240.
One thought I had is that we could use the levenshtein distance (of 1) to ensure this is indeed `test` that was targeted. But maybe it's overkill, not sure.
changelog: [`maybe_misused_cfg`]: Extend lint over `cfg(test)`
r? `@blyxyas`
Changelog for Rust 1.74 🎃
Roses are red,
Halloween is over,
Have you considered,
Buying a Mars rover?
---
### The cats of this release:
<img height=500 src="https://github.com/rust-lang/rust-clippy/assets/17087237/095bd32e-b5e3-41db-8f0f-bdef7ca1a6d0" alt="The cats of this Clippy release" />
<sub>The cat for the next release can be nominated in the comments</sub>
---
changelog: none
Change `if_same_then_else` to be a `style` lint
CC #3770
From https://github.com/rust-lang/rust-clippy/issues/3770#issuecomment-687565594 (`@flip1995):`
> Oh I thought I replied to this: I definitely see now that having this
> as a correctness lint might be the wrong categorization. What we might
> want to do is to just allow this lint, if there are comments in the
> arm bodies. But a good first step would be to downgrade this lint to
> style or complexity. I would vote for style since merging two arms is
> not always less complex.
changelog: [`if_same_then_else`]: Change to be a `style` lint
[`impl_trait_in_params`]: avoid ICE when function with `impl Trait` type has no parameters
Fixes#11803
If I'm reading the old code correctly, it was taking the span of the first parameter (without checking that it exists, which caused the ICE) and uses that to figure out where the generic parameter to insert should go (cc `@blyxyas` you wrote the lint, is that correct?).
This seemed equivalent to just `generics.span`, which doesn't require calculating the spans like that and simplifies it a fair bit
changelog: don't ICE when function has no parameters but generics have an `impl Trait` type
CC #3770
From https://github.com/rust-lang/rust-clippy/issues/3770#issuecomment-687565594 (@flip1995):
> Oh I thought I replied to this: I definitely see now that having this
> as a correctness lint might be the wrong categorization. What we might
> want to do is to just allow this lint, if there are comments in the
> arm bodies. But a good first step would be to downgrade this lint to
> style or complexity. I would vote for style since merging two arms is
> not always less complex.
Implement new lint `iter_over_hash_type`
Implements and fixes https://github.com/rust-lang/rust-clippy/issues/11788
This PR adds a new *restriction* lint `iter_over_hash_type` which prevents `Hash`-types (that is, `HashSet` and `HashMap`) from being used as the iterator in `for` loops.
The justification for this is because in `Hash`-based types, the ordering of items is not guaranteed and may vary between executions of the same program on the same hardware. In addition, it reduces readability due to the unclear iteration order.
The implementation of this lint also ensures the following:
- Calls to `HashMap::keys`, `HashMap::values`, and `HashSet::iter` are also denied when used in `for` loops,
- When this expression is used in procedural macros, it is not linted/denied.
changelog: add new `iter_over_hash_type` lint to prevent unordered iterations through hashed data structures
Fixes to `manual_let_else`'s divergence check
A few changes to the divergence check in `manual_let_else` and moves it the implementation to `clippy_utils` since it's generally useful:
* Handle internal `break` and `continue` expressions.
e.g. The first loop is divergent, but the second is not.
```rust
{
loop {
break 'outer;
};
}
{
loop {
break;
};
}
```
* Match rust's definition of divergence which is defined via the type system.
e.g. The following is not considered divergent by rustc as the inner block has a result type of `()`:
```rust
{
'a: {
panic!();
break 'a;
};
}
```
* Handle when adding a single semicolon would make the expression divergent.
e.g. The following would be a divergent if a semicolon were added after the `if` expression:
```rust
{ if panic!() { 0 } else { 1 } }
```
changelog: None
Lint `needless_borrow` and `explicit_auto_deref` on most union field accesses
Changes both lints to follow rustc's rules around auto-deref through `ManuallyDrop` union fields rather than just bailing on union fields.
changelog: [`needless_borrow`] & [`explicit_auto_deref`]: Lint on most union field accesses
Disable `vec_box` when using different allocators
Fixes#7114
This PR disables the `vec_box` lint when the `Box` and `Vec` use different allocators (but not when they use the same - custom - allocator).
For example - `Vec<Box<i32, DummyAllocator>>` will disable the lint, and `Vec<Box<i32, DummyAllocator>, DummyAllocator>` will not disable the lint.
In addition, the applicability of this lint has been changed to `Unspecified` due to the automatic fixes potentially breaking code such as the following:
```rs
fn foo() -> Vec<Box<i32>> { // -> Vec<i32>
vec![Box::new(1)]
}
```
It should be noted that the `if_chain->let-chains` fix has also been applied to this lint, so the diff does contain many changes.
changelog: disable `vec_box` lint when using nonstandard allocators
[`mod_module_files`] Don't emit lint for mod.rs in tests
fixes: #11775
current state: indiscriminately emits the lint for mod files in tests.
The following
```
tests/
common/
mod.rs
test.rs
```
is a common pattern for code shared across the tests and is suggested in the rust book. The change adds an additional check to verify that the mod file is not in tests.
changelog: Fix [`mod_module_files`]: false positive for mod files in tests folder
fixes: #11775
current state: indiscriminately emits the lint for mod files in tests.
The following
tests/
common/
mod.rs
test.rs
is a common pattern for code shared across the tests and is suggested in
the rust book. The change adds an additional check to verify that the
mod file is not in tests.
changelog: Fix [`mod_module_files`]: false positive for mod files in
tests folder
Fix `dbg_macro` semi span calculation
`span_including_semi` was using a `BytePos` to index into a file's source which happened to work because the root file of the test started at `BytePos` 0, it didn't work for other files
changelog: none
Most notably, this commit changes the `pub use crate::*;` in that file
to `use crate::*;`. This requires a lot of `use` items in other crates
to be adjusted, because everything defined within `rustc_span::*` was
also available via `rustc_span::source_map::*`, which is bizarre.
The commit also removes `SourceMap::span_to_relative_line_string`, which
is unused.
new lint: `unnecessary_fallible_conversions`
Closes#11577
A new lint that looks for calls such as `i64::try_from(1i32)` and suggests `i64::from(1i32)`. See lint description (and linked issue) for more details for why.
There's a tiny bit of overlap with the `useless_conversion` lint, in that the other one warns `T::try_from(T)` (i.e., fallibly converting to the same type), so this lint ignores cases like `i32::try_from(1i32)` to avoid emitting two warnings for the same expression.
Also, funnily enough, with this one exception, this lint would warn on exactly every case in the `useless_conversion_try` ui test that `useless_conversion` didn't cover (but never two warnings at the same time), which is neat. I did add an `#![allow]` though since we don't want interleaved warnings from multiple lints in the same uitest.
changelog: new lint: `unnecessary_fallible_conversions`
fix enum_variant_names depending lint depending on order
changelog: [`enum_variant_names`]: fix single word variants preventing lint of later variant pre/postfixed with the enum name
fixes#11494
Single word variants prevented checking the `check_enum_start` and `check_enum_end` for being run on later variants
Use multiple pushes in `vec_init_then_push` example
Makes the perf argument clearer, since a single push doesn't have unnecessary allocations compared to `vec![x]`
changelog: none
Remove internal feature from clippy_utils
It's only used to gate a few `const`s, removing the feature gate means it doesn't have to be recompiled when moving between a normal and `-F internal` build/test/etc
changelog: none
ignore lower-camel-case words in `doc_markdown`
This fixes#11568 by ignoring camelCase words starting with a lower case letter.
r? `@blyxyas`
---
changelog: none
move `read_zero_byte_vec` to nursery
I think the concerns in #9274 are valid, and we should move this to nursery while we're reworking this.
changelog: [`read_zero_byte_vec`] moved to nursery
Expand docs on clippy::todo
https://doc.rust-lang.org/nightly/core/macro.todo.html describes that `todo!()` is intended for explicitly unfinished code. Explain this, and mention `unimplemented!()` as an alternative.
Whilst we're here, improve the punctuation on the other lints.
changelog: [`todo`]: expand docs
Fix missing parenthesis in suboptimal floating point help
This fixes#11559 by adding a branch in the `Neg` implementation for `Sugg` that adds parentheses to keep precedence in order, then using that in the suggestion. I also removed some needless `.to_string()`s while I was at it.
---
changelog: none
[`iter_without_into_iter`]: fix papercuts in suggestion and restrict linting to exported types
See #11692 for more context.
tldr: the lint `iter_without_into_iter` has suggestions that don't compile, which imo isn't that problematic because it does have the appropriate `Applicability` that tells external tools that it shouldn't be auto-applied.
However there were some obvious "errors" in the suggestion that really should've been included in my initial PR adding the lint, which is fixed by this PR:
- `IntoIterator::into_iter` needs a `self` argument.
- `IntoIterator::Iter` associated type doesn't exist. This should've just been `Item`.
This still doesn't make it machine applicable, and the remaining things are imho quite non-trivial to implement, as I've explained in https://github.com/rust-lang/rust-clippy/issues/11692#issuecomment-1773886111.
I personally think it's fine to leave it there and let the user change the remaining errors when copy-pasting the suggestion (e.g. errors caused by lifetimes that were permitted in fn return-position but are not in associated types).
This is how many of our other lint suggestions already work.
Also, we now restrict linting to only exported types. This required moving basically all of the tests around since they were previously in the `main` function. Same for `into_iter_without_iter`. The git diff is a bit useless here...
changelog: [`iter_without_into_iter`]: fix papercuts in suggestion and restrict linting to exported types
(cc `@lopopolo,` figured I should mention you since you created the issue)
https://doc.rust-lang.org/nightly/core/macro.todo.html
describes that `todo!()` is intended for explicitly unfinished
code. Explain this, and mention `unimplemented!()` as an alternative.
Whilst we're here, improve the punctuation on the other lints.
Add `waker_clone_and_wake` lint to check needless `Waker` clones
Check for patterns of `waker.clone().wake()` and replace them with `waker.wake_by_ref()`.
An alternative name could be `waker_clone_then_wake`
changelog: [ `waker_clone_wake`]: new lint
Remove the `internal_warn` lint category
`LINT_AUTHOR` and `DUMP_HIR` can be removed since their corresponding lint passes are only used for side effects
The metadata collector lint can be made an `internal` lint since `clippy::internal` is set to deny when running the collector
Also renames some internal lints/passes
changelog: none
Set doc-tests to `no_run`
This excludes `should_panic` tests, those are still run to ensure they panic. Most of our other doc snippets don't gain much from being run though so this frees up a nice bit of CI time
It also fixes the occasional issue such as `foo.txt`s being created f942470ca7/clippy_lints/src/permissions_set_readonly_false.rs (L19)
changelog: none
suggest passing function instead of calling it in closure for [`option_if_let_else`]
fixes: #11429
changelog: suggest passing function instead of calling it in closure for [`option_if_let_else`]
Skip if_not_else lint for '!= 0'-style checks
Currently, clippy makes unhelpful suggestions such as this:
```
warning: unnecessary `!=` operation
--> src/vm.rs:598:36
|
598 | *destination = if source & 0x8000 != 0 { 0xFFFF } else { 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: change to `==` and swap the blocks of the `if`/`else`
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#if_not_else
= note: `-W clippy::if-not-else` implied by `-W clippy::pedantic`
```
Bit tests often take on the form `if foo & 0x1234 != 0 { … } else { … }`, and the `!= 0` part reads as "has any bits set". Therefore, this code already has the "correct" order, and shouldn't be changed.
This PR disables the lint for these cases, and in fact all cases where the condition is "foo is non-zero".
I did my homework:
- \[X] Followed [lint naming conventions][lint_naming] → Not applicable, this PR fixes an existing lint
- \[X] Added passing UI tests (including committed `.stderr` file) → Yes, `tests/ui/if_not_else_bittest.rs`
- \[X] `cargo test` passes locally
- \[X] Executed `cargo dev update_lints`
- \[X] Added lint documentation → Not applicable, this PR fixes an existing lint
- \[X] Run `cargo dev fmt`
changelog: Fix [`if_not_else`] false positive when something like `bitflags != 0` is used
Now `declare_interior_mutable_const` and `borrow_interior_mutable_const` respect the `ignore-interior-mutability` configuration entry
Fix#10537
changelog: Now `declare_interior_mutable_const` and `borrow_interior_mutable_const` respect the `ignore-interior-mutability` configuration entry
[`map_identity`]: allow closure with type annotations
Fixes#9122
`.map(|a: u32| a)` can help type inference, so we should probably allow this and not warn about "unnecessary map of the identity function"
changelog: [`map_identity`]: allow closure with type annotations
Implement rustc part of RFC 3127 trim-paths
This PR implements (or at least tries to) [RFC 3127 trim-paths](https://github.com/rust-lang/rust/issues/111540), the rustc part. That is `-Zremap-path-scope` with all of it's components/scopes.
`@rustbot` label: +F-trim-paths
Deserialize `Msrv` directly in `Conf`
Gives the error a span pointing to the invalid config value
Also puts `Conf` itself in the `OnceLock` rather than just the `Msrv` for [the `register_late_mod_pass` work](https://github.com/rust-lang/rust/pull/116731) since it will be used from two different callbacks
changelog: none
add lint for struct field names
changelog: [`struct_field_names`]: lint structs with the same pre/postfix in all fields or with fields that are pre/postfixed with the name of the struct.
fixes#2555
I've followed general structure and naming from the code in [enum_variants](b788addfcc/clippy_lints/src/enum_variants.rs) lint, which implements the same logic for enum variants.
side effect for `enum_variants`:
use .first() instead of .get(0) in enum_variants lint
move to_camel_case to str_util module
move module, enum and struct name repetitions check to a single file `item_name_repetitions`
rename enum_variants threshold config option
Make `multiple_unsafe_ops_per_block` ignore await desugaring
The await desugaring contains two calls (`Poll::new_unchecked` and `get_context`) inside a single unsafe block. That violates the lint.
fixes#11312
changelog: [`multiple_unsafe_ops_per_block`]: fix false positives in `.await`
[`unnecessary_lazy_eval`]: reduce applicability if closure has return type annotation
Fixes#11672
We already check if closure parameters don't have type annotations and reduce the applicability to `MaybeIncorrect` if they do, since those help type inference and removing them breaks code. We didn't do this for return type annotations however. This PR adds it. This doesn't change it to produce a fix that will compile, but it will prevent rustfix from auto-applying it.
(In general I'm not sure if we can suggest a fix that will compile. In this specific example, it might be possible to suggest `&[] as &[u8]`, but as-casts won't always work, e.g. `Default::default() as &[u8]` is a compile error, so just reducing applicability should be a safe fix in any case for now)
changelog: [`unnecessary_lazy_eval`]: reduce applicability to `MaybeIncorrect` if closure has return type annotation
changelog: Now `declare_interior_mutable_const` and `borrow_interior_mutable_const` respect the `ignore-interior-mutability` configuration entry
Signed-off-by: slinkydeveloper <francescoguard@gmail.com>
[`get_first`]: lint on non-primitive slices
Fixes#11594
I left the issue open for a couple days before making the PR to see if anyone has something to say, but it looks like there aren't any objections to removing this check that prevented linting on non-primitive slices, so here's the PR now.
There's a couple of instances in clippy itself where we now emit the lint. The actual relevant change is in the first commit and fixing the `.get(0)` instances in clippy itself is in the 2nd commit.
changelog: [`get_first`]: lint on non-primitive slices
Fix/11134
Fix#11134
Hir of `qpath` will be `TypeRelative(Ty { kind: Path(LangItem...` when a closure contains macro (e.g. https://github.com/rust-lang/rust-clippy/issues/11651) and #11134, it causes panic.
This PR avoids panicking and emitting incomplete path string when `qpath` contains `LangItem`.
changelog: none
There are several that are unused and can be removed.
And there are some calls to `to_string`, which can be expressed more
nicely as a `foo_to_string` call, and then `to_string` need not be
`pub`. (This requires adding `pat_to_string`).
`impl_trait_in_params` now supports impls and traits
Before this PR, the lint `impl_trait_in_params`. This PR gives the lint support for functions in impls and traits. (Also, some pretty heavy refactor)
fixes#11548
changelog:[`impl_trait_in_params`] now supports `impl` blocks and functions in traits
Improve `redundant_locals` help message
Fixes#11625
AFAIK, `span_lint_and_help` points the beginning of spans when we pass multiple spans to the second argument, so This PR I also modified its help span and its message.
lint result of the given example in the issue will be:
```console
error: redundant redefinition of a binding `apple`
--> src/main.rs:5:5
|
5 | let apple = apple;
| ^^^^^^^^^^^^^^^^^^
|
help: `apple` is initially defined here
--> src/main.rs:4:9
|
4 | let apple = 42;
| ^^^^^
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_locals
```
I hope that this change might help reduce user confusion, but I'd appreciate alternative suggestions:)
changelog: [`redundant_locals`]: Now points at the rebinding of the variable
Fix `items_after_test_module` for non root modules, add applicable suggestion
Fixes#11050Fixes#11153
changelog: [`items_after_test_module`]: Now suggests a machine-applicable suggestion.
changelog: [`items:after_test_module`]: Also lints for non root modules
The word "active" is currently used in two different and confusing ways:
- `ACTIVE_FEATURES` actually means "available unstable features"
- `Features::active_features` actually means "features declared in the
crate's code", which can include feature within `ACTIVE_FEATURES` but
also others.
(This is also distinct from "enabled" features which includes declared
features but also some edition-specific features automatically enabled
depending on the edition in use.)
This commit changes the `Features::active_features` to
`Features::declared_features` which actually matches its meaning.
Likewise, `Features::active` becomes `Features::declared`.
std_instead_of_core: avoid lint inside of proc-macro
- fixes https://github.com/rust-lang/rust-clippy/issues/10198
note: The lint for the reported `thiserror::Error` has been suppressed by [Don't lint unstable moves in std_instead_of_core](https://github.com/rust-lang/rust-clippy/pull/9545/files#diff-2cb8a24429cf9d9898de901450d640115503a10454d692dddc6a073a299fbb7eR29) because `thiserror::Error` internally implements `std::error::Error for (derived struct)`.
changelog: [`std_intead_of_core`]: avoid linting inside proc-macro
I confirmed this change fixes the problem:
<details>
<summary>test result without the change</summary>
```console
error: used import from `std` instead of `core`
--> tests/ui/std_instead_of_core.rs:65:14
|
LL | #[derive(ImplStructWithStdDisplay)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the derive macro `ImplStructWithStdDisplay` (in Nightly builds, run with -Z macro-backtrace for more info)
```
</details>
Move `needless_pass_by_ref_mut`: `suspicious` -> `nursery`
[Related to [this Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/257328-clippy/topic/needless_pass_by_ref_mut.20isn't.20ready.20for.20stable)]
`needless_pass_by_ref_mut` has been released with some important bugs (notably having a lot of reported false positives and an ICE). So it may not be really ready for being in stable until these problems are solved. This PR changes the lint's category from `suspicious` to `nursery`, just that.
changelog: none
Partially outline code inside the panic! macro
This outlines code inside the panic! macro in some cases. This is split out from https://github.com/rust-lang/rust/pull/115562 to exclude changes to rustc.
There are cases where users create a unit variant for the purposes
of tracking the number of variants for an nonexhaustive enum.
We should check if an enum is explicitly marked as nonexhaustive
before reporting `manual_non_exhaustive` in these cases. Fixes#11583
new lint: `into_iter_without_iter`
Closes#9736 (part 2)
This implements the other lint that my earlier PR missed: given an `IntoIterator for &Type` impl, check that there exists an inherent `fn iter(&self)` method.
changelog: new lint: `into_iter_without_iter`
r? `@Jarcho` since you reviewed #11527 I figured it makes sense for you to review this as well?
[`manual_let_else`]: only omit block if span is from same ctxt
Fixes#11579.
The lint already had logic for omitting a block in `else` if a block is already present, however this didn't handle the case where the block is from a different expansion/syntax context. E.g.
```rs
macro_rules! panic_in_block {
() => { { panic!() } }
}
let _ = match Some(1) {
Some(v) => v,
_ => panic_in_block!()
};
```
It would see this in its expanded form as `_ => { panic!() }` and think it doesn't have to include a block in its suggestion because it is already there, however that's not true if it's from a different expansion like in this case.
changelog: [`manual_let_else`]: only omit block in suggestion if the block is from the same expansion
Clippy backport: Move needless_raw_string_hashes to pedantic
Really small backport this time. Context: https://github.com/rust-lang/rust-clippy/pull/11415#issuecomment-1739880932
I'd rather get this in 1.74 than waiting another release cycle.
r? `@Manishearth`
cc `@Mark-Simulacrum` This should be merged before beta is branched tomorrow.
mir_to_const improvements
This simplifies some code and also fixes the float array handling to properly take into account the `offset`, and to work with little-endian targets.
Fixes https://github.com/rust-lang/rust-clippy/issues/11488
changelog: none
Don't store lazyness in `DefKind::TyAlias`
1. Don't store lazyness of a type alias in its `DefKind`, but instead via a query.
2. This allows us to treat type aliases as lazy if `#[feature(lazy_type_alias)]` *OR* if the alias contains a TAIT, rather than having checks for both in separate parts of the codebase.
r? `@oli-obk` cc `@fmease`
subst -> instantiate
continues #110793, there are still quite a few uses of `subst` and `substitute`, but changing them all in the same PR was a bit too much, so I've stopped here for now.
prevent ice when threshold is 0 and enum has no variants
changelog: [`enum_variant_names`]: prevent ice when threshold is 0 and enum has no variants
r? `@y21`
Fixes the same ice issue raised during review of https://github.com/rust-lang/rust-clippy/pull/11496
Fix large_futures example
The value used in the large_futures example was not large enough to trigger the lint given the default threshold. The example also contained more code than necessary. This PR changes the value size from 1kB to 16kB and reduces the example in size.
changelog: [`large_futures`]: Fix and simplify example
fixed fp caused by moving &mut reference inside of a closure
changelog: [`needless_pass_by_ref mut`]: fixes false positive caused by not covering mutable references passed to a closure inside of a fuction
fixes#11545
The value used in the large_futures example was not large enough to
trigger the lint given the default threshold.
The example also contained more code than necessary.
This PR changes the value size from 1kB to 16kB and reduces the example
in size.
Remove most usage of `hir_ty_to_ty`
Removes the usages where there's a suitable query or the type was already available elsewhere. The remaining cases would all require more involved changes
changelog: none
r? `@Jarcho`
fix FP with needless_raw_string_hashes
changelog: Fix [`needless_raw_string_hashes`]: Continue the lint checking of raw string when `needless_raw_strings` is allowed.
fix#11420
rename mir::Constant -> mir::ConstOperand, mir::ConstKind -> mir::Const
Also, be more consistent with the `to/eval_bits` methods... we had some that take a type and some that take a size, and then sometimes the one that takes a type is called `bits_for_ty`.
Turns out that `ty::Const`/`mir::ConstKind` carry their type with them, so we don't need to even pass the type to those `eval_bits` functions at all.
However this is not properly consistent yet: in `ty` we have most of the methods on `ty::Const`, but in `mir` we have them on `mir::ConstKind`. And indeed those two types are the ones that correspond to each other. So `mir::ConstantKind` should actually be renamed to `mir::Const`. But what to do with `mir::Constant`? It carries around a span, that's really more like a constant operand that appears as a MIR operand... it's more suited for `syntax.rs` than `consts.rs`, but the bigger question is, which name should it get if we want to align the `mir` and `ty` types? `ConstOperand`? `ConstOp`? `Literal`? It's not a literal but it has a field called `literal` so it would at least be consistently wrong-ish...
``@oli-obk`` any ideas?
[`redundant_guards`]: lint if the pattern is on the left side
A tiny improvement to the `redundant_guards` lint. There's no associated issue for this, just noticed it while going through the code.
Right now it warns on `Some(x) if x == 2` and suggests `Some(2)`, but it didn't do that for `Some(x) if 2 == x` (i.e. when the local is on the right side and the pattern on the left side).
changelog: [`redundant_guards`]: also lint if the pattern is on the left side
Change defaults of `accept-comment-above-statement` and `accept-comment-above-attributes`
This patch sets the two configuration options for `undocumented_unsafe_blocks` to `true` by default: these are `accept-comment-above-statement` and `accept-comment-above-attributes`. Having these values `false` by default prevents what many users would consider clean code, e.g. placing the `// SAFETY:` comment above a single-line functino call, rather than directly next to the argument.
This was originally discussed in https://github.com/rust-lang/rust-clippy/issues/11162
changelog: [`undocumented_unsafe_blocks`]: set
`accept-comment-above-statement` and `accept-comment-above-attributes` to `true` by default.
Fix mutaby used async function argument in closure for `needless_pass_by_ref_mut`
Fixes https://github.com/rust-lang/rust-clippy/issues/11380.
The problem was that it needed to go through closures as well in async functions to correctly find the mutable usage of async function arguments.
changelog: Correctly handle mutable usage of async function arguments in closures.
r? `@Centri3`
This patch sets the two configuration options for
`undocumented_unsafe_blocks` to `true` by default: these are
`accept-comment-above-statement` and `accept-comment-above-attributes`.
Having these values `false` by default prevents what many users would
consider clean code, e.g. placing the `// SAFETY:` comment above a
single-line functino call, rather than directly next to the argument.
changelog: [`undocumented_unsafe_blocks`]: set
`accept-comment-above-statement` and `accept-comment-above-attributes`
to `true` by default.
Add redundant_as_str lint
This lint checks for `as_str` on a `String` immediately followed by `as_bytes` or `is_empty` as those methods are available on `String` too. This could possibly also be extended to `&[u8]` in the future.
changelog: New lint [`redundant_as_str`] #11526
move required_consts check to general post-mono-check function
This factors some code that is common between the interpreter and the codegen backends into shared helper functions. Also as a side-effect the interpreter now uses the same `eval` functions as everyone else to get the evaluated MIR constants.
Also this is in preparation for another post-mono check that will be needed for (the current hackfix for) https://github.com/rust-lang/rust/issues/115709: ensuring that all locals are dynamically sized.
I didn't expect this to change diagnostics, but it's just cycle errors that change.
r? `@oli-obk`
This lint checks for `as_str` on a `String` immediately followed by `as_bytes` or `is_empty` as those methods are available on `String` too. This could possibly also be extended to `&[u8]` in the future.
Split `needless_borrow` into two lints
Splits off the case where the borrow is used as a generic argument to a function. I think the two cases are different enough to warrant a separate lint.
The tests for the new lint have been reordered to group related parts together. Two warning have been dropped, one looked like it was testing the generic argument form, but it ends up triggering the auto-deref variant. The second was just a redundant test that didn't do anything interesting.
An issue with cycle detection is also included. The old version was checking if a cycle was reachable from a block when it should have been checking if the block is part or a cycle.
As a side note, I'm liking the style of just jamming all the tests into separate scopes in main.
changelog: Split off `needless_borrows_for_generic_args` from `needless_borrow`
[`filter_map_bool_then`]: include multiple derefs from adjustments
In #11506 this lint was improved to suggest one deref if the bool is behind references (fixed the FP #11503), however it might need multiple dereferences if the bool is behind multiple layers of references or custom derefs. E.g. `&&&bool` needs `***b`.
changelog: [`filter_map_bool_then`]: suggest as many dereferences as there are needed to get to the bool
add extra `byref` checking for the guard's local
changelog: [`redundant_guards`]: Now checks if the variable is bound using `ref` before linting.
The lint should not be emitted, when the local variable is bind by-ref in the pattern.
fixes#11465
[`useless_conversion`]: don't lint if type parameter has unsatisfiable bounds for `.into_iter()` receiver
Fixes#11300.
Before this PR, clippy assumed that if it sees a `f(x.into_iter())` call and the type at that argument position is generic over any `IntoIterator`, then the `.into_iter()` call must be useless because `x` already implements `IntoIterator`, *however* this assumption is not right if the generic parameter has more than just the `IntoIterator` bound (because other traits can be implemented for the IntoIterator target type but not the IntoIterator implementor, as can be seen in the linked issue: `<[i32; 3] as IntoIterator>::IntoIter` satisfies `ExactSizeIterator`, but `[i32; 3]` does not).
So, this PR makes it check that the type parameter only has a single `IntoIterator` bound. It *might* be possible to check if the type of `x` in `f(x.into_iter())` satisfies all the bounds on the generic type parameter as defined on the function (which would allow removing the `.into_iter()` call even with multiple bounds), however I'm not sure how to do that, and the current fix should always work.
**Edit:** This PR has been changed to check if any of the bounds don't hold for the type of the `.into_iter()` receiver, so we can still lint in some cases.
changelog: [`useless_conversion`]: don't lint `.into_iter()` if type parameter has multiple bounds
fix filter_map_bool_then with a bool reference
changelog: [`filter_map_bool_then`]: Fix the incorrect autofix when the `bool` in question is a reference.
fix#11503
[`extra_unused_type_parameters`]: Fix edge case FP for parameters in where bounds
Generic parameters can end up being used on the left side of where-bounds if they are not directly bound but instead appear nested in some concrete generic type. Therefore, we should walk the left side of where bounds, but only if the bounded type is *not* a generic param, in which case we still need to ignore the bound.
Fixes#11302
changelog: [`extra_unused_type_parameters`]: Fix edge case false positive for parameters in where bounds
Ignore closures for some type lints
Fixes#11417
`hir_ty_to_ty` is used in a couple of the `!is_local` lints, which doesn't play nicely inside bodies
changelog: none
Improve invalid let expression handling
- Move all of the checks for valid let expression positions to parsing.
- Add a field to ExprKind::Let in AST/HIR to mark whether it's in a valid location.
- Suppress some later errors and MIR construction for invalid let expressions.
- Fix a (drop) scope issue that was also responsible for #104172.
Fixes#104172Fixes#104868
treat host effect params as erased in codegen
This fixes the changes brought to codegen tests when effect params are added to libcore, by not attempting to monomorphize functions that get the host param by being `const fn`.
r? `@oli-obk`
This fixes the changes brought to codegen tests when effect params are
added to libcore, by not attempting to monomorphize functions that get
the host param by being `const fn`.
[`len_without_is_empty`]: follow type alias to find inherent `is_empty` method
Fixes#11165
When we see an `impl B` and `B` is a type alias to some type `A`, then we need to follow the type alias to look for an `is_empty` method on the aliased type `A`. Before this PR, it'd get the inherent impls of `B`, which there aren't any and so it would warn that there isn't an `is_empty` method even if there was one.
Passing the type alias `DefId` to `TyCtxt::type_of` gives us the aliased `DefId` (or simply return the type itself if it wasn't a type alias) so we can just use that
changelog: [`len_without_is_empty`]: follow type alias to find inherent `is_empty` method
[`implied_bounds_in_impls`]: include (previously omitted) associated types in suggestion
Fixes#11435
It now includes associated types from the implied bound that were omitted in the second bound. Example:
```rs
fn f() -> impl Iterator<Item = u8> + ExactSizeIterator> {..}
```
Suggestion before this change:
```diff
- pub fn my_iter() -> impl Iterator<Item = u32> + ExactSizeIterator {
+ pub fn my_iter() -> impl ExactSizeIterator {
```
It didn't include `<Item = u32>` on `ExactSizeIterator`. Now, with this change, it does.
```diff
- pub fn my_iter() -> impl Iterator<Item = u32> + ExactSizeIterator {
+ pub fn my_iter() -> impl ExactSizeIterator<Item = u32> {
```
We also now extend the span to include not just possible `+` ahead of it, but also behind it (an example for this is in the linked issue as well).
**Note:** The overall diff is a bit noisy, because building up the suggestion involves quite a bit more logic now and I decided to extract that into its own function. For that reason, I split this PR up into two commits. The first commit contains the actual "logic" changes. Second commit just moves code around.
changelog: [`implied_bounds_in_impls`]: include (previously omitted) associated types in suggestion
changelog: [`implied_bounds_in_impls`]: include the `+` behind bound if it's the last bound
Rename incorrect_impls to non_canonical_impls, move them to warn by default
The wording/category of these feel too strong to me, I would expect most of the time it's linting the implementations aren't going to be *incorrect*, just unnecessary
changelog: rename `incorrect_clone_impl_on_copy_type` to [`non_canonical_clone_impl`]
changelog: rename `incorrect_partial_ord_impl_on_ord_type` to [`non_canonical_partial_ord_impl`]
changelog: Move [`non_canonical_clone_impl`], [`non_canonical_partial_ord_impl`] to suspicious
Preserve literals and range kinds in `manual_range_patterns`
Fixes#11461
Also enables linting when there are 3 or fewer alternatives if one of them is already a range pattern
changelog: none
[`slow_vector_initialization`]: use the source span of vec![] macro and fix another FP
Fixes#11408
<details>
<summary>Also fixes a FP when the vec initializer comes from a macro other than `vec![]`</summary>
```rs
macro_rules! x {
() => { vec![] }
}
fn f() {
let mut v = x!();
v.resize(10, 0);
}
```
This shouldn't warn. The `x!` macro might be doing other things, so just replacing `x!()` with `vec![0; 10]` is not always an option.
</details>
I added some test cases for macro expansions, however I don't think there's a way to write a test for that specific warning that appeared in the linked issue. As far as I understand, that happens when the rust-src rustup component isn't installed (so the stdlib source is unavailable) and the span points to the `vec![]` *expansion*, instead of the `vec![]` that the user wrote.
changelog: [`slow_vector_initialization`]: use the source span of `vec![]` macro
changelog: [`slow_vector_initialization`]: only warn on `vec![]` expansions and allow other macros
fix fp when [`undocumented_unsafe_blocks`] not able to detect comment on globally defined const/static variables
fixes: #11246
changelog: fix detection on global variables for [`undocumented_unsafe_blocks`]
skip `todo!()` in `never_loop`
As promised in #11450, here is an implementation which skips occurrences of the `todo!()` macro.
changelog: [`never_loop`]: skip loops containing `todo!()`
Don't pass extra generic arguments in `needless_borrow`
fixes#10253
Also switches to using `implements_trait` which does ICE when clippy's debug assertions are enabled.
changelog: None
[`implied_bounds_in_impls`]: don't ICE on default generic parameter and move to nursery
Fixes#11422
This fixes two ICEs ([1](https://github.com/rust-lang/rust-clippy/issues/11422#issue-1872351763), [2](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2901e6febb479d3bd2a74f8a5b8a9305)), and moves it to nursery for now, because this lint needs some improvements in its suggestion (see #11435, for one such example).
changelog: Moved [`implied_bounds_in_impls`] to nursery (Now allow-by-default)
[#11437](https://github.com/rust-lang/rust-clippy/pull/11437)
changelog: [`implied_bounds_in_impls`]: don't ICE on default generic parameter in supertrait clause
r? `@xFrednet` (since you reviewed my PR that added this lint, I figured it might make sense to have you review this as well since you have seen this code before. If you don't want to review this, sorry! Feel free to reroll then)
--------
As for the ICE, it's pretty complicated and very confusing imo, so I'm going to try to explain the idea here (partly for myself, too, because I've confused myself several times writing- and fixing this):
<details>
<summary>Expand</summary>
The general idea behind the lint is that, if we have this function:
```rs
fn f() -> impl PartialEq<i32> + PartialOrd<i32> { 0 }
```
We want to lint the `PartialEq` bound because it's unnecessary. That exact bound is already specified in `PartialOrd<i32>`'s supertrait clause:
```rs
trait PartialOrd<Rhs>: PartialEq<Rhs> {}
// PartialOrd<i32>: PartialEq<i32>
```
The way it does this is in two steps:
- Go through all of the bounds in the `impl Trait` return type and collect each of the trait's supertrait bounds into a vec. We also store the generic arguments for later.
- `PartialEq` has no supertraits, nothing to add.
- `PartialOrd` is defined as `trait PartialOrd: PartialEq`, so add `PartialEq` to the list, as well as the generic argument(s) `<i32>`
Once we are done, we have these entries in the vec: `[(PartialEq, [i32])]`
- Go through all the bounds again, and looking for those bounds that have their trait `DefId` in the implied bounds vec.
- `PartialEq` is in that vec. However, that is not enough, because the trait is generic. If the user wrote `impl PartialEq<String> + PartialOrd<i32>`, then `PartialOrd` clearly doesn't imply `PartialEq`. Which means, we also need to check that the generic parameters match. This is why we also collected the generic arguments in `PartialOrd<i32>`. This process of checking generic arguments is pretty complicated and is also where the two ICEs happened.
The way it checks that the generic arguments match is by comparing the generic parameters in the super trait clause:
```rs
trait PartialOrd<Rhs>: PartialEq<Rhs> {}
// ^^^^^^^^^^^^^^
```
...this needs to match...
```rs
fn f() -> impl PartialEq<i32> + ...
// ^^^^^^^^^^^^^^
```
In the compiler, the `Rhs` generic parameter is its own type and we cannot just compare it to `i32`. We need to "substitute" it.
Internally, `Rhs` is represented as `Rhs#1` (the number next to # represents the type parameter index. They start at 0, but 0 is "reserved" for the implicit `Self` generic parameter).
How do we go from `Rhs#1` to `i32`? Well, we know that all the generic parameters had to be substituted in the `impl ... + PartialOrd<i32>` type. So we subtract 1 from the type parameter index, giving us 0 (`Self` is not specified in that list of arguments). We use that as the index into the generic argument list `<i32>`. That's `i32`. Now we know that the supertrait clause looks like `: PartialEq<i32>`.
Then, we can compare that to what the user actually wrote on the bound that we think is being implied: `impl PartialEq<i32> + ...`.
Now to the actual bug: this whole logic doesn't take into account *default* generic parameters. Actually, `PartialOrd` is defined like this:
```rs
trait PartialOrd<Rhs = Self>: PartialEq<Rhs> {}
```
If we now have a function like this:
```rs
fn f() -> impl PartialOrd + PartialEq {}
```
that logic breaks apart... We look at the supertrait predicate `: PartialEq<Rhs>` (`Rhs` is `Rhs#1`), then take the first argument in the generic argument list `PartialEq<..>` to resolve the `Rhs`, but at this point we crash because there *is no* generic argument.
The index 0 is out of bounds. If this happens (and we even get to linting here, which could only happen if it passes typeck), it must mean that that generic parameter has a default type that is not required to be specified.
This PR changes the logic such that if we have a type parameter index that is out of bounds, it looks at the definition of the trait and check that there exists a default type that we can use instead.
So, we see `<Rhs = Self>`, and use `Self` for substitution, and end up with this predicate: `: PartialEq<Self>`. No crash this time.
</details>
`never_loop` catches `loop { panic!() }`
* Depends on: #11447
This is an outgrowth of #11447 which I felt would best be done as a separate PR because it yields significant new results.
This uses typecheck results to determine divergence, meaning we can now detect cases like `loop { std::process::abort() }` or `loop { panic!() }`. A downside is that `loop { unimplemented!() }` is also being linted, which is arguably a false positive. I'm not really sure how to check this from HIR though, and it seems best to leave this epicycle for a later PR.
changelog: [`never_loop`]: Now lints on `loop { panic!() }` and similar constructs
Fix span when linting `explicit_auto_deref` immediately after `needless_borrow`
fixes#11366
changelog: `explicit_auto_deref`: Fix span when linting immediately after `needless_borrow`
Add config flag for reborrows in explicit_iter_loop
This PR adds a config flag for enforcing explicit into iter lint for reborrowed values. The config flag, `enforce_iter_loop_reborrow`, can be added to clippy.toml files to enable the linting behaviour. By default the reborrow lint is disabled.
fixes: #11074
changelog: [`explicit_iter_loop`]: add config flag `enforce_iter_loop_reborrow` to disable reborrow linting by default
new lint: `iter_out_of_bounds`
Closes#11345
The original idea in the linked issue seemed to be just about arrays afaict, but I extended this to catch some other iterator sources such as `iter::once` or `iter::empty`.
I'm not entirely sure if this name makes a lot of sense now that it's not just about arrays anymore (specifically, not sure if you can call `.take(1)` on an `iter::Empty` to be "out of bounds"?).
changelog: [`iter_out_of_bounds`]: new lint
[`unnecessary_unwrap`]: lint on `.as_ref().unwrap()`
Closes#11371
This turned out to be a little more code than I originally thought, because the lint also makes sure to not lint if the user tries to mutate the option:
```rs
if option.is_some() {
option = None;
option.unwrap(); // don't lint here
}
```
... which means that even if we taught this lint to recognize `.as_mut()`, it would *still* not lint because that would count as a mutation. So we need to allow `.as_mut()` calls but reject other kinds of mutations.
Unfortunately it doesn't look like this is possible with `is_potentially_mutated` (seeing what kind of mutation happened).
This replaces it with a custom little visitor that does basically what it did before, but also allows `.as_mut()`.
changelog: [`unnecessary_unwrap`]: lint on `.as_ref().unwrap()`
skip float_cmp check if lhs is a custom type
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: [`float_cmp`]: allow float eq comparison when lhs is a custom type that implements PartialEq<f32/f64>
If the lhs of a comparison is not float, it means there is a user implemented PartialEq, and the caller is invoking that custom version of `==`, instead of the default floating point equal comparison.
People may wrap f32 with a struct (say `MyF32`) and implement its PartialEq that will do the `is_close()` check, so that `MyF32` can be compared with either f32 or `MyF32`.