Skip to content

Commit 1c889b8

Browse files
Extend extra_unused_lifetimes for spurious for<'a>
Co-authored-by: Jona Draaijer <jcdra1@gmail.com> Signed-off-by: Marcel Müller <neikos@neikos.email>
1 parent bbfff70 commit 1c889b8

3 files changed

Lines changed: 111 additions & 16 deletions

File tree

clippy_lints/src/lifetimes.rs

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ use rustc_errors::Applicability;
99
use rustc_hir::FnRetTy::Return;
1010
use rustc_hir::intravisit::nested_filter::{self as hir_nested_filter, NestedFilter};
1111
use rustc_hir::intravisit::{
12-
Visitor, VisitorExt, walk_fn_decl, walk_generic_args, walk_generics, walk_impl_item_ref, walk_param_bound,
13-
walk_poly_trait_ref, walk_trait_ref, walk_ty, walk_unambig_ty, walk_where_predicate,
12+
Visitor, VisitorExt, walk_fn_decl, walk_generic_args, walk_generic_param, walk_generics, walk_impl_item_ref,
13+
walk_param_bound, walk_poly_trait_ref, walk_trait_ref, walk_ty, walk_unambig_ty, walk_where_predicate,
1414
};
1515
use rustc_hir::{
1616
AmbigArg, BodyId, FnDecl, FnPtrTy, FnSig, GenericArg, GenericArgs, GenericBound, GenericParam, GenericParamKind,
1717
Generics, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, Lifetime, LifetimeKind, LifetimeParamKind, Node,
18-
PolyTraitRef, PredicateOrigin, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WhereBoundPredicate, WherePredicate,
19-
WherePredicateKind, lang_items,
18+
PolyTraitRef, PredicateOrigin, TraitFn, TraitItem, TraitItemKind, TraitRef, Ty, TyKind, WhereBoundPredicate,
19+
WherePredicate, WherePredicateKind, lang_items,
2020
};
2121
use rustc_lint::{LateContext, LateLintPass, LintContext};
2222
use rustc_middle::hir::nested_filter as middle_nested_filter;
@@ -160,6 +160,10 @@ impl<'tcx> LateLintPass<'tcx> for Lifetimes {
160160
}
161161
}
162162

