In Rust, how to coerce a mutex lock into a reference with identical lifetime?

36 Views Asked by At

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_ref is 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

0

There are 0 best solutions below