Auto merge of #13286 - smoelius:elidable-impl-lifetimes, r=Alexendoo

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
This commit is contained in:
bors 2024-10-01 00:41:21 +00:00
commit db1bda3df1
115 changed files with 796 additions and 618 deletions

View file

@ -118,7 +118,7 @@ impl IntTypeBounds for IntTy {
}
}
impl<'tcx> PartialEq for Constant<'tcx> {
impl PartialEq for Constant<'_> {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Str(ls), Self::Str(rs)) => ls == rs,
@ -147,7 +147,7 @@ impl<'tcx> PartialEq for Constant<'tcx> {
}
}
impl<'tcx> Hash for Constant<'tcx> {
impl Hash for Constant<'_> {
fn hash<H>(&self, state: &mut H)
where
H: Hasher,
@ -203,7 +203,7 @@ impl<'tcx> Hash for Constant<'tcx> {
}
}
impl<'tcx> Constant<'tcx> {
impl Constant<'_> {
pub fn partial_cmp(tcx: TyCtxt<'_>, cmp_type: Ty<'_>, left: &Self, right: &Self) -> Option<Ordering> {
match (left, right) {
(Self::Str(ls), Self::Str(rs)) => Some(ls.cmp(rs)),

View file

@ -118,7 +118,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
eagerness: EagernessSuggestion,
}
impl<'cx, 'tcx> Visitor<'tcx> for V<'cx, 'tcx> {
impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> {
fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
use EagernessSuggestion::{ForceNoChange, Lazy, NoChange};
if self.eagerness == ForceNoChange {

View file

@ -1345,7 +1345,7 @@ pub struct ContainsName<'a, 'tcx> {
pub result: bool,
}
impl<'a, 'tcx> Visitor<'tcx> for ContainsName<'a, 'tcx> {
impl<'tcx> Visitor<'tcx> for ContainsName<'_, 'tcx> {
type NestedFilter = nested_filter::OnlyBodies;
fn visit_name(&mut self, name: Symbol) {
@ -3115,7 +3115,7 @@ pub fn is_never_expr<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> Option<
is_never: bool,
}
impl<'tcx> V<'_, 'tcx> {
impl V<'_, '_> {
fn push_break_target(&mut self, id: HirId) {
self.break_targets.push(BreakTarget { id, unused: true });
self.break_targets_for_result_ty += u32::from(self.in_final_expr);

View file

@ -58,7 +58,7 @@ struct V<'a> {
results: Vec<LocalUsage>,
}
impl<'a, 'tcx> Visitor<'tcx> for V<'a> {
impl<'tcx> Visitor<'tcx> for V<'_> {
fn visit_place(&mut self, place: &Place<'tcx>, ctx: PlaceContext, loc: Location) {
if loc.block == self.location.block && loc.statement_index <= self.location.statement_index {
return;

View file

@ -65,7 +65,7 @@ impl<'a, 'b, 'tcx> PossibleBorrowerVisitor<'a, 'b, 'tcx> {
}
}
impl<'a, 'b, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'b, 'tcx> {
impl<'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'_, '_, 'tcx> {
fn visit_assign(&mut self, place: &mir::Place<'tcx>, rvalue: &mir::Rvalue<'_>, _location: mir::Location) {
let lhs = place.local;
match rvalue {
@ -177,8 +177,8 @@ pub struct PossibleBorrowerMap<'b, 'tcx> {
pub bitset: (BitSet<mir::Local>, BitSet<mir::Local>),
}
impl<'a, 'b, 'tcx> PossibleBorrowerMap<'b, 'tcx> {
pub fn new(cx: &'a LateContext<'tcx>, mir: &'b mir::Body<'tcx>) -> Self {
impl<'b, 'tcx> PossibleBorrowerMap<'b, 'tcx> {
pub fn new(cx: &LateContext<'tcx>, mir: &'b mir::Body<'tcx>) -> Self {
let possible_origin = {
let mut vis = PossibleOriginVisitor::new(mir);
vis.visit_body(mir);

View file

@ -39,7 +39,7 @@ impl<'a, 'tcx> PossibleOriginVisitor<'a, 'tcx> {
}
}
impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleOriginVisitor<'a, 'tcx> {
impl<'tcx> mir::visit::Visitor<'tcx> for PossibleOriginVisitor<'_, 'tcx> {
fn visit_assign(&mut self, place: &mir::Place<'tcx>, rvalue: &mir::Rvalue<'_>, _location: mir::Location) {
let lhs = place.local;
match rvalue {

View file

@ -108,7 +108,7 @@ impl<'cx, 'tcx> CertaintyVisitor<'cx, 'tcx> {
}
}
impl<'cx, 'tcx> Visitor<'cx> for CertaintyVisitor<'cx, 'tcx> {
impl<'cx> Visitor<'cx> for CertaintyVisitor<'cx, '_> {
fn visit_qpath(&mut self, qpath: &'cx QPath<'_>, hir_id: HirId, _: Span) {
self.certainty = self.certainty.meet(qpath_certainty(self.cx, qpath, true));
if self.certainty != Certainty::Uncertain {

View file

@ -46,8 +46,8 @@ struct MutVarsDelegate {
skip: bool,
}
impl<'tcx> MutVarsDelegate {
fn update(&mut self, cat: &PlaceWithHirId<'tcx>) {
impl MutVarsDelegate {
fn update(&mut self, cat: &PlaceWithHirId<'_>) {
match cat.place.base {
PlaceBase::Local(id) => {
self.used_mutably.insert(id);
@ -122,7 +122,7 @@ impl<'a, 'tcx> BindingUsageFinder<'a, 'tcx> {
finder.usage_found
}
}
impl<'a, 'tcx> Visitor<'tcx> for BindingUsageFinder<'a, 'tcx> {
impl<'tcx> Visitor<'tcx> for BindingUsageFinder<'_, 'tcx> {
type NestedFilter = nested_filter::OnlyBodies;
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {

View file

@ -552,7 +552,7 @@ pub fn for_each_local_use_after_expr<'tcx, B>(
res: ControlFlow<B>,
f: F,
}
impl<'cx, 'tcx, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>, B> Visitor<'tcx> for V<'cx, 'tcx, F, B> {
impl<'tcx, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>, B> Visitor<'tcx> for V<'_, 'tcx, F, B> {
type NestedFilter = nested_filter::OnlyBodies;
fn nested_visit_map(&mut self) -> Self::Map {
self.cx.tcx.hir()
@ -734,7 +734,7 @@ pub fn for_each_local_assignment<'tcx, B>(
res: ControlFlow<B>,
f: F,
}
impl<'cx, 'tcx, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>, B> Visitor<'tcx> for V<'cx, 'tcx, F, B> {
impl<'tcx, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>, B> Visitor<'tcx> for V<'_, 'tcx, F, B> {
type NestedFilter = nested_filter::OnlyBodies;
fn nested_visit_map(&mut self) -> Self::Map {
self.cx.tcx.hir()