I am new to Rust and I am trying to create combinator parser in it. Here is the code:
enum Parser<T: Copy + Eq> {
Ok,
Eof,
Satisfy { predicate: Box<dyn Fn(&T) -> bool> },
Element { elem : T }
}
impl<T: Copy + Eq> Parser<T> {
fn parse<'a, P>(&self, input: &'a [T]) -> Option<(&'a [T], P)>
where
P: Default,
T: Into<P>
{
match self {
Parser::Ok => Some((input, P::default())),
Parser::Eof => match input {
[] => None,
_ => Some((input, P::default())),
},
Parser::Satisfy { predicate } => match input {
[] => None,
[x, rest @ ..] => {
if predicate(x) {
Some((rest, T::into(*x)))
} else {
None
}
}
},
Parser::Element { elem } => {
let to_match = *elem;
Parser::Satisfy { predicate: Box::new(move|x| *x == to_match) }.parse(input)
}
}
}
}
Parser::Ok, Parser::Eof and Parser::Satisfy are working fine but I struggled with realization of Parser::Element (which must much only exact element). I want to realize method parse for it with creation of Parser::Satisfy with predicate of eq between argument x and given elem. But I run into this error:
error[E0310]: the parameter type `T` may not live long enough
--> src/lib.rs:32:46
|
32 | Parser::Satisfy { predicate: Box::new(move|x| *x == to_match) }.parse(input)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
8 | impl<T: Copy + Eq + 'static> Parser<T> {
| +++++++++
I feel there is some problem with lifetimes but I do not know how to fix it.
dyn Traitcontains things. These things may have lifetimes. Therefore,dyn Traitalso has a lifetime.This lifetime, like functions' lifetimes, can be elided. The full rules are somewhat complicated, but when in an ADT, the lifetime is assumed to be
'static. You can specify another lifetime withdyn Trait + 'lifetime.Thus, the
Box<dyn Fn(&T) -> bool>in your enum is actuallyBox<dyn Fn(&T) -> bool + 'static>.But the problem is that the function you assign into it captures
to_match, of typeT. And typeTmay contain a non-'staticlifetime. For example, it may contain&'non_static str. This is the error.This has two possible solutions.
Either accept that and require
Tto be'static:Or allow non-
'staticlifetime for the function: