Split needless_lifetime '_ suggestions into elidable_lifetime_names (#13960)

Fixes https://github.com/rust-lang/rust-clippy/issues/13514

changelog: Added [`elidable_lifetime_names`] to `pedantic` (Split off
from [`needless_lifetime`] for suggestions with `'_`)
[#13960](https://github.com/rust-lang/rust-clippy/pull/13960)

changelog: Enhancement: [`needless_lifetime`] No longer lints for
elidable lifetimes `'_`, use [`elidable_lifetime_names`] to lint these.
[#13960](https://github.com/rust-lang/rust-clippy/pull/13960)
This commit is contained in:
Fridtjof Stoldt
2025-02-27 09:21:50 +00:00
committed by GitHub
14 changed files with 687 additions and 637 deletions
+1
View File
@@ -5592,6 +5592,7 @@ Released 2018-09-13
[`duplicated_attributes`]: https://rust-lang.github.io/rust-clippy/master/index.html#duplicated_attributes
[`duration_subsec`]: https://rust-lang.github.io/rust-clippy/master/index.html#duration_subsec
[`eager_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#eager_transmute
[`elidable_lifetime_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#elidable_lifetime_names
[`else_if_without_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#else_if_without_else
[`empty_docs`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_docs
[`empty_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_drop
+1
View File
@@ -274,6 +274,7 @@
crate::let_underscore::LET_UNDERSCORE_MUST_USE_INFO,
crate::let_underscore::LET_UNDERSCORE_UNTYPED_INFO,
crate::let_with_type_underscore::LET_WITH_TYPE_UNDERSCORE_INFO,
crate::lifetimes::ELIDABLE_LIFETIME_NAMES_INFO,
crate::lifetimes::EXTRA_UNUSED_LIFETIMES_INFO,
crate::lifetimes::NEEDLESS_LIFETIMES_INFO,
crate::lines_filter_map_ok::LINES_FILTER_MAP_OK_INFO,
+85 -25
View File
@@ -38,8 +38,8 @@
/// them leads to more readable code.
///
/// ### Known problems
/// - We bail out if the function has a `where` clause where lifetimes
/// are mentioned due to potential false positives.
/// This lint ignores functions with `where` clauses that reference
/// lifetimes to prevent false positives.
///
/// ### Example
/// ```no_run
@@ -62,6 +62,38 @@
would allow omitting them"
}
declare_clippy_lint! {
/// ### What it does
/// Checks for lifetime annotations which can be replaced with anonymous lifetimes (`'_`).
///
/// ### Why is this bad?
/// The additional lifetimes can make the code look more complicated.
///
/// ### Known problems
/// This lint ignores functions with `where` clauses that reference
/// lifetimes to prevent false positives.
///
/// ### Example
/// ```no_run
/// # use std::str::Chars;
/// fn f<'a>(x: &'a str) -> Chars<'a> {
/// x.chars()
/// }
/// ```
///
/// Use instead:
/// ```no_run
/// # use std::str::Chars;
/// fn f(x: &str) -> Chars<'_> {
/// x.chars()
/// }
/// ```
#[clippy::version = "1.84.0"]
pub ELIDABLE_LIFETIME_NAMES,
pedantic,
"lifetime name that can be replaced with the anonymous lifetime"
}
declare_clippy_lint! {
/// ### What it does
/// Checks for lifetimes in generics that are never used
@@ -104,7 +136,11 @@ pub fn new(conf: &'static Conf) -> Self {
}
}
impl_lint_pass!(Lifetimes => [NEEDLESS_LIFETIMES, EXTRA_UNUSED_LIFETIMES]);
impl_lint_pass!(Lifetimes => [
NEEDLESS_LIFETIMES,
ELIDABLE_LIFETIME_NAMES,
EXTRA_UNUSED_LIFETIMES,
]);
impl<'tcx> LateLintPass<'tcx> for Lifetimes {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
@@ -746,6 +782,15 @@ fn report_elidable_impl_lifetimes<'tcx>(
report_elidable_lifetimes(cx, impl_.generics, &elidable_lts, &usages, true);
}
#[derive(Copy, Clone)]
enum ElidableUsage {
/// Used in a ref (`&'a T`), can be removed
Ref(Span),
/// Used as a generic param (`T<'a>`) or an impl lifetime (`impl T + 'a`), can be replaced
/// with `'_`
Other(Span),
}
/// Generate diagnostic messages for elidable lifetimes.
fn report_elidable_lifetimes(
cx: &LateContext<'_>,
@@ -763,9 +808,29 @@ fn report_elidable_lifetimes(
.collect::<Vec<_>>()
.join(", ");
let elidable_usages: Vec<ElidableUsage> = usages
.iter()
.filter(|usage| named_lifetime(usage).is_some_and(|id| elidable_lts.contains(&id)))
.map(|usage| match cx.tcx.parent_hir_node(usage.hir_id) {
Node::Ty(Ty {
kind: TyKind::Ref(..), ..
}) => ElidableUsage::Ref(usage.ident.span),
_ => ElidableUsage::Other(usage.ident.span),
})
.collect();
let lint = if elidable_usages
.iter()
.any(|usage| matches!(usage, ElidableUsage::Other(_)))
{
ELIDABLE_LIFETIME_NAMES
} else {
NEEDLESS_LIFETIMES
};
span_lint_and_then(
cx,
NEEDLESS_LIFETIMES,
lint,
elidable_lts
.iter()
.map(|&lt| cx.tcx.def_span(lt))
@@ -785,7 +850,7 @@ fn report_elidable_lifetimes(
return;
}
if let Some(suggestions) = elision_suggestions(cx, generics, elidable_lts, usages) {
if let Some(suggestions) = elision_suggestions(cx, generics, elidable_lts, &elidable_usages) {
diag.multipart_suggestion("elide the lifetimes", suggestions, Applicability::MachineApplicable);
}
},
@@ -796,7 +861,7 @@ fn elision_suggestions(
cx: &LateContext<'_>,
generics: &Generics<'_>,
elidable_lts: &[LocalDefId],
usages: &[Lifetime],
usages: &[ElidableUsage],
) -> Option<Vec<(Span, String)>> {
let explicit_params = generics
.params
@@ -836,26 +901,21 @@ fn elision_suggestions(
.collect::<Option<Vec<_>>>()?
};
suggestions.extend(
usages
.iter()
.filter(|usage| named_lifetime(usage).is_some_and(|id| elidable_lts.contains(&id)))
.map(|usage| {
match cx.tcx.parent_hir_node(usage.hir_id) {
Node::Ty(Ty {
kind: TyKind::Ref(..), ..
}) => {
// expand `&'a T` to `&'a T`
// ^^ ^^^
let span = cx.sess().source_map().span_extend_while_whitespace(usage.ident.span);
suggestions.extend(usages.iter().map(|&usage| {
match usage {
ElidableUsage::Ref(span) => {
// expand `&'a T` to `&'a T`
// ^^ ^^^
let span = cx.sess().source_map().span_extend_while_whitespace(span);
(span, String::new())
},
// `T<'a>` and `impl Foo + 'a` should be replaced by `'_`
_ => (usage.ident.span, String::from("'_")),
}
}),
);
(span, String::new())
},
ElidableUsage::Other(span) => {
// `T<'a>` and `impl Foo + 'a` should be replaced by `'_`
(span, String::from("'_"))
},
}
}));
Some(suggestions)
}
@@ -1,4 +1,4 @@
#![deny(clippy::needless_lifetimes)]
#![deny(clippy::elidable_lifetime_names)]
#![allow(dead_code)]
trait Foo {}
@@ -10,11 +10,11 @@ struct Baz<'a> {
}
impl Foo for Baz<'_> {}
//~^ needless_lifetimes
//~^ elidable_lifetime_names
impl Bar {
fn baz(&self) -> impl Foo + '_ {
//~^ needless_lifetimes
//~^ elidable_lifetime_names
Baz { bar: self }
}
@@ -1,4 +1,4 @@
#![deny(clippy::needless_lifetimes)]
#![deny(clippy::elidable_lifetime_names)]
#![allow(dead_code)]
trait Foo {}
@@ -10,11 +10,11 @@ struct Baz<'a> {
}
impl<'a> Foo for Baz<'a> {}
//~^ needless_lifetimes
//~^ elidable_lifetime_names
impl Bar {
fn baz<'a>(&'a self) -> impl Foo + 'a {
//~^ needless_lifetimes
//~^ elidable_lifetime_names
Baz { bar: self }
}
@@ -1,14 +1,14 @@
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/crashes/needless_lifetimes_impl_trait.rs:12:6
--> tests/ui/crashes/elidable_lifetime_names_impl_trait.rs:12:6
|
LL | impl<'a> Foo for Baz<'a> {}
| ^^ ^^
|
note: the lint level is defined here
--> tests/ui/crashes/needless_lifetimes_impl_trait.rs:1:9
--> tests/ui/crashes/elidable_lifetime_names_impl_trait.rs:1:9
|
LL | #![deny(clippy::needless_lifetimes)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | #![deny(clippy::elidable_lifetime_names)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: elide the lifetimes
|
LL - impl<'a> Foo for Baz<'a> {}
@@ -16,7 +16,7 @@ LL + impl Foo for Baz<'_> {}
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/crashes/needless_lifetimes_impl_trait.rs:16:12
--> tests/ui/crashes/elidable_lifetime_names_impl_trait.rs:16:12
|
LL | fn baz<'a>(&'a self) -> impl Foo + 'a {
| ^^ ^^ ^^
+194
View File
@@ -0,0 +1,194 @@
#![warn(clippy::needless_lifetimes, clippy::elidable_lifetime_names)]
type Ref<'r> = &'r u8;
// No error; same lifetime on two params.
fn lifetime_param_1<'a>(_x: Ref<'a>, _y: &'a u8) {}
//~v ERROR: could be elided: 'a, 'b
fn lifetime_param_2(_x: Ref<'_>, _y: &u8) {}
// No error; bounded lifetime.
fn lifetime_param_3<'a, 'b: 'a>(_x: Ref<'a>, _y: &'b u8) {}
// No error; bounded lifetime.
fn lifetime_param_4<'a, 'b>(_x: Ref<'a>, _y: &'b u8)
where
'b: 'a,
{
}
struct Lt<'a, I: 'static> {
x: &'a I,
}
// No error; fn bound references `'a`.
fn fn_bound<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>
where
F: Fn(Lt<'a, I>) -> Lt<'a, I>,
{
unreachable!()
}
//~v ERROR: could be elided: 'a
fn fn_bound_2<F, I>(_m: Lt<'_, I>, _f: F) -> Lt<'_, I>
where
for<'x> F: Fn(Lt<'x, I>) -> Lt<'x, I>,
{
unreachable!()
}
struct Foo<'a>(&'a u8);
//~v ERROR: could be elided: 'a
fn struct_with_lt(_foo: Foo<'_>) -> &str {
unimplemented!()
}
// No warning; two input lifetimes (named on the reference, anonymous on `Foo`).
fn struct_with_lt2<'a>(_foo: &'a Foo) -> &'a str {
unimplemented!()
}
// No warning; two input lifetimes (anonymous on the reference, named on `Foo`).
fn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str {
unimplemented!()
}
//~v ERROR: could be elided: 'b
fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str {
unimplemented!()
}
type FooAlias<'a> = Foo<'a>;
//~v ERROR: could be elided: 'a
fn alias_with_lt(_foo: FooAlias<'_>) -> &str {
unimplemented!()
}
// No warning; two input lifetimes (named on the reference, anonymous on `FooAlias`).
fn alias_with_lt2<'a>(_foo: &'a FooAlias) -> &'a str {
unimplemented!()
}
// No warning; two input lifetimes (anonymous on the reference, named on `FooAlias`).
fn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str {
unimplemented!()
}
//~v ERROR: could be elided: 'b
fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str {
unimplemented!()
}
// Issue #3284: give hint regarding lifetime in return type.
struct Cow<'a> {
x: &'a str,
}
//~v ERROR: could be elided: 'a
fn out_return_type_lts(e: &str) -> Cow<'_> {
unimplemented!()
}
mod issue2944 {
trait Foo {}
struct Bar;
struct Baz<'a> {
bar: &'a Bar,
}
//~v ERROR: could be elided: 'a
impl Foo for Baz<'_> {}
impl Bar {
//~v ERROR: could be elided: 'a
fn baz(&self) -> impl Foo + '_ {
Baz { bar: self }
}
}
}
mod issue13923 {
struct Py<'py> {
data: &'py str,
}
enum Content<'t, 'py> {
Py(Py<'py>),
T1(&'t str),
T2(&'t str),
}
enum ContentString<'t> {
T1(&'t str),
T2(&'t str),
}
impl<'t, 'py> ContentString<'t> {
// `'py` cannot be elided
fn map_content1(self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {
match self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(content) => Content::T2(f(content)),
}
}
}
//~v ERROR: could be elided: 'py
impl<'t> ContentString<'t> {
// `'py` can be elided because of `&self`
fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> {
match self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(content) => Content::T2(f(content)),
}
}
}
//~v ERROR: could be elided: 'py
impl<'t> ContentString<'t> {
// `'py` can be elided because of `&'_ self`
fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> {
match self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(content) => Content::T2(f(content)),
}
}
}
impl<'t, 'py> ContentString<'t> {
// `'py` should not be elided as the default lifetime, even if working, could be named as `'t`
fn map_content4(self, f: impl FnOnce(&'t str) -> &'t str, o: &'t str) -> Content<'t, 'py> {
match self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(_) => Content::T2(o),
}
}
}
//~v ERROR: could be elided: 'py
impl<'t> ContentString<'t> {
// `'py` can be elided because of `&Self`
fn map_content5(
self: std::pin::Pin<&Self>,
f: impl FnOnce(&'t str) -> &'t str,
o: &'t str,
) -> Content<'t, '_> {
match *self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(_) => Content::T2(o),
}
}
}
struct Cx<'a, 'b> {
a: &'a u32,
b: &'b u32,
}
// `'c` cannot be elided because we have several input lifetimes
fn one_explicit<'b>(x: Cx<'_, 'b>) -> &'b u32 {
x.b
}
}
+194
View File
@@ -0,0 +1,194 @@
#![warn(clippy::needless_lifetimes, clippy::elidable_lifetime_names)]
type Ref<'r> = &'r u8;
// No error; same lifetime on two params.
fn lifetime_param_1<'a>(_x: Ref<'a>, _y: &'a u8) {}
//~v ERROR: could be elided: 'a, 'b
fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {}
// No error; bounded lifetime.
fn lifetime_param_3<'a, 'b: 'a>(_x: Ref<'a>, _y: &'b u8) {}
// No error; bounded lifetime.
fn lifetime_param_4<'a, 'b>(_x: Ref<'a>, _y: &'b u8)
where
'b: 'a,
{
}
struct Lt<'a, I: 'static> {
x: &'a I,
}
// No error; fn bound references `'a`.
fn fn_bound<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>
where
F: Fn(Lt<'a, I>) -> Lt<'a, I>,
{
unreachable!()
}
//~v ERROR: could be elided: 'a
fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>
where
for<'x> F: Fn(Lt<'x, I>) -> Lt<'x, I>,
{
unreachable!()
}
struct Foo<'a>(&'a u8);
//~v ERROR: could be elided: 'a
fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str {
unimplemented!()
}
// No warning; two input lifetimes (named on the reference, anonymous on `Foo`).
fn struct_with_lt2<'a>(_foo: &'a Foo) -> &'a str {
unimplemented!()
}
// No warning; two input lifetimes (anonymous on the reference, named on `Foo`).
fn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str {
unimplemented!()
}
//~v ERROR: could be elided: 'b
fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {
unimplemented!()
}
type FooAlias<'a> = Foo<'a>;
//~v ERROR: could be elided: 'a
fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str {
unimplemented!()
}
// No warning; two input lifetimes (named on the reference, anonymous on `FooAlias`).
fn alias_with_lt2<'a>(_foo: &'a FooAlias) -> &'a str {
unimplemented!()
}
// No warning; two input lifetimes (anonymous on the reference, named on `FooAlias`).
fn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str {
unimplemented!()
}
//~v ERROR: could be elided: 'b
fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {
unimplemented!()
}
// Issue #3284: give hint regarding lifetime in return type.
struct Cow<'a> {
x: &'a str,
}
//~v ERROR: could be elided: 'a
fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> {
unimplemented!()
}
mod issue2944 {
trait Foo {}
struct Bar;
struct Baz<'a> {
bar: &'a Bar,
}
//~v ERROR: could be elided: 'a
impl<'a> Foo for Baz<'a> {}
impl Bar {
//~v ERROR: could be elided: 'a
fn baz<'a>(&'a self) -> impl Foo + 'a {
Baz { bar: self }
}
}
}
mod issue13923 {
struct Py<'py> {
data: &'py str,
}
enum Content<'t, 'py> {
Py(Py<'py>),
T1(&'t str),
T2(&'t str),
}
enum ContentString<'t> {
T1(&'t str),
T2(&'t str),
}
impl<'t, 'py> ContentString<'t> {
// `'py` cannot be elided
fn map_content1(self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {
match self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(content) => Content::T2(f(content)),
}
}
}
//~v ERROR: could be elided: 'py
impl<'t, 'py> ContentString<'t> {
// `'py` can be elided because of `&self`
fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {
match self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(content) => Content::T2(f(content)),
}
}
}
//~v ERROR: could be elided: 'py
impl<'t, 'py> ContentString<'t> {
// `'py` can be elided because of `&'_ self`
fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {
match self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(content) => Content::T2(f(content)),
}
}
}
impl<'t, 'py> ContentString<'t> {
// `'py` should not be elided as the default lifetime, even if working, could be named as `'t`
fn map_content4(self, f: impl FnOnce(&'t str) -> &'t str, o: &'t str) -> Content<'t, 'py> {
match self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(_) => Content::T2(o),
}
}
}
//~v ERROR: could be elided: 'py
impl<'t, 'py> ContentString<'t> {
// `'py` can be elided because of `&Self`
fn map_content5(
self: std::pin::Pin<&Self>,
f: impl FnOnce(&'t str) -> &'t str,
o: &'t str,
) -> Content<'t, 'py> {
match *self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(_) => Content::T2(o),
}
}
}
struct Cx<'a, 'b> {
a: &'a u32,
b: &'b u32,
}
// `'c` cannot be elided because we have several input lifetimes
fn one_explicit<'b>(x: Cx<'_, 'b>) -> &'b u32 {
x.b
}
}
+162
View File
@@ -0,0 +1,162 @@
error: the following explicit lifetimes could be elided: 'a, 'b
--> tests/ui/elidable_lifetime_names.rs:9:21
|
LL | fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {}
| ^^ ^^ ^^ ^^
|
= note: `-D clippy::elidable-lifetime-names` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::elidable_lifetime_names)]`
help: elide the lifetimes
|
LL - fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {}
LL + fn lifetime_param_2(_x: Ref<'_>, _y: &u8) {}
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/elidable_lifetime_names.rs:34:15
|
LL | fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>
| ^^ ^^ ^^
|
help: elide the lifetimes
|
LL - fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>
LL + fn fn_bound_2<F, I>(_m: Lt<'_, I>, _f: F) -> Lt<'_, I>
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/elidable_lifetime_names.rs:44:19
|
LL | fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str {
| ^^ ^^ ^^
|
help: elide the lifetimes
|
LL - fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str {
LL + fn struct_with_lt(_foo: Foo<'_>) -> &str {
|
error: the following explicit lifetimes could be elided: 'b
--> tests/ui/elidable_lifetime_names.rs:59:25
|
LL | fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {
| ^^ ^^
|
help: elide the lifetimes
|
LL - fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {
LL + fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/elidable_lifetime_names.rs:66:18
|
LL | fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str {
| ^^ ^^ ^^
|
help: elide the lifetimes
|
LL - fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str {
LL + fn alias_with_lt(_foo: FooAlias<'_>) -> &str {
|
error: the following explicit lifetimes could be elided: 'b
--> tests/ui/elidable_lifetime_names.rs:81:24
|
LL | fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {
| ^^ ^^
|
help: elide the lifetimes
|
LL - fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {
LL + fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/elidable_lifetime_names.rs:91:24
|
LL | fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> {
| ^^ ^^ ^^
|
help: elide the lifetimes
|
LL - fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> {
LL + fn out_return_type_lts(e: &str) -> Cow<'_> {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/elidable_lifetime_names.rs:103:10
|
LL | impl<'a> Foo for Baz<'a> {}
| ^^ ^^
|
help: elide the lifetimes
|
LL - impl<'a> Foo for Baz<'a> {}
LL + impl Foo for Baz<'_> {}
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/elidable_lifetime_names.rs:106:16
|
LL | fn baz<'a>(&'a self) -> impl Foo + 'a {
| ^^ ^^ ^^
|
help: elide the lifetimes
|
LL - fn baz<'a>(&'a self) -> impl Foo + 'a {
LL + fn baz(&self) -> impl Foo + '_ {
|
error: the following explicit lifetimes could be elided: 'py
--> tests/ui/elidable_lifetime_names.rs:139:14
|
LL | impl<'t, 'py> ContentString<'t> {
| ^^^
LL | // `'py` can be elided because of `&self`
LL | fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {
| ^^^
|
help: elide the lifetimes
|
LL ~ impl<'t> ContentString<'t> {
LL | // `'py` can be elided because of `&self`
LL ~ fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> {
|
error: the following explicit lifetimes could be elided: 'py
--> tests/ui/elidable_lifetime_names.rs:150:14
|
LL | impl<'t, 'py> ContentString<'t> {
| ^^^
LL | // `'py` can be elided because of `&'_ self`
LL | fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {
| ^^^
|
help: elide the lifetimes
|
LL ~ impl<'t> ContentString<'t> {
LL | // `'py` can be elided because of `&'_ self`
LL ~ fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> {
|
error: the following explicit lifetimes could be elided: 'py
--> tests/ui/elidable_lifetime_names.rs:171:14
|
LL | impl<'t, 'py> ContentString<'t> {
| ^^^
...
LL | ) -> Content<'t, 'py> {
| ^^^
|
help: elide the lifetimes
|
LL ~ impl<'t> ContentString<'t> {
LL | // `'py` can be elided because of `&Self`
...
LL | o: &'t str,
LL ~ ) -> Content<'t, '_> {
|
error: aborting due to 12 previous errors
+1
View File
@@ -11,6 +11,7 @@
clippy::new_without_default,
clippy::needless_pass_by_value,
clippy::needless_lifetimes,
clippy::elidable_lifetime_names,
clippy::print_stdout,
clippy::must_use_candidate,
clippy::use_self,
+2 -2
View File
@@ -1,5 +1,5 @@
error: methods called `new` usually return `Self`
--> tests/ui/methods.rs:103:5
--> tests/ui/methods.rs:104:5
|
LL | / fn new() -> i32 {
LL | |
@@ -11,7 +11,7 @@ LL | | }
= help: to override `-D warnings` add `#[allow(clippy::new_ret_no_self)]`
error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead
--> tests/ui/methods.rs:125:13
--> tests/ui/methods.rs:126:13
|
LL | let _ = v.iter().filter(|&x| {
| _____________^
+1 -198
View File
@@ -1,6 +1,6 @@
//@aux-build:proc_macros.rs
#![warn(clippy::needless_lifetimes)]
#![warn(clippy::needless_lifetimes, clippy::elidable_lifetime_names)]
#![allow(
unused,
clippy::boxed_local,
@@ -101,44 +101,6 @@ where
Ok(x)
}
type Ref<'r> = &'r u8;
// No error; same lifetime on two params.
fn lifetime_param_1<'a>(_x: Ref<'a>, _y: &'a u8) {}
fn lifetime_param_2(_x: Ref<'_>, _y: &u8) {}
//~^ needless_lifetimes
// No error; bounded lifetime.
fn lifetime_param_3<'a, 'b: 'a>(_x: Ref<'a>, _y: &'b u8) {}
// No error; bounded lifetime.
fn lifetime_param_4<'a, 'b>(_x: Ref<'a>, _y: &'b u8)
where
'b: 'a,
{
}
struct Lt<'a, I: 'static> {
x: &'a I,
}
// No error; fn bound references `'a`.
fn fn_bound<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>
where
F: Fn(Lt<'a, I>) -> Lt<'a, I>,
{
unreachable!()
}
fn fn_bound_2<F, I>(_m: Lt<'_, I>, _f: F) -> Lt<'_, I>
//~^ needless_lifetimes
where
for<'x> F: Fn(Lt<'x, I>) -> Lt<'x, I>,
{
unreachable!()
}
// No error; see below.
fn fn_bound_3<'a, F: FnOnce(&'a i32)>(x: &'a i32, f: F) {
f(x);
@@ -203,30 +165,6 @@ fn already_elided<'a>(_: &u8, _: &'a u8) -> &'a u8 {
unimplemented!()
}
fn struct_with_lt(_foo: Foo<'_>) -> &str {
//~^ needless_lifetimes
unimplemented!()
}
// No warning; two input lifetimes (named on the reference, anonymous on `Foo`).
fn struct_with_lt2<'a>(_foo: &'a Foo) -> &'a str {
unimplemented!()
}
// No warning; two input lifetimes (anonymous on the reference, named on `Foo`).
fn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str {
unimplemented!()
}
// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is
// valid:
// fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str
// ^^
fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str {
//~^ needless_lifetimes
unimplemented!()
}
// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is
// valid:
// fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str
@@ -254,30 +192,6 @@ fn trait_obj_elided2(_arg: &dyn Drop) -> &str {
type FooAlias<'a> = Foo<'a>;
fn alias_with_lt(_foo: FooAlias<'_>) -> &str {
//~^ needless_lifetimes
unimplemented!()
}
// No warning; two input lifetimes (named on the reference, anonymous on `FooAlias`).
fn alias_with_lt2<'a>(_foo: &'a FooAlias) -> &'a str {
unimplemented!()
}
// No warning; two input lifetimes (anonymous on the reference, named on `FooAlias`).
fn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str {
unimplemented!()
}
// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is
// valid:
// fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str
// ^^
fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str {
//~^ needless_lifetimes
unimplemented!()
}
// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is
// valid:
// fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str
@@ -329,15 +243,6 @@ fn test<'a>(x: &'a [u8]) -> u8 {
*y
}
// Issue #3284: give hint regarding lifetime in return type.
struct Cow<'a> {
x: &'a str,
}
fn out_return_type_lts(e: &str) -> Cow<'_> {
//~^ needless_lifetimes
unimplemented!()
}
// Make sure we still warn on implementations
mod issue4291 {
trait BadTrait {
@@ -351,23 +256,6 @@ mod issue4291 {
}
}
mod issue2944 {
trait Foo {}
struct Bar;
struct Baz<'a> {
bar: &'a Bar,
}
impl Foo for Baz<'_> {}
//~^ needless_lifetimes
impl Bar {
fn baz(&self) -> impl Foo + '_ {
//~^ needless_lifetimes
Baz { bar: self }
}
}
}
mod nested_elision_sites {
// issue #issue2944
@@ -646,89 +534,4 @@ mod issue13749bis {
impl<'a, T: 'a> Generic<T> {}
}
mod issue13923 {
struct Py<'py> {
data: &'py str,
}
enum Content<'t, 'py> {
Py(Py<'py>),
T1(&'t str),
T2(&'t str),
}
enum ContentString<'t> {
T1(&'t str),
T2(&'t str),
}
impl<'t, 'py> ContentString<'t> {
// `'py` cannot be elided
fn map_content1(self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {
match self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(content) => Content::T2(f(content)),
}
}
}
impl<'t> ContentString<'t> {
//~^ needless_lifetimes
// `'py` can be elided because of `&self`
fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> {
match self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(content) => Content::T2(f(content)),
}
}
}
impl<'t> ContentString<'t> {
//~^ needless_lifetimes
// `'py` can be elided because of `&'_ self`
fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> {
match self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(content) => Content::T2(f(content)),
}
}
}
impl<'t, 'py> ContentString<'t> {
// `'py` should not be elided as the default lifetime, even if working, could be named as `'t`
fn map_content4(self, f: impl FnOnce(&'t str) -> &'t str, o: &'t str) -> Content<'t, 'py> {
match self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(_) => Content::T2(o),
}
}
}
impl<'t> ContentString<'t> {
//~^ needless_lifetimes
// `'py` can be elided because of `&Self`
fn map_content5(
self: std::pin::Pin<&Self>,
f: impl FnOnce(&'t str) -> &'t str,
o: &'t str,
) -> Content<'t, '_> {
match *self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(_) => Content::T2(o),
}
}
}
struct Cx<'a, 'b> {
a: &'a u32,
b: &'b u32,
}
// `'c` cannot be elided because we have several input lifetimes
fn one_explicit<'b>(x: Cx<'_, 'b>) -> &'b u32 {
x.b
//~^ needless_borrow
}
}
fn main() {}
+1 -198
View File
@@ -1,6 +1,6 @@
//@aux-build:proc_macros.rs
#![warn(clippy::needless_lifetimes)]
#![warn(clippy::needless_lifetimes, clippy::elidable_lifetime_names)]
#![allow(
unused,
clippy::boxed_local,
@@ -101,44 +101,6 @@ fn where_clause_without_lt<'a, T>(x: &'a u8, _y: u8) -> Result<&'a u8, ()>
Ok(x)
}
type Ref<'r> = &'r u8;
// No error; same lifetime on two params.
fn lifetime_param_1<'a>(_x: Ref<'a>, _y: &'a u8) {}
fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {}
//~^ needless_lifetimes
// No error; bounded lifetime.
fn lifetime_param_3<'a, 'b: 'a>(_x: Ref<'a>, _y: &'b u8) {}
// No error; bounded lifetime.
fn lifetime_param_4<'a, 'b>(_x: Ref<'a>, _y: &'b u8)
where
'b: 'a,
{
}
struct Lt<'a, I: 'static> {
x: &'a I,
}
// No error; fn bound references `'a`.
fn fn_bound<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>
where
F: Fn(Lt<'a, I>) -> Lt<'a, I>,
{
unreachable!()
}
fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>
//~^ needless_lifetimes
where
for<'x> F: Fn(Lt<'x, I>) -> Lt<'x, I>,
{
unreachable!()
}
// No error; see below.
fn fn_bound_3<'a, F: FnOnce(&'a i32)>(x: &'a i32, f: F) {
f(x);
@@ -203,30 +165,6 @@ fn already_elided<'a>(_: &u8, _: &'a u8) -> &'a u8 {
unimplemented!()
}
fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str {
//~^ needless_lifetimes
unimplemented!()
}
// No warning; two input lifetimes (named on the reference, anonymous on `Foo`).
fn struct_with_lt2<'a>(_foo: &'a Foo) -> &'a str {
unimplemented!()
}
// No warning; two input lifetimes (anonymous on the reference, named on `Foo`).
fn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str {
unimplemented!()
}
// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is
// valid:
// fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str
// ^^
fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {
//~^ needless_lifetimes
unimplemented!()
}
// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is
// valid:
// fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str
@@ -254,30 +192,6 @@ fn trait_obj_elided2<'a>(_arg: &'a dyn Drop) -> &'a str {
type FooAlias<'a> = Foo<'a>;
fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str {
//~^ needless_lifetimes
unimplemented!()
}
// No warning; two input lifetimes (named on the reference, anonymous on `FooAlias`).
fn alias_with_lt2<'a>(_foo: &'a FooAlias) -> &'a str {
unimplemented!()
}
// No warning; two input lifetimes (anonymous on the reference, named on `FooAlias`).
fn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str {
unimplemented!()
}
// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is
// valid:
// fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str
// ^^
fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {
//~^ needless_lifetimes
unimplemented!()
}
// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is
// valid:
// fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str
@@ -329,15 +243,6 @@ fn test<'a>(x: &'a [u8]) -> u8 {
*y
}
// Issue #3284: give hint regarding lifetime in return type.
struct Cow<'a> {
x: &'a str,
}
fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> {
//~^ needless_lifetimes
unimplemented!()
}
// Make sure we still warn on implementations
mod issue4291 {
trait BadTrait {
@@ -351,23 +256,6 @@ fn needless_lt<'a>(_x: &'a u8) {}
}
}
mod issue2944 {
trait Foo {}
struct Bar;
struct Baz<'a> {
bar: &'a Bar,
}
impl<'a> Foo for Baz<'a> {}
//~^ needless_lifetimes
impl Bar {
fn baz<'a>(&'a self) -> impl Foo + 'a {
//~^ needless_lifetimes
Baz { bar: self }
}
}
}
mod nested_elision_sites {
// issue #issue2944
@@ -646,89 +534,4 @@ mod issue13749bis {
impl<'a, T: 'a> Generic<T> {}
}
mod issue13923 {
struct Py<'py> {
data: &'py str,
}
enum Content<'t, 'py> {
Py(Py<'py>),
T1(&'t str),
T2(&'t str),
}
enum ContentString<'t> {
T1(&'t str),
T2(&'t str),
}
impl<'t, 'py> ContentString<'t> {
// `'py` cannot be elided
fn map_content1(self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {
match self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(content) => Content::T2(f(content)),
}
}
}
impl<'t, 'py> ContentString<'t> {
//~^ needless_lifetimes
// `'py` can be elided because of `&self`
fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {
match self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(content) => Content::T2(f(content)),
}
}
}
impl<'t, 'py> ContentString<'t> {
//~^ needless_lifetimes
// `'py` can be elided because of `&'_ self`
fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {
match self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(content) => Content::T2(f(content)),
}
}
}
impl<'t, 'py> ContentString<'t> {
// `'py` should not be elided as the default lifetime, even if working, could be named as `'t`
fn map_content4(self, f: impl FnOnce(&'t str) -> &'t str, o: &'t str) -> Content<'t, 'py> {
match self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(_) => Content::T2(o),
}
}
}
impl<'t, 'py> ContentString<'t> {
//~^ needless_lifetimes
// `'py` can be elided because of `&Self`
fn map_content5(
self: std::pin::Pin<&Self>,
f: impl FnOnce(&'t str) -> &'t str,
o: &'t str,
) -> Content<'t, 'py> {
match *self {
Self::T1(content) => Content::T1(f(content)),
Self::T2(_) => Content::T2(o),
}
}
}
struct Cx<'a, 'b> {
a: &'a u32,
b: &'b u32,
}
// `'c` cannot be elided because we have several input lifetimes
fn one_explicit<'b>(x: Cx<'_, 'b>) -> &'b u32 {
&x.b
//~^ needless_borrow
}
}
fn main() {}
+34 -203
View File
@@ -108,32 +108,8 @@ LL - fn where_clause_without_lt<'a, T>(x: &'a u8, _y: u8) -> Result<&'a u8, ()>
LL + fn where_clause_without_lt<T>(x: &u8, _y: u8) -> Result<&u8, ()>
|
error: the following explicit lifetimes could be elided: 'a, 'b
--> tests/ui/needless_lifetimes.rs:109:21
|
LL | fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {}
| ^^ ^^ ^^ ^^
|
help: elide the lifetimes
|
LL - fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {}
LL + fn lifetime_param_2(_x: Ref<'_>, _y: &u8) {}
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:134:15
|
LL | fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>
| ^^ ^^ ^^
|
help: elide the lifetimes
|
LL - fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>
LL + fn fn_bound_2<F, I>(_m: Lt<'_, I>, _f: F) -> Lt<'_, I>
|
error: the following explicit lifetimes could be elided: 's
--> tests/ui/needless_lifetimes.rs:165:21
--> tests/ui/needless_lifetimes.rs:127:21
|
LL | fn self_and_out<'s>(&'s self) -> &'s u8 {
| ^^ ^^ ^^
@@ -145,7 +121,7 @@ LL + fn self_and_out(&self) -> &u8 {
|
error: the following explicit lifetimes could be elided: 't
--> tests/ui/needless_lifetimes.rs:173:30
--> tests/ui/needless_lifetimes.rs:135:30
|
LL | fn self_and_in_out_1<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 {
| ^^ ^^
@@ -157,7 +133,7 @@ LL + fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8 {
|
error: the following explicit lifetimes could be elided: 's
--> tests/ui/needless_lifetimes.rs:181:26
--> tests/ui/needless_lifetimes.rs:143:26
|
LL | fn self_and_in_out_2<'s, 't>(&'s self, x: &'t u8) -> &'t u8 {
| ^^ ^^
@@ -169,7 +145,7 @@ LL + fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8 {
|
error: the following explicit lifetimes could be elided: 's, 't
--> tests/ui/needless_lifetimes.rs:186:29
--> tests/ui/needless_lifetimes.rs:148:29
|
LL | fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) {}
| ^^ ^^ ^^ ^^
@@ -181,31 +157,7 @@ LL + fn distinct_self_and_in(&self, _x: &u8) {}
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:206:19
|
LL | fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str {
| ^^ ^^ ^^
|
help: elide the lifetimes
|
LL - fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str {
LL + fn struct_with_lt(_foo: Foo<'_>) -> &str {
|
error: the following explicit lifetimes could be elided: 'b
--> tests/ui/needless_lifetimes.rs:225:25
|
LL | fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {
| ^^ ^^
|
help: elide the lifetimes
|
LL - fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {
LL + fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:234:21
--> tests/ui/needless_lifetimes.rs:172:21
|
LL | fn struct_with_lt4b<'a, 'b>(_foo: &'a Foo<'b>) -> &'b str {
| ^^ ^^
@@ -217,7 +169,7 @@ LL + fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:250:22
--> tests/ui/needless_lifetimes.rs:188:22
|
LL | fn trait_obj_elided2<'a>(_arg: &'a dyn Drop) -> &'a str {
| ^^ ^^ ^^
@@ -229,31 +181,7 @@ LL + fn trait_obj_elided2(_arg: &dyn Drop) -> &str {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:257:18
|
LL | fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str {
| ^^ ^^ ^^
|
help: elide the lifetimes
|
LL - fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str {
LL + fn alias_with_lt(_foo: FooAlias<'_>) -> &str {
|
error: the following explicit lifetimes could be elided: 'b
--> tests/ui/needless_lifetimes.rs:276:24
|
LL | fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {
| ^^ ^^
|
help: elide the lifetimes
|
LL - fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {
LL + fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:285:20
--> tests/ui/needless_lifetimes.rs:199:20
|
LL | fn alias_with_lt4b<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'b str {
| ^^ ^^
@@ -265,7 +193,7 @@ LL + fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:290:30
--> tests/ui/needless_lifetimes.rs:204:30
|
LL | fn named_input_elided_output<'a>(_arg: &'a str) -> &str {
| ^^ ^^ ^
@@ -277,7 +205,7 @@ LL + fn named_input_elided_output(_arg: &str) -> &str {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:299:19
--> tests/ui/needless_lifetimes.rs:213:19
|
LL | fn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) {
| ^^ ^^
@@ -289,19 +217,7 @@ LL + fn trait_bound_ok<T: WithLifetime<'static>>(_: &u8, _: T) {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:336:24
|
LL | fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> {
| ^^ ^^ ^^
|
help: elide the lifetimes
|
LL - fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> {
LL + fn out_return_type_lts(e: &str) -> Cow<'_> {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:344:24
--> tests/ui/needless_lifetimes.rs:249:24
|
LL | fn needless_lt<'a>(x: &'a u8) {}
| ^^ ^^
@@ -313,7 +229,7 @@ LL + fn needless_lt(x: &u8) {}
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:349:24
--> tests/ui/needless_lifetimes.rs:254:24
|
LL | fn needless_lt<'a>(_x: &'a u8) {}
| ^^ ^^
@@ -325,31 +241,7 @@ LL + fn needless_lt(_x: &u8) {}
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:361:10
|
LL | impl<'a> Foo for Baz<'a> {}
| ^^ ^^
|
help: elide the lifetimes
|
LL - impl<'a> Foo for Baz<'a> {}
LL + impl Foo for Baz<'_> {}
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:364:16
|
LL | fn baz<'a>(&'a self) -> impl Foo + 'a {
| ^^ ^^ ^^
|
help: elide the lifetimes
|
LL - fn baz<'a>(&'a self) -> impl Foo + 'a {
LL + fn baz(&self) -> impl Foo + '_ {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:397:55
--> tests/ui/needless_lifetimes.rs:285:55
|
LL | fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 {
| ^^ ^^ ^^
@@ -361,7 +253,7 @@ LL + fn impl_trait_elidable_nested_anonymous_lifetimes(i: &i32, f: impl Fn(&
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:407:26
--> tests/ui/needless_lifetimes.rs:295:26
|
LL | fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 {
| ^^ ^^ ^^
@@ -373,7 +265,7 @@ LL + fn generics_elidable<T: Fn(&i32) -> &i32>(i: &i32, f: T) -> &i32 {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:420:30
--> tests/ui/needless_lifetimes.rs:308:30
|
LL | fn where_clause_elidable<'a, T>(i: &'a i32, f: T) -> &'a i32
| ^^ ^^ ^^
@@ -385,7 +277,7 @@ LL + fn where_clause_elidable<T>(i: &i32, f: T) -> &i32
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:436:28
--> tests/ui/needless_lifetimes.rs:324:28
|
LL | fn pointer_fn_elidable<'a>(i: &'a i32, f: fn(&i32) -> &i32) -> &'a i32 {
| ^^ ^^ ^^
@@ -397,7 +289,7 @@ LL + fn pointer_fn_elidable(i: &i32, f: fn(&i32) -> &i32) -> &i32 {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:450:28
--> tests/ui/needless_lifetimes.rs:338:28
|
LL | fn nested_fn_pointer_3<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 {
| ^^ ^^
@@ -409,7 +301,7 @@ LL + fn nested_fn_pointer_3(_: &i32) -> fn(fn(&i32) -> &i32) -> i32 {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:454:28
--> tests/ui/needless_lifetimes.rs:342:28
|
LL | fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) {
| ^^ ^^
@@ -421,7 +313,7 @@ LL + fn nested_fn_pointer_4(_: &i32) -> impl Fn(fn(&i32)) {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:477:21
--> tests/ui/needless_lifetimes.rs:365:21
|
LL | fn implicit<'a>(&'a self) -> &'a () {
| ^^ ^^ ^^
@@ -433,7 +325,7 @@ LL + fn implicit(&self) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:481:25
--> tests/ui/needless_lifetimes.rs:369:25
|
LL | fn implicit_mut<'a>(&'a mut self) -> &'a () {
| ^^ ^^ ^^
@@ -445,7 +337,7 @@ LL + fn implicit_mut(&mut self) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:486:21
--> tests/ui/needless_lifetimes.rs:374:21
|
LL | fn explicit<'a>(self: &'a Arc<Self>) -> &'a () {
| ^^ ^^ ^^
@@ -457,7 +349,7 @@ LL + fn explicit(self: &Arc<Self>) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:491:25
--> tests/ui/needless_lifetimes.rs:379:25
|
LL | fn explicit_mut<'a>(self: &'a mut Rc<Self>) -> &'a () {
| ^^ ^^ ^^
@@ -469,7 +361,7 @@ LL + fn explicit_mut(self: &mut Rc<Self>) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:504:31
--> tests/ui/needless_lifetimes.rs:392:31
|
LL | fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a () {
| ^^ ^^ ^^
@@ -481,7 +373,7 @@ LL + fn lifetime_elsewhere(self: Box<Self>, here: &()) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:511:21
--> tests/ui/needless_lifetimes.rs:399:21
|
LL | fn implicit<'a>(&'a self) -> &'a ();
| ^^ ^^ ^^
@@ -493,7 +385,7 @@ LL + fn implicit(&self) -> &();
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:513:30
--> tests/ui/needless_lifetimes.rs:401:30
|
LL | fn implicit_provided<'a>(&'a self) -> &'a () {
| ^^ ^^ ^^
@@ -505,7 +397,7 @@ LL + fn implicit_provided(&self) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:519:21
--> tests/ui/needless_lifetimes.rs:407:21
|
LL | fn explicit<'a>(self: &'a Arc<Self>) -> &'a ();
| ^^ ^^ ^^
@@ -517,7 +409,7 @@ LL + fn explicit(self: &Arc<Self>) -> &();
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:522:30
--> tests/ui/needless_lifetimes.rs:410:30
|
LL | fn explicit_provided<'a>(self: &'a Arc<Self>) -> &'a () {
| ^^ ^^ ^^
@@ -529,7 +421,7 @@ LL + fn explicit_provided(self: &Arc<Self>) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:533:31
--> tests/ui/needless_lifetimes.rs:421:31
|
LL | fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a ();
| ^^ ^^ ^^
@@ -541,7 +433,7 @@ LL + fn lifetime_elsewhere(self: Box<Self>, here: &()) -> &();
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:535:40
--> tests/ui/needless_lifetimes.rs:423:40
|
LL | fn lifetime_elsewhere_provided<'a>(self: Box<Self>, here: &'a ()) -> &'a () {
| ^^ ^^ ^^
@@ -553,7 +445,7 @@ LL + fn lifetime_elsewhere_provided(self: Box<Self>, here: &()) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:545:12
--> tests/ui/needless_lifetimes.rs:433:12
|
LL | fn foo<'a>(x: &'a u8, y: &'_ u8) {}
| ^^ ^^
@@ -565,7 +457,7 @@ LL + fn foo(x: &u8, y: &'_ u8) {}
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:548:12
--> tests/ui/needless_lifetimes.rs:436:12
|
LL | fn bar<'a>(x: &'a u8, y: &'_ u8, z: &'_ u8) {}
| ^^ ^^
@@ -577,7 +469,7 @@ LL + fn bar(x: &u8, y: &'_ u8, z: &'_ u8) {}
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:556:18
--> tests/ui/needless_lifetimes.rs:444:18
|
LL | fn one_input<'a>(x: &'a u8) -> &'a u8 {
| ^^ ^^ ^^
@@ -589,7 +481,7 @@ LL + fn one_input(x: &u8) -> &u8 {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:562:42
--> tests/ui/needless_lifetimes.rs:450:42
|
LL | fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 {
| ^^ ^^
@@ -601,7 +493,7 @@ LL + fn multiple_inputs_output_not_elided<'b>(x: &u8, y: &'b u8, z: &'b u8)
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:579:22
--> tests/ui/needless_lifetimes.rs:467:22
|
LL | fn one_input<'a>(x: &'a u8) -> &'a u8 {
| ^^ ^^ ^^
@@ -613,66 +505,5 @@ LL - fn one_input<'a>(x: &'a u8) -> &'a u8 {
LL + fn one_input(x: &u8) -> &u8 {
|
error: the following explicit lifetimes could be elided: 'py
--> tests/ui/needless_lifetimes.rs:675:14
|
LL | impl<'t, 'py> ContentString<'t> {
| ^^^
...
LL | fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {
| ^^^
|
help: elide the lifetimes
|
LL ~ impl<'t> ContentString<'t> {
LL |
LL | // `'py` can be elided because of `&self`
LL ~ fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> {
|
error: the following explicit lifetimes could be elided: 'py
--> tests/ui/needless_lifetimes.rs:686:14
|
LL | impl<'t, 'py> ContentString<'t> {
| ^^^
...
LL | fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {
| ^^^
|
help: elide the lifetimes
|
LL ~ impl<'t> ContentString<'t> {
LL |
LL | // `'py` can be elided because of `&'_ self`
LL ~ fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> {
|
error: the following explicit lifetimes could be elided: 'py
--> tests/ui/needless_lifetimes.rs:707:14
|
LL | impl<'t, 'py> ContentString<'t> {
| ^^^
...
LL | ) -> Content<'t, 'py> {
| ^^^
|
help: elide the lifetimes
|
LL ~ impl<'t> ContentString<'t> {
LL |
...
LL | o: &'t str,
LL ~ ) -> Content<'t, '_> {
|
error: this expression creates a reference which is immediately dereferenced by the compiler
--> tests/ui/needless_lifetimes.rs:729:9
|
LL | &x.b
| ^^^^ help: change this to: `x.b`
|
= note: `-D clippy::needless-borrow` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::needless_borrow)]`
error: aborting due to 55 previous errors
error: aborting due to 42 previous errors