Rust 1.81 and later support elision with explicit self types

Commit 9ef6e2199c introduced a check to
ensure that Clippy doesn't consider a lifetime present in an explicit
self type as being the default for an elided output lifetime. For
example, elision did not work in the case like:

```rust
  fn func(self: &Rc<Self>, &str) -> &str { … }
```

Since Rust 1.81.0, the lifetime in the self type is now considered
the default for elision. Elision should then be suggested when
appropriate.
This commit is contained in:
Samuel Tardieu
2025-01-13 10:02:46 +01:00
parent 8f257c71a3
commit 8b7cfc75dd
6 changed files with 184 additions and 74 deletions
+1 -1
View File
@@ -681,7 +681,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
store.register_late_pass(|_| Box::new(unit_types::UnitTypes));
store.register_late_pass(move |_| Box::new(loops::Loops::new(conf)));
store.register_late_pass(|_| Box::<main_recursion::MainRecursion>::default());
store.register_late_pass(|_| Box::new(lifetimes::Lifetimes));
store.register_late_pass(move |_| Box::new(lifetimes::Lifetimes::new(conf)));
store.register_late_pass(|_| Box::new(entry::HashMapPass));
store.register_late_pass(|_| Box::new(minmax::MinMaxPass));
store.register_late_pass(|_| Box::new(zero_div_zero::ZeroDiv));
+39 -13
View File
@@ -1,4 +1,6 @@
use clippy_config::Conf;
use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::trait_ref_of_method;
use itertools::Itertools;
use rustc_ast::visit::{try_visit, walk_list};
@@ -20,7 +22,7 @@
use rustc_middle::hir::map::Map;
use rustc_middle::hir::nested_filter as middle_nested_filter;
use rustc_middle::lint::in_external_macro;
use rustc_session::declare_lint_pass;
use rustc_session::impl_lint_pass;
use rustc_span::Span;
use rustc_span::def_id::LocalDefId;
use rustc_span::symbol::{Ident, kw};
@@ -91,7 +93,19 @@
"unused lifetimes in function definitions"
}
declare_lint_pass!(Lifetimes => [NEEDLESS_LIFETIMES, EXTRA_UNUSED_LIFETIMES]);
pub struct Lifetimes {
msrv: Msrv,
}
impl Lifetimes {
pub fn new(conf: &'static Conf) -> Self {
Self {
msrv: conf.msrv.clone(),
}
}
}
impl_lint_pass!(Lifetimes => [NEEDLESS_LIFETIMES, EXTRA_UNUSED_LIFETIMES]);
impl<'tcx> LateLintPass<'tcx> for Lifetimes {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
@@ -102,7 +116,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
..
} = item.kind
{
check_fn_inner(cx, sig, Some(id), None, generics, item.span, true);
check_fn_inner(cx, sig, Some(id), None, generics, item.span, true, &self.msrv);
} else if let ItemKind::Impl(impl_) = item.kind {
if !item.span.from_expansion() {
report_extra_impl_lifetimes(cx, impl_);
@@ -121,6 +135,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>)
item.generics,
item.span,
report_extra_lifetimes,
&self.msrv,
);
}
}
@@ -131,11 +146,14 @@ fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>
TraitFn::Required(sig) => (None, Some(sig)),
TraitFn::Provided(id) => (Some(id), None),
};
check_fn_inner(cx, sig, body, trait_sig, item.generics, item.span, true);
check_fn_inner(cx, sig, body, trait_sig, item.generics, item.span, true, &self.msrv);
}
}
extract_msrv_attr!(LateContext);
}
#[allow(clippy::too_many_arguments)]
fn check_fn_inner<'tcx>(
cx: &LateContext<'tcx>,
sig: &'tcx FnSig<'_>,
@@ -144,6 +162,7 @@ fn check_fn_inner<'tcx>(
generics: &'tcx Generics<'_>,
span: Span,
report_extra_lifetimes: bool,
msrv: &Msrv,
) {
if in_external_macro(cx.sess(), span) || has_where_lifetimes(cx, generics) {
return;
@@ -195,7 +214,7 @@ fn check_fn_inner<'tcx>(
}
}
if let Some((elidable_lts, usages)) = could_use_elision(cx, sig.decl, body, trait_sig, generics.params) {
if let Some((elidable_lts, usages)) = could_use_elision(cx, sig.decl, body, trait_sig, generics.params, msrv) {
if usages.iter().any(|usage| !usage.ident.span.eq_ctxt(span)) {
return;
}
@@ -216,6 +235,7 @@ fn could_use_elision<'tcx>(
body: Option<BodyId>,
trait_sig: Option<&[Ident]>,
named_generics: &'tcx [GenericParam<'_>],
msrv: &Msrv,
) -> Option<(Vec<LocalDefId>, Vec<Lifetime>)> {
// There are two scenarios where elision works:
// * no output references, all input references have different LT
@@ -249,17 +269,17 @@ fn could_use_elision<'tcx>(
let input_lts = input_visitor.lts;
let output_lts = output_visitor.lts;
if let Some(trait_sig) = trait_sig {
if explicit_self_type(cx, func, trait_sig.first().copied()) {
return None;
}
if let Some(trait_sig) = trait_sig
&& non_elidable_self_type(cx, func, trait_sig.first().copied(), msrv)
{
return None;
}
if let Some(body_id) = body {
let body = cx.tcx.hir().body(body_id);
let first_ident = body.params.first().and_then(|param| param.pat.simple_ident());
if explicit_self_type(cx, func, first_ident) {
if non_elidable_self_type(cx, func, first_ident, msrv) {
return None;
}
@@ -332,9 +352,15 @@ fn allowed_lts_from(named_generics: &[GenericParam<'_>]) -> FxIndexSet<LocalDefI
.collect()
}
// elision doesn't work for explicit self types, see rust-lang/rust#69064
fn explicit_self_type<'tcx>(cx: &LateContext<'tcx>, func: &FnDecl<'tcx>, ident: Option<Ident>) -> bool {
if let Some(ident) = ident
// elision doesn't work for explicit self types before Rust 1.81, see rust-lang/rust#69064
fn non_elidable_self_type<'tcx>(
cx: &LateContext<'tcx>,
func: &FnDecl<'tcx>,
ident: Option<Ident>,
msrv: &Msrv,
) -> bool {
if !msrv.meets(msrvs::EXPLICIT_SELF_TYPE_ELISION)
&& let Some(ident) = ident
&& ident.name == kw::SelfLower
&& !func.implicit_self.has_implicit_self()
&& let Some(self_ty) = func.inputs.first()
+1 -1
View File
@@ -20,7 +20,7 @@ macro_rules! msrv_aliases {
msrv_aliases! {
1,83,0 { CONST_EXTERN_FN, CONST_FLOAT_BITS_CONV, CONST_FLOAT_CLASSIFY }
1,82,0 { IS_NONE_OR, REPEAT_N, RAW_REF_OP }
1,81,0 { LINT_REASONS_STABILIZATION, ERROR_IN_CORE }
1,81,0 { LINT_REASONS_STABILIZATION, ERROR_IN_CORE, EXPLICIT_SELF_TYPE_ELISION }
1,80,0 { BOX_INTO_ITER }
1,77,0 { C_STR_LITERALS }
1,76,0 { PTR_FROM_REF, OPTION_RESULT_INSPECT }
+23 -5
View File
@@ -6,6 +6,7 @@
clippy::boxed_local,
clippy::extra_unused_type_parameters,
clippy::needless_pass_by_value,
clippy::redundant_allocation,
clippy::unnecessary_wraps,
dyn_drop,
clippy::get_first
@@ -443,11 +444,20 @@ mod issue7296 {
fn implicit_mut(&mut self) -> &() {
&()
}
fn explicit<'a>(self: &'a Arc<Self>) -> &'a () {
#[clippy::msrv = "1.81"]
fn explicit(self: &Arc<Self>) -> &() {
&()
}
fn explicit_mut<'a>(self: &'a mut Rc<Self>) -> &'a () {
#[clippy::msrv = "1.81"]
fn explicit_mut(self: &mut Rc<Self>) -> &() {
&()
}
#[clippy::msrv = "1.80"]
fn explicit_older<'a>(self: &'a Arc<Self>) -> &'a () {
&()
}
#[clippy::msrv = "1.80"]
fn explicit_mut_older<'a>(self: &'a mut Rc<Self>) -> &'a () {
&()
}
@@ -462,8 +472,16 @@ mod issue7296 {
&()
}
fn explicit<'a>(self: &'a Arc<Self>) -> &'a ();
fn explicit_provided<'a>(self: &'a Arc<Self>) -> &'a () {
#[clippy::msrv = "1.81"]
fn explicit(self: &Arc<Self>) -> &();
#[clippy::msrv = "1.81"]
fn explicit_provided(self: &Arc<Self>) -> &() {
&()
}
#[clippy::msrv = "1.80"]
fn explicit_older<'a>(self: &'a Arc<Self>) -> &'a ();
#[clippy::msrv = "1.80"]
fn explicit_provided_older<'a>(self: &'a Arc<Self>) -> &'a () {
&()
}
+19 -1
View File
@@ -6,6 +6,7 @@
clippy::boxed_local,
clippy::extra_unused_type_parameters,
clippy::needless_pass_by_value,
clippy::redundant_allocation,
clippy::unnecessary_wraps,
dyn_drop,
clippy::get_first
@@ -443,13 +444,22 @@ fn implicit<'a>(&'a self) -> &'a () {
fn implicit_mut<'a>(&'a mut self) -> &'a () {
&()
}
#[clippy::msrv = "1.81"]
fn explicit<'a>(self: &'a Arc<Self>) -> &'a () {
&()
}
#[clippy::msrv = "1.81"]
fn explicit_mut<'a>(self: &'a mut Rc<Self>) -> &'a () {
&()
}
#[clippy::msrv = "1.80"]
fn explicit_older<'a>(self: &'a Arc<Self>) -> &'a () {
&()
}
#[clippy::msrv = "1.80"]
fn explicit_mut_older<'a>(self: &'a mut Rc<Self>) -> &'a () {
&()
}
fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a () {
&()
@@ -462,10 +472,18 @@ fn implicit_provided<'a>(&'a self) -> &'a () {
&()
}
#[clippy::msrv = "1.81"]
fn explicit<'a>(self: &'a Arc<Self>) -> &'a ();
#[clippy::msrv = "1.81"]
fn explicit_provided<'a>(self: &'a Arc<Self>) -> &'a () {
&()
}
#[clippy::msrv = "1.80"]
fn explicit_older<'a>(self: &'a Arc<Self>) -> &'a ();
#[clippy::msrv = "1.80"]
fn explicit_provided_older<'a>(self: &'a Arc<Self>) -> &'a () {
&()
}
fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a ();
fn lifetime_elsewhere_provided<'a>(self: Box<Self>, here: &'a ()) -> &'a () {
+101 -53
View File
@@ -1,5 +1,5 @@
error: elided lifetime has a name
--> tests/ui/needless_lifetimes.rs:266:52
--> tests/ui/needless_lifetimes.rs:267:52
|
LL | fn named_input_elided_output<'a>(_arg: &'a str) -> &str {
| -- ^ this elided lifetime gets resolved as `'a`
@@ -10,7 +10,7 @@ LL | fn named_input_elided_output<'a>(_arg: &'a str) -> &str {
= help: to override `-D warnings` add `#[allow(elided_named_lifetimes)]`
error: the following explicit lifetimes could be elided: 'a, 'b
--> tests/ui/needless_lifetimes.rs:17:23
--> tests/ui/needless_lifetimes.rs:18:23
|
LL | fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {}
| ^^ ^^ ^^ ^^
@@ -24,7 +24,7 @@ LL + fn distinct_lifetimes(_x: &u8, _y: &u8, _z: u8) {}
|
error: the following explicit lifetimes could be elided: 'a, 'b
--> tests/ui/needless_lifetimes.rs:19:24
--> tests/ui/needless_lifetimes.rs:20:24
|
LL | fn distinct_and_static<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: &'static u8) {}
| ^^ ^^ ^^ ^^
@@ -36,7 +36,7 @@ LL + fn distinct_and_static(_x: &u8, _y: &u8, _z: &'static u8) {}
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:29:15
--> tests/ui/needless_lifetimes.rs:30:15
|
LL | fn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 {
| ^^ ^^ ^^
@@ -48,7 +48,7 @@ LL + fn in_and_out(x: &u8, _y: u8) -> &u8 {
|
error: the following explicit lifetimes could be elided: 'b
--> tests/ui/needless_lifetimes.rs:41:31
--> tests/ui/needless_lifetimes.rs:42:31
|
LL | fn multiple_in_and_out_2a<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 {
| ^^ ^^
@@ -60,7 +60,7 @@ LL + fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8 {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:48:27
--> tests/ui/needless_lifetimes.rs:49:27
|
LL | fn multiple_in_and_out_2b<'a, 'b>(_x: &'a u8, y: &'b u8) -> &'b u8 {
| ^^ ^^
@@ -72,7 +72,7 @@ LL + fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8 {
|
error: the following explicit lifetimes could be elided: 'b
--> tests/ui/needless_lifetimes.rs:65:26
--> tests/ui/needless_lifetimes.rs:66:26
|
LL | fn deep_reference_1a<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> {
| ^^ ^^
@@ -84,7 +84,7 @@ LL + fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()> {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:72:22
--> tests/ui/needless_lifetimes.rs:73:22
|
LL | fn deep_reference_1b<'a, 'b>(_x: &'a u8, y: &'b u8) -> Result<&'b u8, ()> {
| ^^ ^^
@@ -96,7 +96,7 @@ LL + fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()> {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:81:21
--> tests/ui/needless_lifetimes.rs:82:21
|
LL | fn deep_reference_3<'a>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> {
| ^^ ^^ ^^
@@ -108,7 +108,7 @@ LL + fn deep_reference_3(x: &u8, _y: u8) -> Result<&u8, ()> {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:86:28
--> tests/ui/needless_lifetimes.rs:87:28
|
LL | fn where_clause_without_lt<'a, T>(x: &'a u8, _y: u8) -> Result<&'a u8, ()>
| ^^ ^^ ^^
@@ -120,7 +120,7 @@ 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:98:21
--> tests/ui/needless_lifetimes.rs:99:21
|
LL | fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {}
| ^^ ^^ ^^ ^^
@@ -132,7 +132,7 @@ LL + fn lifetime_param_2(_x: Ref<'_>, _y: &u8) {}
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:122:15
--> tests/ui/needless_lifetimes.rs:123:15
|
LL | fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>
| ^^ ^^ ^^
@@ -144,7 +144,7 @@ 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:152:21
--> tests/ui/needless_lifetimes.rs:153:21
|
LL | fn self_and_out<'s>(&'s self) -> &'s u8 {
| ^^ ^^ ^^
@@ -156,7 +156,7 @@ LL + fn self_and_out(&self) -> &u8 {
|
error: the following explicit lifetimes could be elided: 't
--> tests/ui/needless_lifetimes.rs:159:30
--> tests/ui/needless_lifetimes.rs:160:30
|
LL | fn self_and_in_out_1<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 {
| ^^ ^^
@@ -168,7 +168,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:166:26
--> tests/ui/needless_lifetimes.rs:167:26
|
LL | fn self_and_in_out_2<'s, 't>(&'s self, x: &'t u8) -> &'t u8 {
| ^^ ^^
@@ -180,7 +180,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:170:29
--> tests/ui/needless_lifetimes.rs:171:29
|
LL | fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) {}
| ^^ ^^ ^^ ^^
@@ -192,7 +192,7 @@ LL + fn distinct_self_and_in(&self, _x: &u8) {}
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:189:19
--> tests/ui/needless_lifetimes.rs:190:19
|
LL | fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str {
| ^^ ^^ ^^
@@ -204,7 +204,7 @@ LL + fn struct_with_lt(_foo: Foo<'_>) -> &str {
|
error: the following explicit lifetimes could be elided: 'b
--> tests/ui/needless_lifetimes.rs:207:25
--> tests/ui/needless_lifetimes.rs:208:25
|
LL | fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {
| ^^ ^^
@@ -216,7 +216,7 @@ 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:215:21
--> tests/ui/needless_lifetimes.rs:216:21
|
LL | fn struct_with_lt4b<'a, 'b>(_foo: &'a Foo<'b>) -> &'b str {
| ^^ ^^
@@ -228,7 +228,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:230:22
--> tests/ui/needless_lifetimes.rs:231:22
|
LL | fn trait_obj_elided2<'a>(_arg: &'a dyn Drop) -> &'a str {
| ^^ ^^ ^^
@@ -240,7 +240,7 @@ LL + fn trait_obj_elided2(_arg: &dyn Drop) -> &str {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:236:18
--> tests/ui/needless_lifetimes.rs:237:18
|
LL | fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str {
| ^^ ^^ ^^
@@ -252,7 +252,7 @@ LL + fn alias_with_lt(_foo: FooAlias<'_>) -> &str {
|
error: the following explicit lifetimes could be elided: 'b
--> tests/ui/needless_lifetimes.rs:254:24
--> tests/ui/needless_lifetimes.rs:255:24
|
LL | fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {
| ^^ ^^
@@ -264,7 +264,7 @@ 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:262:20
--> tests/ui/needless_lifetimes.rs:263:20
|
LL | fn alias_with_lt4b<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'b str {
| ^^ ^^
@@ -276,7 +276,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:266:30
--> tests/ui/needless_lifetimes.rs:267:30
|
LL | fn named_input_elided_output<'a>(_arg: &'a str) -> &str {
| ^^ ^^ ^
@@ -288,7 +288,7 @@ LL + fn named_input_elided_output(_arg: &str) -> &str {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:274:19
--> tests/ui/needless_lifetimes.rs:275:19
|
LL | fn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) {
| ^^ ^^
@@ -300,7 +300,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:310:24
--> tests/ui/needless_lifetimes.rs:311:24
|
LL | fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> {
| ^^ ^^ ^^
@@ -312,7 +312,7 @@ LL + fn out_return_type_lts(e: &str) -> Cow<'_> {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:317:24
--> tests/ui/needless_lifetimes.rs:318:24
|
LL | fn needless_lt<'a>(x: &'a u8) {}
| ^^ ^^
@@ -324,7 +324,7 @@ LL + fn needless_lt(x: &u8) {}
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:321:24
--> tests/ui/needless_lifetimes.rs:322:24
|
LL | fn needless_lt<'a>(_x: &'a u8) {}
| ^^ ^^
@@ -336,7 +336,7 @@ LL + fn needless_lt(_x: &u8) {}
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:332:10
--> tests/ui/needless_lifetimes.rs:333:10
|
LL | impl<'a> Foo for Baz<'a> {}
| ^^ ^^
@@ -348,7 +348,7 @@ LL + impl Foo for Baz<'_> {}
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:334:16
--> tests/ui/needless_lifetimes.rs:335:16
|
LL | fn baz<'a>(&'a self) -> impl Foo + 'a {
| ^^ ^^ ^^
@@ -360,7 +360,7 @@ LL + fn baz(&self) -> impl Foo + '_ {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:366:55
--> tests/ui/needless_lifetimes.rs:367:55
|
LL | fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 {
| ^^ ^^ ^^
@@ -372,7 +372,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:375:26
--> tests/ui/needless_lifetimes.rs:376:26
|
LL | fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 {
| ^^ ^^ ^^
@@ -384,7 +384,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:387:30
--> tests/ui/needless_lifetimes.rs:388:30
|
LL | fn where_clause_elidable<'a, T>(i: &'a i32, f: T) -> &'a i32
| ^^ ^^ ^^
@@ -396,7 +396,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:402:28
--> tests/ui/needless_lifetimes.rs:403:28
|
LL | fn pointer_fn_elidable<'a>(i: &'a i32, f: fn(&i32) -> &i32) -> &'a i32 {
| ^^ ^^ ^^
@@ -408,7 +408,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:415:28
--> tests/ui/needless_lifetimes.rs:416:28
|
LL | fn nested_fn_pointer_3<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 {
| ^^ ^^
@@ -420,7 +420,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:418:28
--> tests/ui/needless_lifetimes.rs:419:28
|
LL | fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) {
| ^^ ^^
@@ -432,7 +432,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:440:21
--> tests/ui/needless_lifetimes.rs:441:21
|
LL | fn implicit<'a>(&'a self) -> &'a () {
| ^^ ^^ ^^
@@ -444,7 +444,7 @@ LL + fn implicit(&self) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:443:25
--> tests/ui/needless_lifetimes.rs:444:25
|
LL | fn implicit_mut<'a>(&'a mut self) -> &'a () {
| ^^ ^^ ^^
@@ -456,7 +456,31 @@ LL + fn implicit_mut(&mut self) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:454:31
--> tests/ui/needless_lifetimes.rs:448:21
|
LL | fn explicit<'a>(self: &'a Arc<Self>) -> &'a () {
| ^^ ^^ ^^
|
help: elide the lifetimes
|
LL - fn explicit<'a>(self: &'a Arc<Self>) -> &'a () {
LL + fn explicit(self: &Arc<Self>) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:452:25
|
LL | fn explicit_mut<'a>(self: &'a mut Rc<Self>) -> &'a () {
| ^^ ^^ ^^
|
help: elide the lifetimes
|
LL - fn explicit_mut<'a>(self: &'a mut Rc<Self>) -> &'a () {
LL + fn explicit_mut(self: &mut Rc<Self>) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:464:31
|
LL | fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a () {
| ^^ ^^ ^^
@@ -468,7 +492,7 @@ LL + fn lifetime_elsewhere(self: Box<Self>, here: &()) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:460:21
--> tests/ui/needless_lifetimes.rs:470:21
|
LL | fn implicit<'a>(&'a self) -> &'a ();
| ^^ ^^ ^^
@@ -480,7 +504,7 @@ LL + fn implicit(&self) -> &();
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:461:30
--> tests/ui/needless_lifetimes.rs:471:30
|
LL | fn implicit_provided<'a>(&'a self) -> &'a () {
| ^^ ^^ ^^
@@ -492,7 +516,31 @@ LL + fn implicit_provided(&self) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:470:31
--> tests/ui/needless_lifetimes.rs:476:21
|
LL | fn explicit<'a>(self: &'a Arc<Self>) -> &'a ();
| ^^ ^^ ^^
|
help: elide the lifetimes
|
LL - fn explicit<'a>(self: &'a Arc<Self>) -> &'a ();
LL + fn explicit(self: &Arc<Self>) -> &();
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:478:30
|
LL | fn explicit_provided<'a>(self: &'a Arc<Self>) -> &'a () {
| ^^ ^^ ^^
|
help: elide the lifetimes
|
LL - fn explicit_provided<'a>(self: &'a Arc<Self>) -> &'a () {
LL + fn explicit_provided(self: &Arc<Self>) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:488:31
|
LL | fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a ();
| ^^ ^^ ^^
@@ -504,7 +552,7 @@ LL + fn lifetime_elsewhere(self: Box<Self>, here: &()) -> &();
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:471:40
--> tests/ui/needless_lifetimes.rs:489:40
|
LL | fn lifetime_elsewhere_provided<'a>(self: Box<Self>, here: &'a ()) -> &'a () {
| ^^ ^^ ^^
@@ -516,7 +564,7 @@ LL + fn lifetime_elsewhere_provided(self: Box<Self>, here: &()) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:480:12
--> tests/ui/needless_lifetimes.rs:498:12
|
LL | fn foo<'a>(x: &'a u8, y: &'_ u8) {}
| ^^ ^^
@@ -528,7 +576,7 @@ LL + fn foo(x: &u8, y: &'_ u8) {}
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:482:12
--> tests/ui/needless_lifetimes.rs:500:12
|
LL | fn bar<'a>(x: &'a u8, y: &'_ u8, z: &'_ u8) {}
| ^^ ^^
@@ -540,7 +588,7 @@ LL + fn bar(x: &u8, y: &'_ u8, z: &'_ u8) {}
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:489:18
--> tests/ui/needless_lifetimes.rs:507:18
|
LL | fn one_input<'a>(x: &'a u8) -> &'a u8 {
| ^^ ^^ ^^
@@ -552,7 +600,7 @@ LL + fn one_input(x: &u8) -> &u8 {
|
error: the following explicit lifetimes could be elided: 'a
--> tests/ui/needless_lifetimes.rs:494:42
--> tests/ui/needless_lifetimes.rs:512:42
|
LL | fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 {
| ^^ ^^
@@ -564,7 +612,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:510:22
--> tests/ui/needless_lifetimes.rs:528:22
|
LL | fn one_input<'a>(x: &'a u8) -> &'a u8 {
| ^^ ^^ ^^
@@ -577,7 +625,7 @@ LL + fn one_input(x: &u8) -> &u8 {
|
error: the following explicit lifetimes could be elided: 'py
--> tests/ui/needless_lifetimes.rs:605:14
--> tests/ui/needless_lifetimes.rs:623:14
|
LL | impl<'t, 'py> ContentString<'t> {
| ^^^
@@ -593,7 +641,7 @@ LL ~ fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Conte
|
error: the following explicit lifetimes could be elided: 'py
--> tests/ui/needless_lifetimes.rs:615:14
--> tests/ui/needless_lifetimes.rs:633:14
|
LL | impl<'t, 'py> ContentString<'t> {
| ^^^
@@ -609,7 +657,7 @@ LL ~ fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Co
|
error: the following explicit lifetimes could be elided: 'py
--> tests/ui/needless_lifetimes.rs:635:14
--> tests/ui/needless_lifetimes.rs:653:14
|
LL | impl<'t, 'py> ContentString<'t> {
| ^^^
@@ -627,7 +675,7 @@ LL ~ ) -> Content<'t, '_> {
|
error: this expression creates a reference which is immediately dereferenced by the compiler
--> tests/ui/needless_lifetimes.rs:656:9
--> tests/ui/needless_lifetimes.rs:674:9
|
LL | &x.b
| ^^^^ help: change this to: `x.b`
@@ -635,5 +683,5 @@ LL | &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 52 previous errors
error: aborting due to 56 previous errors