1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use core::{
cell::UnsafeCell,
marker::PhantomData,
mem,
};
pub struct GhostToken<'brand> { _marker: InvariantLifetime<'brand> }
impl<'brand> GhostToken<'brand> {
pub fn new<R, F>(fun: F) -> R
where
for <'new_id> F: FnOnce(GhostToken<'new_id>) -> R
{
let token = Self { _marker: InvariantLifetime::default() };
fun(token)
}
}
pub struct GhostCell<'brand, T: ?Sized> {
_marker: InvariantLifetime<'brand>,
value: UnsafeCell<T>,
}
impl<'brand, T> GhostCell<'brand, T> {
pub fn new(value: T) -> Self {
let _marker = InvariantLifetime::default();
let value = UnsafeCell::new(value);
Self { _marker, value, }
}
pub fn into_inner(self) -> T { self.value.into_inner() }
pub fn get_mut(&mut self) -> &mut T { unsafe { mem::transmute(self) } }
pub fn from_mut(t: &mut T) -> &mut Self { unsafe { mem::transmute(t) } }
pub fn borrow<'a>(&'a self, _: &'a GhostToken<'brand>) -> &'a T {
unsafe{ &*self.value.get() }
}
pub fn borrow_mut<'a>(&'a self, _: &'a mut GhostToken<'brand>) -> &'a mut T {
unsafe{ &mut *self.value.get() }
}
}
type InvariantLifetime<'brand> = PhantomData<fn(&'brand ()) -> &'brand ()>;