Description
#![deny(single_use_lifetimes)]
pub enum Data<'a> {
Borrowed(&'a str),
Owned(String),
}
impl<'a> Data<'a> {
pub fn get<'b: 'a>(&'b self) -> &'a str {
match &self {
Self::Borrowed(val) => val,
Self::Owned(val) => &val,
}
}
}
This code, as expected, triggers the lint. This is the compiler output:
error: lifetime parameter `'b` only used once
--> src/lib.rs:9:16
|
9 | pub fn get<'b: 'a>(&'b self) -> &'a str {
| ^^ -- ...is used only here
| |
| this lifetime...
|
note: the lint level is defined here
--> src/lib.rs:1:9
|
1 | #![deny(single_use_lifetimes)]
| ^^^^^^^^^^^^^^^^^^^^
help: elide the single-use lifetime
|
9 - pub fn get<'b: 'a>(&'b self) -> &'a str {
9 + pub fn get(&self) -> &'a str {
|
Applying the suggested change, we then get a lifetime error.
error: lifetime may not live long enough
--> src/lib.rs:10:9
|
8 | impl<'a> Data<'a> {
| -- lifetime `'a` defined here
9 | pub fn get(&self) -> &'a str {
| - let's call the lifetime of this reference `'1`
10 | / match &self {
11 | | Self::Borrowed(val) => val,
12 | | Self::Owned(val) => &val,
13 | | }
| |_________^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
In this specific instance, &'a str
must also be changed to &str
. That'll then trigger the lint on impl<'a> Data<'a>
, with no ensuing issues.
I have not checked this, but I my suspicion is any place where a lifetime bound is also present in the return type (or possibly even a parameter) will result in a similar failure to compile the suggested code. Figuring out which lifetimes to suggest removal of in other parts of the function signature probably isn't straightforward.
This example is not theoretical, unfortunately. I ran into this in real-world code and it caused me quite a bit of time to figure out. The example is the minimal reproduction of the bad suggestion.