The basic idea of the code is to create a hierarchical struct Context
which contains some information of symbols, and a Context
will be provided to the lambda in a Statement
struct to get the final result. A child context can be derived from the parent if needed:
use anyhow::Result; // 1.0.40
use std::{collections::HashMap, rc::Rc};
struct Context<'a> {
parent: Option<&'a mut Context<'a>>,
symbols: HashMap<String, i64>,
}
impl<'a> Context<'a> {
fn new() -> Self {
Context {
parent: None,
symbols: HashMap::new(),
}
}
fn derive(&'a mut self) -> Self {
Context {
parent: Some(self),
symbols: HashMap::new(),
}
}
}
#[derive(Clone)]
struct Statement {
execute: Rc<dyn Fn(&mut Context) -> Result<()>>,
}
struct Node {
cond: Statement,
stmts: Vec<Statement>,
}
impl Node {
fn get(&self) -> Statement {
let cond = self.cond.clone();
let stmts = self.stmts.clone();
Statement {
execute: Rc::new(move |ctx| {
(cond.execute)(ctx)?;
let mut cctx = ctx.derive();
for stmt in stmts {
(stmt.execute)(&mut cctx)?;
}
Ok(())
}),
}
}
}
When I compile this code, I get the error:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/lib.rs:42:36
|
42 | let mut cctx = ctx.derive();
| ^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 40:30...
--> src/lib.rs:40:30
|
40 | execute: Rc::new(move |ctx| {
| ______________________________^
41 | | (cond.execute)(&mut ctx)?;
42 | | let mut cctx = ctx.derive();
43 | | for stmt in stmts {
... |
46 | | Ok(())
47 | | }),
| |_____________^
note: ...so that reference does not outlive borrowed content
--> src/lib.rs:42:32
|
42 | let mut cctx = ctx.derive();
| ^^^
note: but, the lifetime must be valid for the anonymous lifetime #2 defined on the body at 40:30...
--> src/lib.rs:40:30
|
40 | execute: Rc::new(move |ctx| {
| ______________________________^
41 | | (cond.execute)(&mut ctx)?;
42 | | let mut cctx = ctx.derive();
43 | | for stmt in stmts {
... |
46 | | Ok(())
47 | | }),
| |_____________^
note: ...so that the types are compatible
--> src/lib.rs:42:36
|
42 | let mut cctx = ctx.derive();
| ^^^^^^
= note: expected `&mut Context<'_>`
found `&mut Context<'_>`
I find this error message is useless. How can I fix this error?