Adress review comments

This commit is contained in:
Samuel Moelius 2022-10-30 06:47:35 -04:00
parent 10b7fabbf3
commit 2c44398487
8 changed files with 259 additions and 119 deletions

View file

@ -236,7 +236,6 @@ fn explicit_self_type<'tcx>(cx: &LateContext<'tcx>, func: &FnDecl<'tcx>, ident:
}
}
#[expect(clippy::too_many_lines)]
fn could_use_elision<'tcx>(
cx: &LateContext<'tcx>,
func: &'tcx FnDecl<'_>,
@ -331,50 +330,32 @@ fn could_use_elision<'tcx>(
}
}
// no input lifetimes? easy case!
if input_lts.is_empty() {
None
} else if output_lts.is_empty() {
// no output lifetimes, check distinctness of input lifetimes
// only unnamed and static, ok
let unnamed_and_static = input_lts.iter().all(|lt| *lt == RefLt::Unnamed || *lt == RefLt::Static);
if unnamed_and_static {
return None;
}
// we have no output reference, so we can elide explicit lifetimes that occur at most once
let elidable_lts = named_lifetime_occurrences(&input_lts)
.into_iter()
.filter_map(|(def_id, occurrences)| {
if occurrences <= 1 {
Some((def_id, input_visitor.sample_generic_arg_span.get(&def_id).copied()))
} else {
None
}
})
.collect::<Vec<_>>();
if elidable_lts.is_empty() {
None
} else {
Some(elidable_lts)
}
} else {
// we have output references, so we need one input reference,
// and all output lifetimes must be the same
if input_lts.len() == 1 {
match (&input_lts[0], &output_lts[0]) {
(&RefLt::Named(n1), &RefLt::Named(n2)) if n1 == n2 => {
Some(vec![(n1, input_visitor.sample_generic_arg_span.get(&n1).copied())])
},
(&RefLt::Named(n), &RefLt::Unnamed) => {
Some(vec![(n, input_visitor.sample_generic_arg_span.get(&n).copied())])
},
_ => None, /* already elided, different named lifetimes
* or something static going on */
// A lifetime can be newly elided if:
// - It occurs only once among the inputs.
// - If there are multiple input lifetimes, then the newly elided lifetime does not occur among the
// outputs (because eliding such an lifetime would create an ambiguity).
let elidable_lts = named_lifetime_occurrences(&input_lts)
.into_iter()
.filter_map(|(def_id, occurrences)| {
if occurrences <= 1 && (input_lts.len() <= 1 || !output_lts.contains(&RefLt::Named(def_id))) {
Some((
def_id,
input_visitor
.lifetime_generic_arg_spans
.get(&def_id)
.or_else(|| output_visitor.lifetime_generic_arg_spans.get(&def_id))
.copied(),
))
} else {
None
}
} else {
None
}
})
.collect::<Vec<_>>();
if elidable_lts.is_empty() {
None
} else {
Some(elidable_lts)
}
}
@ -397,11 +378,11 @@ fn named_lifetime_occurrences(lts: &[RefLt]) -> Vec<(LocalDefId, usize)> {
let mut occurrences = Vec::new();
for lt in lts {
if let &RefLt::Named(curr_def_id) = lt {
if let Some(i) = occurrences
.iter()
.position(|&(prev_def_id, _)| prev_def_id == curr_def_id)
if let Some(pair) = occurrences
.iter_mut()
.find(|(prev_def_id, _)| *prev_def_id == curr_def_id)
{
occurrences[i].1 += 1;
pair.1 += 1;
} else {
occurrences.push((curr_def_id, 1));
}
@ -416,7 +397,7 @@ const CLOSURE_TRAIT_BOUNDS: [LangItem; 3] = [LangItem::Fn, LangItem::FnMut, Lang
struct RefVisitor<'a, 'tcx> {
cx: &'a LateContext<'tcx>,
lts: Vec<RefLt>,
sample_generic_arg_span: FxHashMap<LocalDefId, Span>,
lifetime_generic_arg_spans: FxHashMap<LocalDefId, Span>,
nested_elision_site_lts: Vec<RefLt>,
unelided_trait_object_lifetime: bool,
}
@ -426,7 +407,7 @@ impl<'a, 'tcx> RefVisitor<'a, 'tcx> {
Self {
cx,
lts: Vec::new(),
sample_generic_arg_span: FxHashMap::default(),
lifetime_generic_arg_spans: FxHashMap::default(),
nested_elision_site_lts: Vec::new(),
unelided_trait_object_lifetime: false,
}
@ -525,7 +506,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
if let GenericArg::Lifetime(l) = generic_arg
&& let LifetimeName::Param(def_id, _) = l.name
{
self.sample_generic_arg_span.entry(def_id).or_insert(l.span);
self.lifetime_generic_arg_spans.entry(def_id).or_insert(l.span);
}
// Replace with `walk_generic_arg` if/when https://github.com/rust-lang/rust/pull/103692 lands.
// walk_generic_arg(self, generic_arg);

View file

@ -83,8 +83,8 @@ fn set_diagnostic<'tcx>(diag: &mut Diagnostic, cx: &LateContext<'tcx>, expr: &'t
/// If the expression is an `ExprKind::Match`, check if the scrutinee has a significant drop that
/// may have a surprising lifetime.
fn has_significant_drop_in_scrutinee<'tcx, 'a>(
cx: &'a LateContext<'tcx>,
fn has_significant_drop_in_scrutinee<'tcx>(
cx: &LateContext<'tcx>,
scrutinee: &'tcx Expr<'tcx>,
source: MatchSource,
) -> Option<(Vec<FoundSigDrop>, &'static str)> {

View file

@ -1,4 +1,4 @@
#![allow(unused)]
#![allow(unused, clippy::needless_lifetimes)]
#![warn(clippy::mut_from_ref)]
struct Foo;

View file

@ -29,11 +29,20 @@ fn multiple_in_and_out_1<'a>(x: &'a u8, _y: &'a u8) -> &'a u8 {
x
}
// No error; multiple input refs.
fn multiple_in_and_out_2<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 {
// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:
// fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8
// ^^^
fn multiple_in_and_out_2a<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 {
x
}
// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:
// fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8
// ^^^
fn multiple_in_and_out_2b<'a, 'b>(_x: &'a u8, y: &'b u8) -> &'b u8 {
y
}
// No error; multiple input refs
async fn func<'a>(args: &[&'a str]) -> Option<&'a str> {
args.get(0).cloned()
@ -44,11 +53,20 @@ fn in_static_and_out<'a>(x: &'a u8, _y: &'static u8) -> &'a u8 {
x
}
// No error.
fn deep_reference_1<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> {
// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:
// fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()>
// ^^^
fn deep_reference_1a<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> {
Ok(x)
}
// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:
// fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()>
// ^^^
fn deep_reference_1b<'a, 'b>(_x: &'a u8, y: &'b u8) -> Result<&'b u8, ()> {
Ok(y)
}
// No error; two input refs.
fn deep_reference_2<'a>(x: Result<&'a u8, &'a u8>) -> &'a u8 {
x.unwrap()
@ -129,11 +147,20 @@ impl X {
&self.x
}
// No error; multiple input refs.
fn self_and_in_out<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 {
// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:
// fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8
// ^^^
fn self_and_in_out_1<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 {
&self.x
}
// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:
// fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8
// ^^^^^
fn self_and_in_out_2<'s, 't>(&'s self, x: &'t u8) -> &'t u8 {
x
}
fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) {}
// No error; same lifetimes on two params.
@ -167,8 +194,19 @@ fn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str {
unimplemented!()
}
// No warning; two input lifetimes.
fn struct_with_lt4<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {
// 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 {
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
// ^^^^
fn struct_with_lt4b<'a, 'b>(_foo: &'a Foo<'b>) -> &'b str {
unimplemented!()
}
@ -203,8 +241,19 @@ fn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str {
unimplemented!()
}
// No warning; two input lifetimes.
fn alias_with_lt4<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {
// 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 {
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
// ^^^^^^^^^
fn alias_with_lt4b<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'b str {
unimplemented!()
}
@ -419,7 +468,7 @@ mod issue7296 {
}
}
mod false_negative {
mod pr_9743_false_negative_fix {
#![allow(unused)]
fn foo<'a>(x: &'a u8, y: &'_ u8) {}
@ -427,4 +476,23 @@ mod false_negative {
fn bar<'a>(x: &'a u8, y: &'_ u8, z: &'_ u8) {}
}
mod pr_9743_output_lifetime_checks {
#![allow(unused)]
// lint: only one input
fn one_input<'a>(x: &'a u8) -> &'a u8 {
unimplemented!()
}
// lint: multiple inputs, output would not be elided
fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 {
unimplemented!()
}
// don't lint: multiple inputs, output would be elided (which would create an ambiguity)
fn multiple_inputs_output_would_be_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'a u8 {
unimplemented!()
}
}
fn main() {}

View file

@ -18,209 +18,299 @@ error: the following explicit lifetimes could be elided: 'a
LL | fn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'b
--> $DIR/needless_lifetimes.rs:35:1
|
LL | fn multiple_in_and_out_2a<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:57:1
--> $DIR/needless_lifetimes.rs:42:1
|
LL | fn multiple_in_and_out_2b<'a, 'b>(_x: &'a u8, y: &'b u8) -> &'b u8 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'b
--> $DIR/needless_lifetimes.rs:59:1
|
LL | fn deep_reference_1a<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:66:1
|
LL | fn deep_reference_1b<'a, 'b>(_x: &'a u8, y: &'b u8) -> Result<&'b u8, ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:75:1
|
LL | fn deep_reference_3<'a>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:62:1
--> $DIR/needless_lifetimes.rs:80:1
|
LL | fn where_clause_without_lt<'a, T>(x: &'a u8, _y: u8) -> Result<&'a u8, ()>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a, 'b
--> $DIR/needless_lifetimes.rs:74:1
--> $DIR/needless_lifetimes.rs:92:1
|
LL | fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: replace with `'_` in generic arguments such as here
--> $DIR/needless_lifetimes.rs:74:37
--> $DIR/needless_lifetimes.rs:92:37
|
LL | fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {}
| ^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:98:1
--> $DIR/needless_lifetimes.rs:116:1
|
LL | fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: replace with `'_` in generic arguments such as here
--> $DIR/needless_lifetimes.rs:98:32
--> $DIR/needless_lifetimes.rs:116:32
|
LL | fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>
| ^^
error: the following explicit lifetimes could be elided: 's
--> $DIR/needless_lifetimes.rs:128:5
--> $DIR/needless_lifetimes.rs:146:5
|
LL | fn self_and_out<'s>(&'s self) -> &'s u8 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 't
--> $DIR/needless_lifetimes.rs:153:5
|
LL | fn self_and_in_out_1<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 's
--> $DIR/needless_lifetimes.rs:160:5
|
LL | fn self_and_in_out_2<'s, 't>(&'s self, x: &'t u8) -> &'t u8 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 's, 't
--> $DIR/needless_lifetimes.rs:137:5
--> $DIR/needless_lifetimes.rs:164:5
|
LL | fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:156:1
--> $DIR/needless_lifetimes.rs:183:1
|
LL | fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: replace with `'_` in generic arguments such as here
--> $DIR/needless_lifetimes.rs:156:33
--> $DIR/needless_lifetimes.rs:183:33
|
LL | fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str {
| ^^
error: the following explicit lifetimes could be elided: 'b
--> $DIR/needless_lifetimes.rs:201:1
|
LL | fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: replace with `'_` in generic arguments such as here
--> $DIR/needless_lifetimes.rs:201:43
|
LL | fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {
| ^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:186:1
--> $DIR/needless_lifetimes.rs:209:1
|
LL | fn struct_with_lt4b<'a, 'b>(_foo: &'a Foo<'b>) -> &'b str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:224:1
|
LL | fn trait_obj_elided2<'a>(_arg: &'a dyn Drop) -> &'a str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:192:1
--> $DIR/needless_lifetimes.rs:230:1
|
LL | fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: replace with `'_` in generic arguments such as here
--> $DIR/needless_lifetimes.rs:192:37
--> $DIR/needless_lifetimes.rs:230:37
|
LL | fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str {
| ^^
error: the following explicit lifetimes could be elided: 'b
--> $DIR/needless_lifetimes.rs:248:1
|
LL | fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: replace with `'_` in generic arguments such as here
--> $DIR/needless_lifetimes.rs:248:47
|
LL | fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {
| ^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:211:1
--> $DIR/needless_lifetimes.rs:256:1
|
LL | fn alias_with_lt4b<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'b str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:260:1
|
LL | fn named_input_elided_output<'a>(_arg: &'a str) -> &str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:219:1
--> $DIR/needless_lifetimes.rs:268:1
|
LL | fn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:255:1
--> $DIR/needless_lifetimes.rs:304:1
|
LL | fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: replace with `'_` in generic arguments such as here
--> $DIR/needless_lifetimes.rs:304:47
|
LL | fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> {
| ^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:262:9
--> $DIR/needless_lifetimes.rs:311:9
|
LL | fn needless_lt<'a>(x: &'a u8) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:266:9
--> $DIR/needless_lifetimes.rs:315:9
|
LL | fn needless_lt<'a>(_x: &'a u8) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:279:9
--> $DIR/needless_lifetimes.rs:328:9
|
LL | fn baz<'a>(&'a self) -> impl Foo + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:311:5
--> $DIR/needless_lifetimes.rs:360:5
|
LL | fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:320:5
--> $DIR/needless_lifetimes.rs:369:5
|
LL | fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:332:5
--> $DIR/needless_lifetimes.rs:381:5
|
LL | fn where_clause_elidadable<'a, T>(i: &'a i32, f: T) -> &'a i32
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:347:5
--> $DIR/needless_lifetimes.rs:396:5
|
LL | fn pointer_fn_elidable<'a>(i: &'a i32, f: fn(&i32) -> &i32) -> &'a i32 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:360:5
--> $DIR/needless_lifetimes.rs:409:5
|
LL | fn nested_fn_pointer_3<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:363:5
--> $DIR/needless_lifetimes.rs:412:5
|
LL | fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:385:9
--> $DIR/needless_lifetimes.rs:434:9
|
LL | fn implicit<'a>(&'a self) -> &'a () {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:388:9
--> $DIR/needless_lifetimes.rs:437:9
|
LL | fn implicit_mut<'a>(&'a mut self) -> &'a () {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:399:9
--> $DIR/needless_lifetimes.rs:448:9
|
LL | fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a () {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:405:9
--> $DIR/needless_lifetimes.rs:454:9
|
LL | fn implicit<'a>(&'a self) -> &'a ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:406:9
--> $DIR/needless_lifetimes.rs:455:9
|
LL | fn implicit_provided<'a>(&'a self) -> &'a () {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:415:9
--> $DIR/needless_lifetimes.rs:464:9
|
LL | fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:416:9
--> $DIR/needless_lifetimes.rs:465:9
|
LL | fn lifetime_elsewhere_provided<'a>(self: Box<Self>, here: &'a ()) -> &'a () {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:425:5
--> $DIR/needless_lifetimes.rs:474:5
|
LL | fn foo<'a>(x: &'a u8, y: &'_ u8) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:427:5
--> $DIR/needless_lifetimes.rs:476:5
|
LL | fn bar<'a>(x: &'a u8, y: &'_ u8, z: &'_ u8) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 33 previous errors
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:483:5
|
LL | fn one_input<'a>(x: &'a u8) -> &'a u8 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:488:5
|
LL | fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 45 previous errors

