1. The Problem
Consdier the following struct and constructor:
#[derive(Clone, Debug)] pub struct ApiServer { port: u16, // mutex is not clonable, we wrap by Arc cache: Arc<Mutex<HashMap<String, BlockChain>>>, }
impl ApiServer { pub fn new(port: u16) -> Self { let api_server = ApiServer { port, cache: Arc::new(Mutex::new(HashMap::<String, BlockChain>::new())), }; let wallet_miner = Wallet::new(); let unlocked_cache = &mut api_server.cache.lock().unwrap(); unlocked_cache.insert( "blockchain".to_string(), BlockChain::new(wallet_miner.get_address()), ); api_server } }
now our compiler will complain:
2. What Causes the Problem?
2.1. Rules for Reference and Ownership
Rust's borrow checker follows simple, strict rules:
- 
"If you have a reference to something, you can't move that something"
 - 
"References must always point to valid data".
It doesn't matter that the reference dies immediately - the rule is applied at compile time based on code structure, not runtime execution.
 
2.2. Which rule have we broken?
Let's start with the line of borrowing:
let unlocked_cache = &mut api_server.cache.lock().unwrap(); unlocked_cache.insert( "blockchain".to_string(), BlockChain::new(wallet_miner.get_address()), ); api_server }
- 
api_serveris returned and its data ownership is potentially moved to another variable that receives the return - 
unlocked_cachereferences toapi_server.cache, however, asapi_serveris moved, the accessapi_server.cachecrashed - 
No matter
unlocked_cachedies immediately outside of the scope ofnew()or not, we are referencing and moving a data at the same time. 
3. Solution 1
We don't create intermediate reference, we simply mutate the data that the MutexGuard referencing to:
impl ApiServer { pub fn new(port: u16) -> Self { let api_server = ApiServer { port, cache: Arc::new(Mutex::new(HashMap::<String, BlockChain>::new())), }; let wallet_miner = Wallet::new(); api_server.cache.lock().unwrap().insert( "blockchain".to_string(), BlockChain::new(wallet_miner.get_address()), ); api_server } }
4. Solution 2
We avoid moving and referencing to the same variable in the same scope:
impl ApiServer { pub fn new(port: u16) -> Self { let api_server = ApiServer { port, cache: Arc::new(Mutex::new(HashMap::<String, BlockChain>::new())), }; let wallet_miner = Wallet::new(); { let unlocked_cache = &mut api_server.cache.lock().unwrap(); unlocked_cache.insert( "blockchain".to_string(), BlockChain::new(wallet_miner.get_address()), ); } api_server } }














