Supporting 'janitorial' style RAII

As far as I can tell, the idea behind this whole thread still being alive is that instead of the already proposed approach

let x: &mut Something = //...
// do sth
{
    let guard = specialized_guard(x);
    let x = guard.as_mut();
    // use inner x
}
// use outer x again

which could (as mentioned) be shortened with a macro, and which unfortunately doesn’t quite work with self syntactically, there ought to be another way. The proposed approach is not “nice” enough, reason being: You need a local copy of x there which is essentially the same as the outer x, but you know it isn’t really the same x and there ought to be (and if not change the language) a way to instead write something like

let x: &mut Something = //...
// do sth
{
    let guard = specialized_guard(&mut#reborrow_delayed *x);
    // use outer x
}
// use outer x 

Unfortunately using the same outer x is not safe. The x’s are not the same in the following regard: The inner x has a shorter life-time and this fact is significant. As demonstrated for example with this code:

use crossbeam_utils::thread;

let x: &mut Something = //...
// do sth
thread::scope(|s| {
    // do sth more
    {
        let guard = specialized_guard(&mut#reborrow_delayed *x);
        let _handle = s.spawn(|_| /* use outer x */);
        // can’t use outer x here anymore
    }
    // can’t use outer x here anymore
}).unwrap();
// can use outer x again

Here, all the sudden, a different thread could access x mutably in parrallel with the guard being dropped. This kind of code would be rejected with a distinct, shorter-lived inner x, since the spawned scoped thread can only be passed references with a lifetime of at least the scope s.

7 Likes