Feature: Subtyping of Mutex lifetimes

The following does not compile:

use std::sync::Mutex;

fn f<'a, 'b>(x: &Mutex<&'a i32>, y: &Mutex<&'b i32>)
    where 'a: 'b
{
    let mut x1 = x;
    let mut y1 = y;
    y1 = x1;
}

I propose to make Mutex<&'b T> a subtype of Mutex<&'a T> when 'a: 'b, because that's a missing useful feature. I met this trouble developing ref_mutex a lib for mutexes holding references (Mutex misses Sync or for references, so I am creating its wrapper.), so I may need a complex workaround.

Please make a path or at least discuss with me an imlementation.

This is unsound. if we have two borrows of a Mutex<&'long i32> and use subtyping to turn one into &Mutex<&'short i32> and then replace the thing inside the mutex with a different &'short i32 the other borrow of the mutex thinks there's a &'long i32 could copy it out and have a &'long i32 that only lives for &'short i32

edit: I recommend reading this page in the rustnomicon: Subtyping and Variance - The Rustonomicon

7 Likes

In particular, the nomicon explains why &mut T is invariant in T, and that UnsafeCell<T> must therefore also be invariant. We can further add here that Mutex<T> contains an UnsafeCell<T> for interior mutability, so it also must be invariant.

4 Likes