Hello friends. I've been working with the OXC library recently, and I'm facing an issue that I can't seem to solve.
The problem is that I declare a mutable variable and pass it to another function, and then I'm no longer able to use it afterwards.
pub fn extend_hook_object_to_ast<'a>(
file_path: &str,
allocator: &'a Allocator,
) -> Result<String, String> {
let mut program = source_to_ast(file_path, allocator)?;
if let Some(hooks_property) = find_hooks_property(&mut program) {
...
} else {
return Err("liveSocket not found in the AST".to_string());
}
let codegen = Codegen::new();
let generated_code = codegen.build(&program).code;
Ok(generated_code)
}
fn find_hooks_property<'a>(program: &'a mut Program<'a>) -> Option<&'a mut Expression<'a>>{}
As you can see, I've created program and passed it to the function find_hooks_property, but now I can't return it at the end of this function, i.e., in the following line:
let generated_code = codegen.build(&program).code;
And I'm getting the following error:
rustc: cannot borrow `program` as immutable because it is also borrowed as mutable
immutable borrow occurs here
Since I'm new to Rust, I checked if methods like clone or owned exist for program, but unfortunately, they don't (at least if I'm on the right track).
What do you suggest I do?
Thanks in advance.
Here's the link to the functions.
The whole project is at the link below, just a few files.
&'a mut Something<'a> is not a particularly useful construction because it always results in the locked-forever behaviour that you're seeing:
The <'a> type annotation indicates that Something<'a> is only valid within the region 'a, probably due to holding some kind of reference.
The 'a in &'a mut ... says that your borrow is exclusive for the entirety of the region 'a.
These two facts combined mean that you've exclusively borrowed the Something for the entire region in which it is valid and therefore can't use it anymore except through the mutable reference you've created.
This is an extremely unfortunate help message from the compiler, as it's suggesting a change that is pretty much guaranteed to cause more problems down the line.
error: lifetime may not live long enough
--> src/parser/ast.rs:227:5
|
226 | fn find_hooks_property<'b, 'a: 'b>(program: &'b mut Program<'a>) -> Option<&'b mut Expression<'a>> {
| -- -- lifetime `'a` defined here
| |
| lifetime `'b` defined here
227 | / program.body.iter_mut().find_map(move |node| {
228 | | let var_decl = match node {
229 | | Statement::VariableDeclaration(var_decl) => var_decl,
230 | | _ => return None,
... |
248 | | })
249 | | })
| |______^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
|
= help: consider adding the following bound: `'b: 'a`
= note: requirement occurs because of a mutable reference to `Expression<'_>`
= note: mutable references are invariant over their type parameter
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
You probably also need to fix the signatures of get_new_expression, get_object_expression, and get_property_by_key which have the same issue (and anywhere else that you use &'a mut ...<'a>)
(In addition, it's also possible that I've gotten the bounds backwards...)
error[E0502]: cannot borrow `program` as immutable because it is also borrowed as mutable
--> src/parser/ast.rs:219:40
|
177 | if let Some(hooks_property) = find_hooks_property(&mut program) {
| ------------ mutable borrow occurs here
...
219 | let generated_code = codegen.build(&program).code;
| ^^^^^^^^
| |
| immutable borrow occurs here
| mutable borrow later used here
For more information about this error, try `rustc --explain E0502`.
error: could not compile `mishka_parser_nif` (lib test) due to 1 previous error
I reverted the changes suggested in this post to the original code, which I linked to.
From this function
If you have time, please download the project and test it. It's not more than two or three files.
You’ve been incredibly kind to me; thank you so much. The changes you showed with the diff were very educational for me.
I’ve watched many courses and read plenty of content, but it seems I still have significant weaknesses.
Do you recommend any resources?
Thank you in advance
Yes, I recommend thoroughly reading through @quinedot's Learning Rust. It is one of the best "casual" sources I have come across that describes many common pitfalls with lifetimes.
The Reference and Nomicon are also excellent resources, but they are much too dense for casual reading.