Big_Bad_E
Big_Bad_E

Reputation: 847

Extend lifetime of struct to exceed that of another struct

I'm trying to make a lexer for HTML, which requires swapping between states. Because states have to store data, I decided to make each state a struct. The problem is dealing with the lifetime of said state, because it requires storing references to previous states.

Currently, I have the following system:

pub struct Lexer<'a> {
    input: Peekable<Chars<'a>>,
    state: Box<dyn LexerState>,
}

trait LexerState {
    fn next_token(&mut self, lexer: &mut Lexer) -> Token;
}

pub struct DataState {}

impl LexerState for DataState {
    fn next_token(&mut self, lexer: &mut Lexer) -> Token {
        lexer.state = Box::new(CharacterReferenceState { return_state: &lexer.state });
        lexer.state.next_token(lexer)
    }
}

pub struct CharacterReferenceState<'a> {
    return_state: &'a Box<dyn LexerState>,
}

impl<'a> LexerState for CharacterReferenceState<'a> {
    fn next_token(&mut self, lexer: &mut Lexer) -> Token {}
}

(for the sake of brevity, I've excluded irrelevant code)

This gives the error: "lexer has an anonymous lifetime '_ but it needs to satisfy a 'static lifetime requirement"

From what I understand, this means I need some guarantee that lexer is valid for the whole time LexerState is valid, because if lexer is invalid, then the state is invalid. From my research, it seems like 'static lifetime would fix this problem, but that raises a few concerns:

  1. Can I fix this issue without static/is there a better design pattern for this?
  2. Will the static lifetime variable be properly invalidated and freed after the parsing is complete?

Upvotes: 0

Views: 207

Answers (1)

Big_Bad_E
Big_Bad_E

Reputation: 847

As pointed out in the comments, the compiler error was a red herring and the actual problem was the self-referential reference. To fix this, I just transferred ownership of the Box instead.

Upvotes: 1

Related Questions