I'm trying to implement a basic Lexer as a learning experience. I understand that returning a reference to the buffer with lifetime <'s> doesn't work because 's outlives the Lexer, but I'm not sure what to do about it.
pub struct Lexer<'s> {
src: Peekable<Chars<'s>>,
buf: String,
}
impl<'s> Iterator for Lexer<'s> {
type Item = Token<'s>;
fn next(&mut self) -> Option<Self::Item> {
self.buf.clear();
loop {
match self.src.next()? {
n if is_ident_start(&n) => {
self.src.next_if(is_ident_char).iter().collect_into(&mut self.buf);
return Some(kw_or_ident(&*self.buf)); // <-- Error occurs here
},
' ' => continue,
_ => {}
}
}
}
}
fn kw_or_ident<'t>(buf: &'t str) -> Token<'t> {
KEYWORDS
.get(buf)
.copied()
.map(|kw| Token::Keyword(kw))
.unwrap_or_else(|| Token::Literal(buf))
}
error: lifetime may not live long enough
--> src/lexer.rs:27:28
|
18 | impl<'s> Iterator for Lexer<'s> {
| -- lifetime `'s` defined here
...
21 | fn next(&mut self) -> Option<Self::Item> {
| - let's call the lifetime of this reference `'1`
...
27 | return Some(kw_or_ident(&*self.buf));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method was supposed to return data with lifetime `'s` but it is returning data with lifetime `'1`