I keep getting problems with lifetimes when I use a trait, but not when I directly use a type that implements the trait.
I have recreated the problem in a few lines of code, with the inferred types shown.
struct Token<'src> {
slice: &'src str,
}
fn lex<'src>(source: &'src str) -> Vec<Token<'src>> {
vec![]
}
struct Parser<'a, 'src> {
tokens: &'a [Token<'src>],
}
trait Parse<'a, 'src> {
fn parse(parser: &mut Parser<'a, 'src>) -> Self;
}
struct Node<'src> {
slice: &'src str,
}
impl<'a, 'src> Parse<'a, 'src> for Node<'src> {
fn parse(parser: &mut Parser<'a, 'src>) -> Self {
Self { slice: parser.tokens[0].slice }
}
}
fn test<'src, P>(source: &'src str)
where
P: Parse<'src, 'src>,
{
let tokens: Vec<Token<'_>> = lex(source); // Inferred type
// tokens does not live long enough
// borrowed value does not live long enough
let mut parser: Parser<'_, '_> = Parser { tokens: &tokens }; // Inferred type
let _ = P::parse(&mut parser);
}
When I create Parser in test, I get an error saying that tokens does not live long enough, though that error doesn't occur when I don't pass the parser through Parse::parse.
fn test<'src>(source: &'src str) {
let tokens: Vec<Token<'_>> = lex(source); // Inferred type
let mut parser: Parser<'_, '_> = Parser { tokens: &tokens }; // Inferred type
let _ = Node::parse(&mut parser);
}
But when I directly use a type implementing the trait, shown in the codeblock above, I don't get the issue anymore.
I'm guessing it's the compiler not being able to know the lifetimes of the type implementing Parse, though I wasn't able to figure out how to make the compiler see them.
How would I get the tokens from lex, and pass it into P::parse, while having tokens live long enough for it?