163+
fn check_poly_trait_ref(&mut self, cx: &LateContext<'tcx>, poly_trait_ref: &'tcx PolyTraitRef<'tcx>) {
164+
report_extra_trait_object_lifetimes(cx, poly_trait_ref.bound_generic_params, &poly_trait_ref.trait_ref);
165+
}
166+
163167
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {
164168
if let ImplItemKind::Fn(ref sig, id) = item.kind {
165169
let report_extra_lifetimes = trait_ref_of_method(cx, item.owner_id).is_none();
@@ -587,9 +591,8 @@ impl<'cx, 'tcx, F> LifetimeChecker<'cx, 'tcx, F>
587591
where
588592
F: NestedFilter<'tcx>,
589593
{
590-
fn new(cx: &'cx LateContext<'tcx>, generics: &'tcx Generics<'_>) -> LifetimeChecker<'cx, 'tcx, F> {
591-
let map = generics
592-
.params
594+
fn new(cx: &'cx LateContext<'tcx>, generic_params: &'tcx [GenericParam<'_>]) -> LifetimeChecker<'cx, 'tcx, F> {
595+
let map = generic_params
593596
.iter()
594597
.filter_map(|par| match par.kind {
595598
GenericParamKind::Lifetime {
@@ -598,6 +601,7 @@ where
598601
_ => None,
599602
})
600603
.collect();
604+
601605
Self {
602606
cx,
603607
map,
@@ -711,8 +715,36 @@ fn is_candidate_for_elision(fd: &FnDecl<'_>) -> bool {
711715
}
712716
}
713717

718+
fn report_extra_trait_object_lifetimes<'tcx>(
719+
cx: &LateContext<'tcx>,
720+
generic_params: &'tcx [GenericParam<'_>],
721+
trait_ref: &'tcx TraitRef<'tcx>,
722+
) {
723+
let mut checker = LifetimeChecker::<hir_nested_filter::None>::new(cx, generic_params);
724+
725+
for param in generic_params {
726+
walk_generic_param(&mut checker, param);
727+
}
728+
729+
walk_trait_ref(&mut checker, trait_ref);
730+
731+
for (def_id, usages) in checker.map {
732+
if usages
733+
.iter()
734+
.all(|usage| usage.in_where_predicate && !usage.in_bounded_ty && !usage.in_generics_arg)
735+
{
736+
span_lint(
737+
cx,
738+
EXTRA_UNUSED_LIFETIMES,
739+
cx.tcx.def_span(def_id),
740+
"this lifetime isn't used in the type",
741+
);
742+
}
743+
}
744+
}
745+
714746
fn report_extra_lifetimes<'tcx>(cx: &LateContext<'tcx>, func: &'tcx FnDecl<'_>, generics: &'tcx Generics<'_>) {
715-
let mut checker = LifetimeChecker::<hir_nested_filter::None>::new(cx, generics);
747+
let mut checker = LifetimeChecker::<hir_nested_filter::None>::new(cx, generics.params);
716748

717749
walk_generics(&mut checker, generics);
718750
walk_fn_decl(&mut checker, func);
@@ -733,7 +765,7 @@ fn report_extra_lifetimes<'tcx>(cx: &LateContext<'tcx>, func: &'tcx FnDecl<'_>,
733765
}
734766

735767
fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'_>) {
736-
let mut checker = LifetimeChecker::<middle_nested_filter::All>::new(cx, impl_.generics);
768+
let mut checker = LifetimeChecker::<middle_nested_filter::All>::new(cx, impl_.generics.params);
737769

738770
walk_generics(&mut checker, impl_.generics);
739771
if let Some(of_trait) = impl_.of_trait {

tests/ui/extra_unused_lifetimes.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,39 @@ fn used_lt<'a>(x: &'a u8) {}
1919
fn unused_lt<'a>(x: u8) {}
2020
//~^ extra_unused_lifetimes
2121

22+
struct BoxedFoo(Box<dyn for<'a> Fn()>);
23+
//~^ extra_unused_lifetimes
24+
25+
struct BoxedFooFine(Box<dyn for<'a> Fn(&'a u32)>);
26+
27+
fn unused_for_return() -> impl for<'a> Fn()
28+
//~^ extra_unused_lifetimes
29+
{
30+
|| unimplemented!()
31+
}
32+
33+
trait SimpleTrait<'a> {}
34+
35+
trait SimplerTrait {}
36+
37+
impl dyn for<'a> SimpleTrait<'a> {}
38+
39+
impl dyn for<'a> SimplerTrait {}
40+
//~^ extra_unused_lifetimes
41+
42+
impl<T: for<'a> SimpleTrait<'a>> SimplerTrait for T {}
43+
44+
impl<T: for<'a> SimplerTrait> SimpleTrait<'_> for T {}
45+
//~^ extra_unused_lifetimes
46+
47+
async fn unused_impl_for<F>(body: impl for<'a> FnOnce(u32) -> F)
48+
//~^ extra_unused_lifetimes
49+
where
50+
F: Future<Output = ()>,
51+
{
52+
unimplemented!()
53+
}
54+
2255
fn unused_lt_transitive<'a, 'b: 'a>(x: &'b u8) {
2356
// 'a is useless here since it's not directly bound
2457
}

tests/ui/extra_unused_lifetimes.stderr

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,41 +7,71 @@ LL | fn unused_lt<'a>(x: u8) {}
77
= note: `-D clippy::extra-unused-lifetimes` implied by `-D warnings`
88
= help: to override `-D warnings` add `#[allow(clippy::extra_unused_lifetimes)]`
99

10+
error: this lifetime isn't used in the type
11+
--> tests/ui/extra_unused_lifetimes.rs:22:29
12+
|
13+
LL | struct BoxedFoo(Box<dyn for<'a> Fn()>);
14+
| ^^
15+
16+
error: this lifetime isn't used in the type
17+
--> tests/ui/extra_unused_lifetimes.rs:27:36
18+
|
19+
LL | fn unused_for_return() -> impl for<'a> Fn()
20+
| ^^
21+
22+
error: this lifetime isn't used in the type
23+
--> tests/ui/extra_unused_lifetimes.rs:39:14
24+
|
25+
LL | impl dyn for<'a> SimplerTrait {}
26+
| ^^
27+
28+
error: this lifetime isn't used in the type
29+
--> tests/ui/extra_unused_lifetimes.rs:44:13
30+
|
31+
LL | impl<T: for<'a> SimplerTrait> SimpleTrait<'_> for T {}
32+
| ^^
33+
34+
error: this lifetime isn't used in the type
35+
--> tests/ui/extra_unused_lifetimes.rs:47:44
36+
|
37+
LL | async fn unused_impl_for<F>(body: impl for<'a> FnOnce(u32) -> F)
38+
| ^^
39+
1040
error: this lifetime isn't used in the function definition
11-
--> tests/ui/extra_unused_lifetimes.rs:47:10
41+
--> tests/ui/extra_unused_lifetimes.rs:80:10
1242
|
1343
LL | fn x<'a>(&self) {}
1444
| ^^
1545

1646
error: this lifetime isn't used in the function definition
17-
--> tests/ui/extra_unused_lifetimes.rs:74:22
47+
--> tests/ui/extra_unused_lifetimes.rs:107:22
1848
|
1949
LL | fn unused_lt<'a>(x: u8) {}
2050
| ^^
2151

2252
error: this lifetime isn't used in the impl
23-
--> tests/ui/extra_unused_lifetimes.rs:86:10
53+
--> tests/ui/extra_unused_lifetimes.rs:119:10
2454
|
2555
LL | impl<'a> std::ops::AddAssign<&Scalar> for &mut Scalar {
2656
| ^^
2757

2858
error: this lifetime isn't used in the impl
29-
--> tests/ui/extra_unused_lifetimes.rs:93:10
59+
--> tests/ui/extra_unused_lifetimes.rs:126:10
3060
|
3161
LL | impl<'b> Scalar {
3262
| ^^
3363

3464
error: this lifetime isn't used in the function definition
35-
--> tests/ui/extra_unused_lifetimes.rs:95:26
65+
--> tests/ui/extra_unused_lifetimes.rs:128:26
3666
|
3767
LL | pub fn something<'c>() -> Self {
3868
| ^^
3969

4070
error: this lifetime isn't used in the impl
41-
--> tests/ui/extra_unused_lifetimes.rs:125:10
71+
--> tests/ui/extra_unused_lifetimes.rs:158:10
4272
|
4373
LL | impl<'a, T: Source + ?Sized + 'a> Source for Box<T> {
4474
| ^^
4575

46-
error: aborting due to 7 previous errors
76+
error: aborting due to 12 previous errors
4777

0 commit comments

Comments
 (0)