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
.