View file

@ -1,4 +1,4 @@
#![allow(dead_code, clippy::borrow_as_ptr)]
#![allow(dead_code, clippy::borrow_as_ptr, clippy::needless_lifetimes)]
extern crate core;

View file

@ -3,6 +3,7 @@
#![deny(clippy::trivially_copy_pass_by_ref)]
#![allow(
clippy::disallowed_names,
clippy::needless_lifetimes,
clippy::redundant_field_names,
clippy::uninlined_format_args
)]

View file

@ -1,5 +1,5 @@
error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
--> $DIR/trivially_copy_pass_by_ref.rs:50:11
--> $DIR/trivially_copy_pass_by_ref.rs:51:11
|
LL | fn bad(x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `u32`
@ -11,103 +11,103 @@ LL | #![deny(clippy::trivially_copy_pass_by_ref)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
--> $DIR/trivially_copy_pass_by_ref.rs:50:20
--> $DIR/trivially_copy_pass_by_ref.rs:51:20
|
LL | fn bad(x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `Foo`
error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
--> $DIR/trivially_copy_pass_by_ref.rs:50:29
--> $DIR/trivially_copy_pass_by_ref.rs:51:29
|
LL | fn bad(x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `Baz`
error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
--> $DIR/trivially_copy_pass_by_ref.rs:57:12
--> $DIR/trivially_copy_pass_by_ref.rs:58:12
|
LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {}
| ^^^^^ help: consider passing by value instead: `self`
error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
--> $DIR/trivially_copy_pass_by_ref.rs:57:22
--> $DIR/trivially_copy_pass_by_ref.rs:58:22
|
LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `u32`
error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
--> $DIR/trivially_copy_pass_by_ref.rs:57:31
--> $DIR/trivially_copy_pass_by_ref.rs:58:31
|
LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `Foo`
error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
--> $DIR/trivially_copy_pass_by_ref.rs:57:40
--> $DIR/trivially_copy_pass_by_ref.rs:58:40
|
LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `Baz`
error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
--> $DIR/trivially_copy_pass_by_ref.rs:59:16
--> $DIR/trivially_copy_pass_by_ref.rs:60:16
|
LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `u32`
error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
--> $DIR/trivially_copy_pass_by_ref.rs:59:25
--> $DIR/trivially_copy_pass_by_ref.rs:60:25
|
LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `Foo`
error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
--> $DIR/trivially_copy_pass_by_ref.rs:59:34
--> $DIR/trivially_copy_pass_by_ref.rs:60:34
|
LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `Baz`
error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
--> $DIR/trivially_copy_pass_by_ref.rs:61:35
--> $DIR/trivially_copy_pass_by_ref.rs:62:35
|
LL | fn bad_issue7518(self, other: &Self) {}
| ^^^^^ help: consider passing by value instead: `Self`
error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
--> $DIR/trivially_copy_pass_by_ref.rs:73:16
--> $DIR/trivially_copy_pass_by_ref.rs:74:16
|
LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `u32`
error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
--> $DIR/trivially_copy_pass_by_ref.rs:73:25
--> $DIR/trivially_copy_pass_by_ref.rs:74:25
|
LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `Foo`
error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
--> $DIR/trivially_copy_pass_by_ref.rs:73:34
--> $DIR/trivially_copy_pass_by_ref.rs:74:34
|
LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `Baz`
error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
--> $DIR/trivially_copy_pass_by_ref.rs:77:34
--> $DIR/trivially_copy_pass_by_ref.rs:78:34
|
LL | fn trait_method(&self, _foo: &Foo);
| ^^^^ help: consider passing by value instead: `Foo`
error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
--> $DIR/trivially_copy_pass_by_ref.rs:109:21
--> $DIR/trivially_copy_pass_by_ref.rs:110:21
|
LL | fn foo_never(x: &i32) {
| ^^^^ help: consider passing by value instead: `i32`
error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
--> $DIR/trivially_copy_pass_by_ref.rs:114:15
--> $DIR/trivially_copy_pass_by_ref.rs:115:15
|
LL | fn foo(x: &i32) {
| ^^^^ help: consider passing by value instead: `i32`
error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
--> $DIR/trivially_copy_pass_by_ref.rs:141:37
--> $DIR/trivially_copy_pass_by_ref.rs:142:37
|
LL | fn _unrelated_lifetimes<'a, 'b>(_x: &'a u32, y: &'b u32) -> &'b u32 {
| ^^^^^^^ help: consider passing by value instead: `u32`