When not to name lifetimes

Sometimes newcomers try to solve borrow check errors by making things more generic, which often involves adding lifetimes and naming previously-elided lifetimes:

#![allow(unused)]
fn main() {
struct S; impl S {
fn quz<'a: 'b, 'b>(&'a mut self) -> &'b str { todo!() }
}
}

But this doesn't actually permit more lifetimes than this:

#![allow(unused)]
fn main() {
struct S; impl S {
fn quz<'b>(&'b mut self) -> &'b str { todo!() }
}
}

Because in the first example, &'a mut self can coerce to &'b mut self. And, in fact, you want it to -- because you generally don't want to exclusively borrow self any longer than necessary.

And at this point you can instead utilize lifetime elision and stick with:

#![allow(unused)]
fn main() {
struct S; impl S {
fn quz(&mut self) -> &str { todo!() }
}
}

As covariance and function lifetime elision become more intuitive, you'll build a feel for when it's pointless to name lifetimes. Adding superfluous lifetimes like in the first example tends to make understanding borrow errors harder, not easier.