[HELP]: Borrow checking problem with v8

I've encountered two problems with the borrow check in v8, how do I fix it, thanks for anyone's reply

https://www.rustexplorer.com/b/uii7ha

[1]. cannot borrow *isolate as immutable because it is also borrowed as mutable immutable borrow occurs here

[2]. no field modules on type &mut Rc<RefCell<ModuleMap>> unknown field

Please post code as text. Images are useless to blind people (they don't show up in a screen reader) and are impossible to copy-paste for reproducing the issue.

4 Likes

Ok, but the code is a bit long, thanks

use futures::Future;
use std::borrow::BorrowMut;
use std::cell::RefCell;
use std::collections::HashMap;
use std::path::PathBuf;
use std::pin::Pin;
use std::rc::Rc;
use std::task::Poll;
use tokio::io::Result;
use v8::{self, Isolate};
type AsyncFunction = Pin<Box<dyn Future<Output = Poll<i32>>>>;

pub struct ModuleInfo {
    pub filename: PathBuf,
}

pub struct ModuleMap {
    pub modules: HashMap<u32, ModuleInfo>,
}

pub struct RuntimeState {
    pub global_context: Option<v8::Global<v8::Context>>,
}

pub struct Runtime {
    pub isolate: v8::OwnedIsolate,
}

impl Runtime {
    fn state(isolate: &Isolate) -> Rc<RefCell<RuntimeState>> {
        let state_ptr = isolate.get_data(0);
        let state_rc = unsafe { Rc::from_raw(state_ptr as *const RefCell<RuntimeState>) };
        let state = state_rc.clone();
        Rc::into_raw(state_rc);
        state
    }

    fn module_map(isolate: &Isolate) -> Rc<RefCell<ModuleMap>> {
        let state_ptr = isolate.get_data(1);
        let state_rc = unsafe { Rc::from_raw(state_ptr as *const RefCell<ModuleMap>) };
        let state = state_rc.clone();
        Rc::into_raw(state_rc);
        state
    }

    pub async fn run(&mut self, entry: &PathBuf) -> Result<()> {
        let isolate = self.isolate.as_mut();
        let state = Self::state(isolate);

        let context = state.borrow().global_context.clone().unwrap();
        let scope = &mut v8::HandleScope::with_context(isolate, context);

        let module_map = Self::module_map(isolate);
       //                                 ^^^^^^^ -- cannot borrow `*isolate` as immutable because it is also borrowed as mutable immutable borrow occurs here
        Ok(())
    }

    pub async fn load(&mut self, filename: &PathBuf, source: Option<String>) -> Result<()> {
        let isolate = self.isolate.as_mut();
        let module_map = Self::module_map(isolate); 
       
        let module_map = module_map.borrow_mut();
        module_map.modules.push(
       //          ^^^^^^^^ -- no field `modules` on type `&mut std::rc::Rc<RefCell<ModuleMap>>` unknown field
           1,
            ModuleInfo {
                filename: filename.to_path_buf(),
                // source_map: None,
            },
        );
        Ok(())
    }
}

For the second error:

Everything implements std::borrow::BorrowMut, and its method is called borrow_mut. For that reason you pretty much never want it in scope, because it interferes with method resolution finding the borrow_mut method on RefCell, say.

So remove this:

-use std::borrow::BorrowMut;

Also, you don't push into a HashMap, you insert.

-        let module_map = module_map.borrow_mut();
-        module_map.modules.push(
+        let mut module_map = module_map.borrow_mut();
+        module_map.modules.insert(
2 Likes

The second problem can be solved, thank you. :100:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.