Hi,
I'm porting Chapter 17 from Crafting Interpreters. The Pratt Parser uses a table of function pointers. So I have
type ParseFn = fn(&mut Compiler) -> ();
struct ParseRule {
prefix: Option<ParseFn>,
infix: Option<ParseFn>,
precedence: Precedence,
}
pub struct Compiler<'a> {
scanner: Scanner<'a>,
...,
parse_rules: HashMap<TokenType, ParseRule>,
}
impl<'a> Compiler<'a> {
pub fn new() -> Self {
let parse_rules: HashMap<TokenType, ParseRule> = {
let mut m: HashMap<TokenType, ParseRule> = HashMap::new();
m.insert(
TokenType::LeftParen,
ParseRule::new(Some(Compiler::grouping), None, Precedence::None),
);
m
};
Compiler {
...,
parse_rules: parse_rules,
}
}
fn grouping(&mut self) { ... }
}
I plan to use it as follows
let rule = get_rule(toke_type);
rule.infix(&mut self);
However, the compiler complains with
error[E0308]: mismatched types
--> bytecode/src/compiler.rs:94:37
|
94 | ParseRule::new(Some(Compiler::grouping), None, Precedence::None),
| ^^^^^^^^^^^^^^^^^^ expected concrete lifetime, found bound lifetime parameter
|
= note: expected type `for<'r, 's> fn(&'r mut compiler::Compiler<'s>)`
found type `for<'r> fn(&'r mut compiler::Compiler<'_>) {compiler::Compiler::<'_>::grouping}`
Here is my pull request.
What is the difference between a concrete and a bound lifetime? How can I define ParseFn
so that it works?
Thanks for your help!