Hi there,
I'm writing an interpreter for an in house tool and everything went very smoothly until I decided to add an "include another file" feature to it.
I have this function:
fn parse_script<'a>(filename: &str, content: &'a str) -> Result<Box<Script<'a>>>
which calls other parse_* function according to pest
parser and I have this particular one:
fn parse_use<'a>(pair: Pair<'a, Rule>, ast: &mut Script<'a>, span: &Span) -> Result<()>
inside, I'm reading a file into a String, and calling parse_script
on the content of it.
Of course, it's not allowed because this new String will be dropped at the end of parse_use
. I know that so I tried to keep this String alive alongside the new Box<Script<'a>>
:
fn parse_use<'a>(pair: Pair<'a, Rule>, ast: &mut Script<'a>, span: &Span) -> Result<()> {
// ... skip
let mut sub_script = SubScript {
script: None,
content: std::fs::read_to_string(&path)?,
};
let script = parse_script(&file_name, &sub_script.content)?;
sub_script.script = Some(script);
ast.sub_scripts.insert(sub_script.id.clone(), sub_script);
}
but it seems this is not sufficient for Rust to garantee safety here:
error[E0597]: `sub_script.content` does not live long enough
--> src\parser.rs:69:43
|
52 | fn parse_use<'a>(pair: Pair<'a, Rule>, ast: &mut Script<'a>, span: &Span) -> Result<()> {
| -- lifetime `'a` defined here
...
69 | let script = parse_script(&file_name, &sub_script.content)?;
| ^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
...
78 | ast.sub_scripts.insert(sub_script.id.clone(), sub_script);
| --------------------------------------------------------- argument requires that `sub_script.content` is borrowed for `'a`
79 | Ok(())
80 | }
| - `sub_script.content` dropped here while still borrowed
error[E0505]: cannot move out of `sub_script` because it is borrowed
--> src\parser.rs:78:51
|
69 | let script = parse_script(&file_name, &sub_script.content)?;
| ------------------- borrow of `sub_script.content`
occurs here
...
78 | ast.sub_scripts.insert(sub_script.id.clone(), sub_script);
| ------ ^^^^^^^^^^ move out of `sub_script` occurs
here
| |
| borrow later used by call
I'm pretty sure this is feasible in Rust, I just don't know how… yet?
Thanks for reading!
EDIT:
forgot to give the def of SubScript
:
pub struct SubScript<'a> {
pub script: Option<Box<Script<'a>>>,
pub content: String,
}