Cannot move out of borrowed content take 2

Thanks again :smiley: , here is the updated code. Now (of course) I get a new error "borrowed value does not live long enough". I am not completely sure I understand why it happens. And how to fix it.

//#![feature(nll)]

use std::collections::HashMap;
use std::thread;
use std::time::Duration;

fn main() {
	let mut clients: HashMap<String, &mut Clients> = HashMap::new();

	thread::spawn(move || loop {
		let session_id = "12345".to_string();

		thread::sleep(Duration::from_millis(1000));
		//receives new events from event loop
		//forward each event to specific module
		module_executor(&mut clients, session_id);
	});
}

pub struct Data<'a, 'b: 'a> {
	pub clients: &'a mut HashMap<String, &'b mut Clients>,
	pub session_id: &'a str,
}

pub struct SystemClient {
	pub session_id: String,
	pub ip: String,
}

impl SystemClient {
	pub fn stop(&mut self) {}
	pub fn start(&mut self) {}

	pub fn new(session_id: String, ip: String) -> Self {
		SystemClient {
			session_id,
			ip,
		}
	}
}

pub struct Clients {
	pub system: Option<SystemClient>,
}

impl Clients {
	pub fn new() -> Self {
		Clients {
			system: None,
		}
	}

	pub fn upgrade_system(&mut self, new_client: SystemClient) {
		if self.system.is_none() {
			self.system = Some(new_client);
			self.system.as_mut().unwrap().start();
		}
	}

	pub fn downgrade_system(&mut self) {
		if let Some(mut s) = self.system.take() {
			s.stop();
		}
	}
}

fn module_executor(clients: &mut HashMap<String, &mut Clients>, session_id: String) {
	//define a handy data struct, makes function signatures easier to read. any function "f" accepts Data
	let call_data = Data { clients, session_id: &session_id };
	//choose between different functions and call them (in this example only f exists)
	f(call_data);
}

fn f(call_data: Data)
{
	let clients;
	if !call_data.clients.contains_key(call_data.session_id) {
		clients = Clients::new();
		call_data.clients.insert(call_data.session_id.to_string(), &mut clients);
	}

	//get a client by session id
	let my_clients = &mut call_data.clients.get_mut(call_data.session_id).unwrap();

	//1st change some value
	{
		let system = &mut my_clients.system.as_mut().unwrap();
		system.ip = "123".to_string();
	}

	//then downgrade
	my_clients.downgrade_system();

	//and upgrade
	let system_client = SystemClient::new(
		call_data.session_id.to_string(),
		"67890".to_string(),
	);

	my_clients.upgrade_system(system_client);
}

Here's the complete output.

error[E0597]: `clients` does not live long enough                        ] 0/1: testt                                                                                              
   --> src/main.rs:79:67
    |
79  |         call_data.clients.insert(call_data.session_id.to_string(), &mut clients);
    |                                                                         ^^^^^^^ borrowed value does not live long enough
...
101 | }
    | - borrowed value only lives until here
    |
note: borrowed value must be valid for the anonymous lifetime #2 defined on the function body at 74:1...
   --> src/main.rs:74:1
    |
74  | / fn f(call_data: Data)
75  | | {
76  | |     let clients;
77  | |     if !call_data.clients.contains_key(call_data.session_id) {
...   |
100 | |     my_clients.upgrade_system(system_client);
101 | | }
    | |_^

Thanks for any suggestions!