Lint against lifetimes not bind to input arguments


#1

After reading the post Capstone_rs unsafety adventure and a little digging into the issue the author have, I realize he didn’t addessed a common bug in the first place and get confused later on.

The issue can be seen on the following commit:

pub fn disasm_all<'a>(&mut self, code: &[u8], addr: u64) -> CsResult<Instructions<'a>> {
        self.disasm(code, addr, 0)
    }

I can see that if 'a didn’t introduced, the above would not compile as the output lifetime cannot be derived: both self and code have elided lifetime. So the author introduced a generic lifetime.

However in his case the lifetime should tie to self, as discussed in his post. Unfortunately Rust didn’t give even a lint in this case, so he get confused and made a wrong decision to add lifetime to Self and complicated the API.

So I tested in playground

use std::marker::PhantomData;
struct L<'a>{
    v: PhantomData<&'a ()>
}
fn t<'a>(_v: &(), _u:&()) -> L<'a>
{
    L{v:PhantomData}
}

fn main() {
    t(&(),&());
}

No lints, but not likely to be useful to write similar things.

Shall we add a lint against this case? A message like

Note: the generic lifetime `'a` didn't tie to any input arguments, this is usually not desired.

would be helpful in this case.


#2

FYI: Unbound lifetimes from Nomicon

As Nomicon strongly against using unbounded lifetimes unless intentionally, we have very strong reason to lint against it.