Repository: MystenLabs/sui
File: external-crates/move/crates/move-vm-runtime/src/execution/values/values_impl.rs (Rust)

Code before:
            | Value::Struct(_)
            | Value::Variant(_)
            | Value::Reference(_) => Err(partial_vm_error!(
                UNKNOWN_INVARIANT_VIOLATION_ERROR,
                "{:?} is not a vector",
                self
            )),
        }
    }
}

impl<T: Debug> MemBox<T> {
    pub fn new(t: T) -> MemBox<T> {
        Self(std::rc::Rc::new(std::cell::RefCell::new(t)))
    }

    pub fn borrow(&self) -> std::cell::Ref<'_, T> {
        self.0.borrow()
    }

    pub fn try_borrow_mut(&self) -> PartialVMResult<std::cell::RefMut<'_, T>> {
        self.0.try_borrow_mut().map_err(|_| {
            partial_vm_error!(
                UNKNOWN_INVARIANT_VIOLATION_ERROR,
                "failed to borrow mutable reference due to previous borrow"
            )
        })
    }

    pub fn replace(&mut self, t: T) -> T {
        self.0.replace(t)
    }

    fn ptr_clone(&self) -> Self {
        MemBox(std::rc::Rc::clone(&self.0))
    }

    #[cfg(test)]
    #[allow(non_snake_case)]
    /// This is strictly for testing cycle dropping.
    /// If you ever mark this not #[cfg(test)] you will have your VM implementor card revoked.
    pub(crate) fn UNSAFE_ptr_clone(&self) -> Self {
        MemBox(std::rc::Rc::clone(&self.0))
    }
}

impl MemBox<Value> {
    pub fn as_ref_value(&self) -> Value {
        Value::Reference(Reference::Value(self.ptr_clone()))
    }


Review comment (bug):
nit: should this take the error and include that in the error message it creates here? something like 
```suggestion
        self.0.try_borrow_mut().map_err(|e| {
            partial_vm_error!(
                UNKNOWN_INVARIANT_VIOLATION_ERROR,
                "failed to borrow mutable reference due to previous borrow: {:?}",
                e
            )
```

Code after:
            | Value::Struct(_)
            | Value::Variant(_)
            | Value::Reference(_) => Err(partial_vm_error!(
                UNKNOWN_INVARIANT_VIOLATION_ERROR,
                "{:?} is not a vector",
                self
            )),
        }
    }
}

impl<T: Debug> MemBox<T> {
    pub fn new(t: T) -> MemBox<T> {
        Self(std::rc::Rc::new(std::cell::RefCell::new(t)))
    }

    pub fn borrow(&self) -> std::cell::Ref<'_, T> {
        self.0.borrow()
    }

    pub fn try_borrow_mut(&self) -> PartialVMResult<std::cell::RefMut<'_, T>> {
        self.0.try_borrow_mut().map_err(|err| {
            partial_vm_error!(
                UNKNOWN_INVARIANT_VIOLATION_ERROR,
                "failed to borrow mutable reference due to previous borrow {:?}",
                err
            )
        })
    }

    pub fn replace(&mut self, t: T) -> T {
        self.0.replace(t)
    }

    fn ptr_clone(&self) -> Self {
        MemBox(std::rc::Rc::clone(&self.0))
    }

    #[cfg(test)]
    #[allow(non_snake_case)]
    /// This is strictly for testing cycle dropping.
    /// If you ever mark this not #[cfg(test)] you will have your VM implementor card revoked.
    pub(crate) fn UNSAFE_ptr_clone(&self) -> Self {
        MemBox(std::rc::Rc::clone(&self.0))
    }
}

impl MemBox<Value> {
    pub fn as_ref_value(&self) -> Value {
        Value::Reference(Reference::Value(self.ptr_clone()))
    }