I don’t see why this should compile. The naive equivalent (adding lifetime parameters) would have me go pub fn new<'b>(lexer: &'a Lexer) -> LexerIter<'b>, which is a type error. Am I missing something, or what is this strange case?
This is a bit subtle, but, fn new(_: &Lexer) is not “elision” or at least not the same kind as that found in the return type.
Instead, missing lifetimes in argument types get substituted with anonymous (late-bound) lifetime parameters, so these are all equivalent:
fn foo(_: &i32) -> R {...}
fn foo<'a>(_: &'a i32) -> R {...}
fn foo<'b>(_: &'b i32) -> R {...}
The return type lifetime elision, however, looks for more or less (self is a bit special) one lifetime in the argument types, and uses that lifetime in all locations where a lifetime is missing.
That is, R above can have any number of lifetime parameters and they all get the same lifetime from the reference to i32.
Thanks for elaborating! I had completely missed that it could be only partway explicit in where a parameter is used. It allows us to write Rust that is extra confusing:
I wouldn’t say that’s particularly confusing. Since the lifetime needs to be bound to an input (unless explicitly 'static) there’s really only one lifetime it could be here.