Extend `needless_lifetimes` to suggest eliding `impl` lifetimes
Example:
```
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:332:10
|
LL | impl<'a> Foo for Baz<'a> {}
| ^^ ^^
|
help: elide the lifetimes
|
LL - impl<'a> Foo for Baz<'a> {}
LL + impl Foo for Baz<'_> {}
```
The main change is in how `impl` lifetime uses are tracked. Previously, a hashmap was created, and lifetimes were removed from the hashmap as their uses were discovered. However, the uses are needed to generate elision suggestions. So, now, uses are added to the hashmap as they are discovered.
The PR is currently organized as six commits, which I think are self-explanatory:
- Extend `needless_lifetimes` to suggest eliding `impl` lifetimes
- Reorder functions _[not strictly necessary, but IMHO, the code is better structured as a result]_
- Fix lifetime tests
- Fix non-lifetime tests
- Fix `clippy_lints` and `clippy_utils`
- Fix typo in `needless_lifetimes` test
r? `@Alexendoo` (I think you are `needless_lifetimes`' primary author? Sorry if I have this wrong.)
---
changelog: Extend `needless_lifetimes` to suggest eliding `impl` lifetimes
Suggest `Option<&T>` instead of `&Option<T>`
closes#13054
```rust
// bad code
fn foo(a: &Option<T>) {}
fn bar(&self) -> &Option<T> {}
// Use instead
fn foo(a: Option<&T>) {}
fn bar(&self) -> Option<&T> {}
```
Handles argument types and return types in functions, methods, and closures with explicit types. Honors `avoid_breaking_exported_api` parameter.
See this great [YouTube video](https://www.youtube.com/watch?v=6c7pZYP_iIE) with the in-depth explanation.
### Open Questions
These are not blocking, and could be done in separate PRs if needed.
* [ ] Should `&Option<Box<T>>` be suggested as `Option<&T>` -- without the box? Handled by [clippy::borrowed_box](https://rust-lang.github.io/rust-clippy/master/index.html#/borrowed_box)
* [ ] Should `&Option<String>` be suggested as `Option<&str>` -- using de-refed type?
### Possible Future Improvements
These cases might also be good to handle, probably in a separate PR.
```rust
fn lambdas() {
let x = |a: &Option<String>| {};
let x = |a: &Option<String>| -> &Option<String> { todo!() };
}
fn mut_ref_to_ref(a: &mut &Option<u8>) {}
```
changelog: [`ref_option`]: Suggest `Option<&T>` instead of `&Option<T>`
Use std_or_core to determine the correct prefix
This is a cleanup commit. It replaces hand-crafted tests by the a call to the `std_or_core()` utility function.
changelog: none
Lint comparison to empty slice using `PartialEq` methods
changelog: [`comparison_to_empty`]: Also detect comparaisons using `PartialEq` methods
Fix#13401
Split def_path_res into two parts
`def_path_res` previously had two jobs:
1. looking up the crates to find the path in
2. looking up path in said crates
This splits that job up into two functions, keeping `def_path_res` as an adapter between the both, to avoid repeating the first step when repeatedly looking up items in the same crate.
changelog: none
Replacing an empty span (which an empty line is) with an empty string triggers a
debug assertion in rustc. This fixes the debug assertion by using contiguous
spans, with the same resulting suggestion.
Unused trait imports (formerly anonymous trait import)
For #11969
I'm looking for help and feedback on implementing a new lint for suggesting `use ... as _` for traits where possible.
I have had a go at implementing this but I don't know if this is the best way to do it as I am new to clippy.
There are some edge cases I can think of where this doesn't work but have aired on the side of false negatives instead of false positives.
An example of a false negative. I couldn't figure out the best way to resolve an import from within clippy. The sub module imports MyAny so that cannot be anonymized but `use std::any::Any` could be. In this case it is not caught because `Any` and `MyAny` have the same DefId.
```rust
mod nested_mod_used_bad1 {
use std::any::Any;
use std::any::Any as MyAny;
mod foo {
use crate::nested_mod_used_bad1::MyAny;
fn foo() {
println!("{:?}", MyAny::type_id("foo"));
}
}
}
```
Any feedback is much appreciated.
-------
changelog: new lint: `unused_trait_names`
Fix `if_then_some_else_none` sugg missing closure intro
Fixes#13407#13407 works in current stable. The suggestion-generating code got trampled over in 0532104247 :-)
changelog: [`if_then_some_else_none`]: Fix missing closure in suggestion