I'm experimenting with Rust's Arc<Mutex>, trying to use it with a struct that is not in the default examples, but rather a custom one that is lazily initialized:
use std::sync::{Arc, Mutex};
#[macro_use]
extern crate lazy_static; // lazy_static = "1.2.0"
pub struct FooBar {}
lazy_static! {
    static ref FOO_BAR: Arc<Mutex<Option<FooBar>>> = Arc::new(Mutex::new(None));
}
pub fn unpack_foo_bar() {
    let foo_bar_arc = Arc::clone(&FOO_BAR);
    let foo_bar_mutex_result = foo_bar_arc.lock();
    let foo_bar_mutex = foo_bar_mutex_result.unwrap();
    let foo_bar = foo_bar_mutex.unwrap();
    // do something
}
The static FOO_BAR variable is later initialized by replacing the content of the option.
The code above won't compile:
error[E0507]: cannot move out of borrowed content
  --> src/lib.rs:15:19
   |
15 |     let foo_bar = foo_bar_mutex.unwrap();
   |                   ^^^^^^^^^^^^^ cannot move out of borrowed content
It would if FooBar were replaced with e. g. u32. The code also doesn't compile with String, but that type has built-in methods for cloning, which my type may not necessarily have. 
Short of using foo_bar_mutex.as_ref().unwrap(), what other options do I have, particularly if I'd like to abstract the extraction of the FooBar instance into a method, like this:
pub fn unpack_foo_bar() -> Option<FooBar> {
    let foo_bar_arc = Arc::clone(&FOO_BAR);
    let foo_bar_mutex_result = foo_bar_arc.lock();
    let foo_bar_mutex = foo_bar_mutex_result.unwrap();
    let foo_bar_option = *foo_bar_mutex;
    foo_bar_option
}
In this case, the compiler throws almost the same error, which is
error[E0507]: cannot move out of borrowed content
  --> src/main.rs:34:26
   |
11 |     let foo_bar_option = *foo_bar_mutex;
   |                          ^^^^^^^^^^^^^^
   |                          |
   |                          cannot move out of borrowed content
   |                          help: consider using a reference instead: `&*foo_bar_mutex`
I have a sense that this would be much simpler if FooBar were easily cloned, but in the real world scenario I'm basing this example on FooBar has a field that is an instance of a third party library object that does not derive the Clone trait.
Using Option::take would only make the contained variable usable once. I'm not trying to take ownership of the FooBar instance. I don't care if it's owned as long as I can call its methods. Returning a reference would be great, but when doing this, the compiler complains:
pub fn unpack_foo_bar() -> &Option<FooBar> {
    let foo_bar_arc = Arc::clone(&FOO_BAR);
    let foo_bar_mutex_result = foo_bar_arc.lock();
    let foo_bar_mutex = foo_bar_mutex_result.unwrap();
    let foo_bar_option = foo_bar_mutex.as_ref();
    foo_bar_option
}
Compiler's response:
error[E0106]: missing lifetime specifier
  --> src/main.rs:30:28
   |
 7 | pub fn unpack_foo_bar() -> &Option<FooBar> {
   |                            ^ help: consider giving it a 'static lifetime: `&'static`
   |
   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
Experimenting with &*foo_bar_mutex and adding 'static to the return type each opens up subsequent cans of compiler errors.
I have also tried experimenting with to_owned() on the FooBar reference and stumbled upon the owning_ref crate, but alas, haven't figured out how to make returning a reference work.
Final Update
Given that it appears impossible to pass on the reference to the Option<FooBar> to an external function caller, I decided to avoid this problem altogether by allowing passing in the methods relying on the FooBar instance as a closure:
pub fn unpack_foo_bar(use_foo_bar: fn(&FooBar)) {
    let foo_bar_arc = Arc::clone(&FOO_BAR);
    let foo_bar_mutex_result = foo_bar_arc.lock();
    let foo_bar_mutex = foo_bar_mutex_result.unwrap();
    let foo_bar_reference = foo_bar_mutex.as_ref().unwrap();
    // pass in the closure that needs the foo bar instance
    use_foo_bar(foo_bar_reference);
}
 
    