I originally opened this question on stackoverflow, it was marked as duplicate, but I don't think the linked questions or Shepmaster resolved my problem.
Consider the following code:
struct Test<'a> {
d: PhantomData<UnsafeCell<&'a u8>>
}
impl<'a> Test<'a> {
pub fn new() -> Self {
Test { d: PhantomData }
}
pub fn test(&'a self){}
}
fn main() {
let t = Test::new();
(move || {
t.test();
})();
}
This fails with following error:
error[E0521]: borrowed data escapes outside of closure
--> src/main.rs:18:9
|
16 | let t = Test::new();
| - `t` declared here, outside of the closure body
17 | (move || {
18 | t.test();
| ^^^^^^^^
Ok, I think the compiler is right, since the lifetime specifier indicates 'a lives outside of the closure, which mismatches with t that was moved into the closure. However, if I change the UnsafeCell to a direct reference, the error no longer appears. Same problem exists for any struct containing UnsafeCell, such as Cell, or Mutex (in the original question).
So my question is:
- Which of the above code (with and without UnsafeCell) is valid? And why?
- Why UnsafeCell would cause the error? Is there anything special about having a reference in it?