Considering the following 2 functions that are very similar:
pub fn locked_fusion_proto<'a>() -> Result<MutexGuard<'a, (Box<(dyn Fusion + 'static)>, bool)>>
{
let c = Self::existing().unwrap();
let mx = c.fusion.as_ref().unwrap();
let lock = mx.lock()?;
Ok(lock)
}
pub fn locked_fusion_proto2<'a>() -> Result<&'a mut (Box<(dyn Fusion + 'static)>, bool)> {
let c = Self::existing().unwrap();
let mx = c.fusion.as_ref().unwrap();
let lock = mx.lock()?;
let lock_as_ref: &mut (Box<dyn Fusion>, bool) = &mut *mx.lock()?;
Ok(lock_as_ref)
}
the first one compiles successfully despite that lock is a local variable, the type & livetime of lock was automatically figured out by the compiler to be 'a.
the second one fails with the following message:
error[E0515]: cannot return value referencing temporary value
--> src/lib.rs:243:9
|
242 | let lock_as_ref: &mut (Box<dyn Fusion>, bool) = &mut *mx.lock()?;
| ---------- temporary value created here
243 | Ok(lock_as_ref)
| ^^^^^^^^^^^^^^^ returns a value referencing data owned by the current function
this entails at least 2 problems:
the lifetime of
lock_as_refis automatically inferred as&mut, instead of&'a mut.the reference cannot be copied to be owned to a variable outside the function, despite that it can be easily done.
Obviously &'a mut is only a barebone reference that is not as powerful as a smart pointer, but apparent this is the only method to effectively return a reference INSIDE the tuple (Box<(dyn Fusion + 'static)>, bool), e.g.:
pub fn locked_fusion<'a>() -> Result<&'a mut Box<dyn Fusion>> {
let c = Self::existing().unwrap();
let mx = c.fusion.as_ref().unwrap();
let lock = mx.lock()?;
todo!()
}
In this case, what's the correct way to return a reference of Box<dyn Fusion> with least runtime overhead?
You can find the whole project on github