When we have some complex lifetimes problem, it's usually a good idea to make every lifetime explicit; the compiler can help you with elided_lifetimes_in_paths
lint. Let's apply it to your current code:
error: hidden lifetime parameters in types are deprecated
--> src/lib.rs:16:23
|
16 | fn parse_ident(i: CharIndices) -> (Self, CharIndices) {
| ^^^^^^^^^^^ expected lifetime parameter
|
note: the lint level is defined here
--> src/lib.rs:1:9
|
1 | #![deny(elided_lifetimes_in_paths)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
help: indicate the anonymous lifetime
|
16 | fn parse_ident(i: CharIndices<'_>) -> (Self, CharIndices) {
| ++++
error: hidden lifetime parameters in types are deprecated
--> src/lib.rs:16:46
|
16 | fn parse_ident(i: CharIndices) -> (Self, CharIndices) {
| ^^^^^^^^^^^ expected lifetime parameter
|
help: indicate the anonymous lifetime
|
16 | fn parse_ident(i: CharIndices) -> (Self, CharIndices<'_>) {
| ++++
Then, now that every lifetime is here (even if it's inferred), let's apply the lifetime elision rules and give each of them a name (updated playground):
impl<'token> Token<'token> {
fn parse_ident<'char_indices>(i: CharIndices<'char_indices>) -> (Self, CharIndices<'char_indices>) {
// snip
}
}
And finally, replace Self
with the exact type it stands for:
impl<'token> Token<'token> {
fn parse_ident<'char_indices>(i: CharIndices<'char_indices>) -> (Token<'token>, CharIndices<'char_indices>) {
// snip
}
}
Now the compiler can show you the problem more cleanly:
error: lifetime may not live long enough
--> src/lib.rs:15:9
|
13 | impl<'token> Token<'token> {
| ------ lifetime `'token` defined here
14 | fn parse_ident<'char_indices>(i: CharIndices<'char_indices>) -> (Token<'token>, CharIndices<'char_indices>) {
| ------------- lifetime `'char_indices` defined here
15 | / (
16 | | Token {
17 | | kind: TokenKind::Ident(i.clone().as_str()),
18 | | },
19 | | i,
20 | | )
| |_________^ associated function was supposed to return data with lifetime `'token` but it is returning data with lifetime `'char_indices`
|
= help: consider adding the following bound: `'char_indices: 'token`
That is, lifetimes of the token and of the CharIndices
iterator are independent in the signature, but the implementation requires them to be dependent - since CharIndices
borrows from its input, and Token
consumes this borrow, its lifetime must not be longer then the input's scope.
On the other hand, if you replace Self
with Token
and do the same thing, you arrive to another signature:
impl<'token> Token<'token> {
fn parse_ident<'char_indices>(i: CharIndices<'char_indices>) -> (Token<'char_indices>, CharIndices<'char_indices>) {
// snip
}
}
Which is exactly what I described above: the borrow in Token
is the same as the borrow in CharIndices
; but it's probably not what you want (@kpreid beat me to that, so I just refer to what is already said).
Could you share the reproduction case? When I simply drop the pub
in your code on playground, the error is exactly the same as before.