mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-15 20:45:45 +03:00
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:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(|<| 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)
|
||||
}
|
||||
|
||||
+3
-3
@@ -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 }
|
||||
}
|
||||
+3
-3
@@ -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 }
|
||||
}
|
||||
+5
-5
@@ -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 {
|
||||
| ^^ ^^ ^^
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,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,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() {}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user