improve the suggestion of the lint `unit-arg`
Fixes#5823Fixes#6015
Changes
```
help: move the expression in front of the call...
|
3 | g();
|
help: ...and use a unit literal instead
|
3 | o.map_or((), |i| f(i))
|
```
into
```
help: move the expression in front of the call and replace it with the unit literal `()`
|
3 | g();
| o.map_or((), |i| f(i))
|
```
changelog: improve the suggestion of the lint `unit-arg`
Add CONST_ITEM_MUTATION lint
Fixes#74053Fixes#55721
This PR adds a new lint `CONST_ITEM_MUTATION`.
Given an item `const FOO: SomeType = ..`, this lint fires on:
* Attempting to write directly to a field (`FOO.field = some_val`) or
array entry (`FOO.array_field[0] = val`)
* Taking a mutable reference to the `const` item (`&mut FOO`), including
through an autoderef `FOO.some_mut_self_method()`
The lint message explains that since each use of a constant creates a
new temporary, the original `const` item will not be modified.
* Remove the mention to `Rc` and `Arc` as these are `Freeze`
so the lint correctly handles already.
* Instead, explain what could cause a false positive,
and mention `bytes` as an example.
We no longer lint assignments to const item fields in the
`temporary_assignment` lint, since this is now covered by the
`CONST_ITEM_MUTATION` lint.
Additionally, we `#![allow(const_item_mutation)]` in the
`borrow_interior_mutable_const.rs` test. Clippy UI tests are run with
`-D warnings`, which seems to cause builtin lints to prevent Clippy
lints from running.
Support dataflow problems on arbitrary lattices
This PR implements last of the proposed extensions I mentioned in the design meeting for the original dataflow refactor. It extends the current dataflow framework to work with arbitrary lattices, not just `BitSet`s. This is a prerequisite for dataflow-enabled MIR const-propagation. Personally, I am skeptical of the usefulness of doing const-propagation pre-monomorphization, since many useful constants only become known after monomorphization (e.g. `size_of::<T>()`) and users have a natural tendency to hand-optimize the rest. It's probably worth exprimenting with, however, and others have shown interest cc `@rust-lang/wg-mir-opt.`
The `Idx` associated type is moved from `AnalysisDomain` to `GenKillAnalysis` and replaced with an associated `Domain` type that must implement `JoinSemiLattice`. Like before, each `Analysis` defines the "bottom value" for its domain, but can no longer override the dataflow join operator. Analyses that want to use set intersection must now use the `lattice::Dual` newtype. `GenKillAnalysis` impls have an additional requirement that `Self::Domain: BorrowMut<BitSet<Self::Idx>>`, which effectively means that they must use `BitSet<Self::Idx>` or `lattice::Dual<BitSet<Self::Idx>>` as their domain.
Most of these changes were mechanical. However, because a `Domain` is no longer always a powerset of some index type, we can no longer use an `IndexVec<BasicBlock, GenKillSet<A::Idx>>>` to store cached block transfer functions. Instead, we use a boxed `dyn Fn` trait object. I discuss a few alternatives to the current approach in a commit message.
The majority of new lines of code are to preserve existing Graphviz diagrams for those unlucky enough to have to debug dataflow analyses. I find these diagrams incredibly useful when things are going wrong and considered regressing them unacceptable, especially the pretty-printing of `MovePathIndex`s, which are used in many dataflow analyses. This required a parallel `fmt` trait used only for printing dataflow domains, as well as a refactoring of the `graphviz` module now that we cannot expect the domain to be a `BitSet`. Some features did have to be removed, such as the gen/kill display mode (which I didn't use but existed to mirror the output of the old dataflow framework) and line wrapping. Since I had to rewrite much of it anyway, I took the opportunity to switch to a `Visitor` for printing dataflow state diffs instead of using cursors, which are error prone for code that must be generic over both forward and backward analyses. As a side-effect of this change, we no longer have quadratic behavior when writing graphviz diagrams for backward dataflow analyses.
r? `@pnkfelix`
Fix FP in `same_item_push`
Don't emit a lint when the pushed item doesn't have Clone trait
Fix#5979
changelog: Fix FP in `same_item_push` not to emit a lint when the pushed item doesn't have Clone trait
useless_attribute: Permit wildcard_imports and enum_glob_use
Fixes#5918
changelog: `useless_attribute`: Permit `wildcard_imports` and `enum_glob_use` on `use` items
default_trait_access: Fix wrong suggestion
https://github.com/rust-lang/rust-clippy/issues/5975#issuecomment-683751131
> I think the underlying problem is clippy suggests code with complete parameters, not clippy triggers this lint even for complex types. AFAIK, If code compiles with `Default::default`, it doesn't need to specify any parameters, as type inference is working. (So, in this case, `default_trait_access` should suggest `RefCell::default`.)
Fixes#5975Fixes#5990
changelog: `default_trait_access`: fixed wrong suggestion
Add a lint for an async block/closure that yields a type that is itself awaitable.
This catches bugs of the form
tokio::spawn(async move {
let f = some_async_thing();
f // Oh no I forgot to await f so that work will never complete.
});
See the two XXXkhuey comments and the unfixed `_l` structure for things that need more thought.
*Please keep the line below*
changelog: none
or_fn_call: ignore nullary associated const fns
The fix in #5889 was missing associated functions.
changelog: Ignore also `const fn` methods in [`or_fun_call`]
Fixes#5693
This catches bugs of the form
tokio::spawn(async move {
let f = some_async_thing();
f // Oh no I forgot to await f so that work will never complete.
});
Fix FP in `to_string_in_display`
Don't emit a lint when `.to_string()` on anything that is not `self`
Fix#5967
changelog: Fix FP in `to_string_in_display` when calling `.to_string()` on anything that is not `self`
Corrects the float_equality_without_abs lint
Fixes an issue in the `float_equality_without_abs` lint. The lint suggestion was configured in a way that it lints the whole error and not just the subtraction part. In the current configuration the lint would suggest to change the expression in a wrong way, e.g.
```rust
let _ = (a - b) < f32::EPSILON; // before
let _ = (a - b).abs(); // after
```
This was dicovered by @flip1995. (See discussion of PR #5952).
Also the suggestion is now formatted via `utils::sugg`.
changelog: none
Fix `let_and_return` bad suggestion
Add a cast to the suggestion when the return expression has adjustments.
These adjustments are lost when the suggestion is applied.
This is similar to the problem in issue #4437.
Closes#5729
changelog: Fix `let_and_return` bad suggestion
Fix fp in `borrow_interior_mutable_const`
fixes#5796
changelog: fix false positive in `borrow_interior_mutable_const` when referencing a field behind a pointer.
Fix incorrect suggestion when `clone_on_ref_ptr` is triggered in macros
In the lint `clone_on_ref_ptr`, if the `span` is in a macro, don't expand it for suggestion.
Fixes: #2076
changelog: none
r? @ebroto
Add a cast to the suggestion when the return expression has adjustments.
These adjustments are lost when the suggestion is applied.
This is similar to the problem in issue #4437.
Closes#5729
Don't lint if it has always inline attribute
Don't trigger the lint `trivially_copy_pass_by_ref` if it has `#[inline(always)]` attribute.
Note: I am not particularly familiar with `inline` impacts, so I implemented this the way that if only `#[inline]` attribute is here (without `always`), the lint will still trigger. Also, it will still trigger if it has `#[inline(never)]`.
Just tell me if it sounds too much conservative.
Fixes: #5876
changelog: none
Prelude imports are exempt from wildcard import warnings. Until now only
imports of the form
```
use ...::prelude::*;
```
were considered. This change makes it so that the segment `prelude` can
show up anywhere, for instance:
```
use ...::prelude::v1::*;
```
Fixes#5917
Fix false positive in `PRECEDENCE` lint
Extend the lint to handle chains of methods combined with unary negation.
Closes#5924
changelog: Fix false negative in `PRECEDENCE` lint
This extends PR #73293 to handle patterns (Pat). Unlike expressions,
patterns do not support custom attributes, so we only need to capture
tokens during macro_rules! argument parsing.
Warn about assignments where left-hand side place expression is the same
as right-hand side value expression. For example, warn about assignment in:
```rust
pub struct Event {
id: usize,
x: i32,
y: i32,
}
pub fn copy_position(a: &mut Event, b: &Event) {
a.x = b.x;
a.y = a.y;
}
```
Add unnecessary lazy evaluation lint
changelog: Add [`unnecessary_lazy_evaluations`] lint that checks for usages of `unwrap_or_else` and similar functions that can be simplified.
Closes#5715
should_impl_trait - ignore methods with lifetime params
Fixes: #5617
changelog: don't lint should_implement_trait when an `Iterator::next` case has explicit parameters
Fix: keep parenthesis for suggestion in `useless_conversion` lint
Note: this lint was previously named `identity_conversion`.
fixes: #4750
changelog: fix parenthesis for `useless_conversion` lint suggestion
Add the other overloadable operations to suspicious_arithmetic_impl
In #2268 I idly mused that the other user-overloadable operations could be added to this lint. Knowing that the lint was arguably incomplete was gnawing at the back of my mind, so I figured that I might as well make this PR, particularly given the change needed was so small.
changelog: Start warning on suspicious implementations of the `BitAnd`, `BitOr`, `BitXor`, `Rem`, `Shl`, and `Shr` traits.
In #2268 I idly mused that the other user-overloadable operations could be added to this lint. Knowing that the lint was arguably incomplete was gnawing at the back of my mind, so I figured that I might as well make this PR, particularly given the change needed was so small.
Miri: Renamed "undef" to "uninit"
Renamed remaining references to "undef" to "uninit" when referring to Miri.
Impacted directories are:
- `src/librustc_codegen_llvm/consts.rs`
- `src/librustc_middle/mir/interpret/`
- `src/librustc_middle/ty/print/pretty.rs`
- `src/librustc_mir/`
- `src/tools/clippy/clippy_lints/src/consts.rs`
Upon building Miri based on the new changes it was verified that no changes needed to be made with the Miri project.
Related issue #71193
make a bunch of lints texts adhere to rustc dev guide
According to the rustc-dev guide: "The text should be matter of fact and avoid capitalization and periods, unless multiple sentences are needed"
changelog: make some lint output adhere to the rustc-dev guide
enable #[allow(clippy::unsafe_derive_deserialize)]
Before this change this lint could not be allowed as the code we are checking is automatically generated.
changelog: Enable using the `allow` attribute on top of an ADT linted by [`unsafe_derive_deserialize`].
Fixes: #5789
Fix ICE in `loops` module
changelog: Fix ICE related to `needless_collect` when a call to `iter()` was not present.
I went for restoring the old suggestion of `next().is_some()` over `get(0).is_some()` given that `iter()` is not necessarily present (could be e.g. `into_iter()` or `iter_mut()`) and that the old suggestion could change semantics, e.g. a call to `filter()` could be present between `iter()` and the collect part.
Fixes#5872
Renamed remaining references to "undef" to "uninit" when referring to Miri.
Impacted directories are:
- src/librustc_codegen_llvm/consts.rs
- src/librustc_middle/mir/interpret/
- src/librustc_middle/ty/print/pretty.rs
- src/librustc_mir/
- src/tools/clippy/clippy_lints/src/consts.rs
Upon building Miri based on the new changes it was verified that no changes needed to be made with the Miri project.
Related issue #71193
By moving `{known,used}_attrs` from `SessionGlobals` to `Session`. This
means they are accessed via the `Session`, rather than via TLS. A few
`Attr` methods and `librustc_ast` functions are now methods of
`Session`.
All of this required passing a `Session` to lots of functions that didn't
already have one. Some of these functions also had arguments removed, because
those arguments could be accessed directly via the `Session` argument.
`contains_feature_attr()` was dead, and is removed.
Some functions were moved from `librustc_ast` elsewhere because they now need
to access `Session`, which isn't available in that crate.
- `entry_point_type()` --> `librustc_builtin_macros`
- `global_allocator_spans()` --> `librustc_metadata`
- `is_proc_macro_attr()` --> `Session`
try_err: Consider Try impl for Poll when generating suggestions
There are two different implementation of `Try` trait for `Poll` type:
`Poll<Result<T, E>>` and `Poll<Option<Result<T, E>>>`. Take them into
account when generating suggestions.
For example, for `Err(e)?` suggest either `return Poll::Ready(Err(e))` or
`return Poll::Ready(Some(Err(e)))` as appropriate.
Fixes#5855
changelog: try_err: Consider Try impl for Poll when generating suggestions
Add derive_ord_xor_partial_ord lint
Fix#1621
Some remarks:
This PR follows the example of the analogous derive_hash_xor_partial_eq lint where possible.
I initially tried using the `match_path` function to identify `Ord` implementation like the derive_hash_xor_partial_eq lint currently does, for `Hash` implementations but that didn't work.
Specifically, the structs at the top level were getting paths that matched `&["$crate", "cmp", "Ord"]` instead of `&["std", "cmp", "Ord"]`. While trying to figure out what to do instead I saw the comment at the top of [clippy_lints/src/utils/paths.rs](f5d429cd76/clippy_lints/src/utils/paths.rs (L5)) that mentioned [this issue](https://github.com/rust-lang/rust-clippy/issues/5393) and suggested to use diagnostic items instead of hardcoded paths whenever possible. I looked for a way to identify `Ord` implementations with diagnostic items, but (possibly because this was the first time I had heard of diagnostic items,) I was unable to find one.
Eventually I tried using `get_trait_def_id` and comparing `DefId` values directly and that seems to work as expected. Maybe there's a better approach however?
changelog: new lint: derive_ord_xor_partial_ord
Handle mapping to Option in `map_flatten` lint
Fixes#4496
The existing [`map_flatten`](https://rust-lang.github.io/rust-clippy/master/index.html#map_flatten) lint suggests changing `expr.map(...).flatten()` to `expr.flat_map(...)` when `expr` is `Iterator`. This PR changes suggestion to `filter_map` instead of `flat_map` when mapping to `Option`, because it is more natural
Also here are some questions:
* If expression has type which implements `Iterator` trait (`match_trait_method(cx, expr, &paths::ITERATOR) == true`), how can I get type of iterator elements? Currently I use return type of closure inside `map`, but probably it is not good way
* I would like to change suggestion range to cover only `.map(...).flatten()`, that is from:
```
let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| 0..x).flatten().collect();
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `flat_map` instead: `vec![5_i8; 6].into_iter().flat_map
```
to
```
let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| 0..x).flatten().collect();
^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `flat_map` instead: `.flat_map(|x| 0..x)`
```
Is it ok?
* Is `map_flatten` lint intentionally in `pedantic` category, or could it be moved to `complexity`?
changelog: Handle mapping to Option in [`map_flatten`](https://rust-lang.github.io/rust-clippy/master/index.html#map_flatten) lint
needless_collect: catch x: Vec<_> = iter.collect(); x.into_iter() ...
changelog: Expand the needless_collect lint as suggested in #5627 (WIP).
This PR is WIP because I can't figure out how to make the multi-part suggestion include its changes in the source code (the fixed is identical to the source, despite the lint making suggestions). Aside from that one issue, I think this should be good.
For consistency with `Attribute::has_name` which doesn't mark the attribute as used either.
Replace all uses of `check_name` with `has_name` outside of rustc