Moved Variable Error

Hey!

I’m encountering an issue with the moved variable deps. I’ve tried several solutions, such as:

  • clone()
  • mut
  • borrow()
  • as_ref()
  • and more...

None of these seem to work for me.

Here’s the code snippet:

pub fn transfer(env: ExecuteEnv, to: String, amount: Uint128) -> Result<Response, ContractError> {
    let from_addr = env.info.sender.clone();
    let to_addr = env.deps.api.addr_validate(&to)?;

    let mut rsp = Response::new();

    let event = _transfer(
        env.deps,
        env.env,
        env.info,
        from_addr.clone(),
        to_addr.clone(),
        amount,
    );
    rsp = rsp.add_attribute("transferEvent", format!("{:?}", event));

    // Check if `to` is a contract and requires acceptance logic
    if let Ok(event_msgs) = do_transfer_acceptance_check(
        env.deps,
        from_addr.to_string(),
        to_addr.to_string(),
        amount,
    ) {
        for msg in event_msgs {
            rsp = rsp.add_message(msg);
        }
    }

    Ok(rsp)
}

Here’s the definition of ExecuteEnv<>:

pub struct ExecuteEnv<'a> {
    pub deps: DepsMut<'a>,
    pub env: Env,
    pub info: MessageInfo,
}

The issue occurs with env.deps. Any assistance with a solution would be greatly appreciated!

since DepsMut has a lifetime marker, I would assume it contains a mut reference inside, and mut references are linear types in rust. if you want to use it more than once, you must borrow it or (reborrow from it), clone() won't work.

I don't know which part of the code is your own, and which part is from third party dependencies. if you can change the _transfer() function, changing the parameter type to &mut DepsMut<'_> should fix it.

I'm using functions from this cw20 package with some additional lines on top. However, if I change the type to &mut DepsMut<'_>, the functions above no longer work.

I'm having trouble calling multiple functions with deps / modified deps.

since deps has a different type, you must also change every function you call with deps as arguments. in the screenshot, it's the execute_transfer() function.

I'm using the cw20 import, which includes some predefined functions that I'm currently utilizing. Overwriting a single function isn’t feasible because of the interface declarations; to modify just one, I would need to override all the execute_* functions. This would be a large task and time-consuming.

Is there an alternative solution to handle these copies?

if the API uses DepsMut<'_> in the type signature, then either:

a) the deps are meant to be used only once (because it's a linear type), or:
b) the API design is sub-optimal and should be improved.

BTW, can you show the definition of the DepsMut<'a> type? maybe there's more to it that I didn't think of.

I had to dig a bit, but it looks like DepsMut has a method called branch that works like a re-borrow. That may help.

2 Likes

Thank you, @nerditation, for your help! I resolved the issue by declaring env as mutable and then borrowing deps, as mentioned by @ogeon.

1 Like

Thanks, @ogeon! Borrowing worked after making env mutable.

1 Like