Elimination of verbose lifetimes (with Clippy?)

I am not good at English. Sorry if there are any funny expressions.

I like short code!

Therefore, I also like to omit lifetime parameters and bounds as much as possible.

I had assumed that Clippy would point out all such points. However, as shown in the code example below, some of them are not.

I tried to find Clippy Lints to see if I could add more detection items. However, I could not find them, either because they were not there in first place, or because I could not find them.

Is there any other way but to manually check?

fn main() {
	fn1_verbose(&0);
	fn2_verbose(&0);
	fn2_not_verbose(&0);
}

// Clippy output warning `needless_lifetimes` 🙂
fn fn1_verbose<'a>(x: &'a i32) -> &'a i32 {
	x
}

// Clippy did not output warning here 😕
fn fn2_verbose<'a, T: 'a>(_: &'a T) {
	// nop.
}

// I expected clippy leads `fn2_verbose` like this fn ✨
fn fn2_not_verbose<T>(_: &T) {
	// nop.
}

I don't know if there's a clippy lint for it or not, but this change:

-fn fn2_verbose<'a, T: 'a>(_: &'a T) {
+fn fn2_verbose<T>(_: &T) {
 	// nop.
 }

is a breaking change.

2 Likes

Thanks for your reply.

First, about my embarrassing mistake.
Oh... I can't foolishly substitute because of that pattern....
I learned the lesson.

And about the Clippy lint item.
I'm satisfied to know that even the most knowledgeable people don't know about it.
Perhaps there is no such item.
I simply wanted to know what others do?

IMO you are approaching it the wrong direction.

don't write explicit lifetimes first then try to delete "the unnecessary". instead, always omit lifetimes (i.e. rely on the compiler to infer the elided lifetiems) whenever possible, and only use explicit lifetime annotation when the elided lifetimes don't work (i.e. when compiler complains).

3 Likes

Thanks for your advice.

Actually, I am trying to omit the lifetime from the beginning as much as possible. However, when I read other people's code, I often see things that have lifetimes that could be omitted (my team and I don't have much experience with Rust), and I was wondering if there is a way to find such things all at once.

My first question was poorly written. Sorry for the lack of clarity.

All the relevant lifetime lints that exist in Clippy so far look like they are warn-by-default to me. Even though they are also prone to false positives or other problems, judging by the "related issues"... So I think just running Clippy is as good as you can do, outside of human review.


Getting a feel for function lifetime elision and using it -- not naming lifetimes if you don't have to -- is great. It's an area where Rust got the ergonomics and semantics mostly right, in my opinion.

But I don't recommend making the presence of lifetimes completely invisible wherever possible. Here's an example of what I mean by that.

Even if it's a little uglier, being aware of where borrows are happening is important. Especially when you start running into borrow errors. The first thing I do when tackling someone else's borrow-checker question is to deny(elided_lifetimes_in_paths). It is common for the problem to involve some place they've made the lifetimes completely invisible.

2 Likes

Thanks again.

I did not know that the example_2a in the example allows for lifetime elision. Indeed, I can agree that this elision is not a good idea, even though my motto is "shorter code is better".

About deny(elided_lifetimes_in_paths). Wow! This is very cool hack. I'll try it next time I run into trouble.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.