1use std::marker::PhantomData;
8#[cfg(miri)]
9use {crate::loom::sync::Mutex, std::collections::BTreeMap};
10
11pub(crate) struct PtrExposeDomain<T> {
12 #[cfg(miri)]
13 map: Mutex<BTreeMap<usize, *const T>>,
14 _phantom: PhantomData<T>,
15}
16
17unsafe impl<T> Sync for PtrExposeDomain<T> {}
19
20impl<T> PtrExposeDomain<T> {
21 pub(crate) const fn new() -> Self {
22 Self {
23 #[cfg(miri)]
24 map: Mutex::const_new(BTreeMap::new()),
25 _phantom: PhantomData,
26 }
27 }
28
29 #[inline]
30 pub(crate) fn expose_provenance(&self, ptr: *const T) -> usize {
31 #[cfg(miri)]
32 {
33 let addr: usize = ptr.addr();
34 self.map.lock().insert(addr, ptr);
35 addr
36 }
37
38 #[cfg(not(miri))]
39 {
40 ptr as usize
41 }
42 }
43
44 #[inline]
45 #[allow(clippy::wrong_self_convention)] pub(crate) fn from_exposed_addr(&self, addr: usize) -> *const T {
47 #[cfg(miri)]
48 {
49 let maybe_ptr = self.map.lock().get(&addr).copied();
50
51 unsafe { maybe_ptr.unwrap_unchecked() }
54 }
55
56 #[cfg(not(miri))]
57 {
58 addr as *const T
59 }
60 }
61
62 #[inline]
63 pub(crate) fn unexpose_provenance(&self, _ptr: *const T) {
64 #[cfg(miri)]
65 {
66 let addr: usize = _ptr.addr();
67 let maybe_ptr = self.map.lock().remove(&addr);
68
69 unsafe { maybe_ptr.unwrap_unchecked() };
72 }
73 }
74}