Skip to content

Instantly share code, notes, and snippets.

@dicej
Last active May 8, 2025 19:57
Show Gist options
  • Save dicej/0fd17b827eb657c5860aa0d4ec979645 to your computer and use it in GitHub Desktop.
Save dicej/0fd17b827eb657c5860aa0d4ec979645 to your computer and use it in GitHub Desktop.
struct StoreToken<T> {
id: StoreId,
_phantom: PhantomData<fn() -> T>,
}
impl<T> StoreToken<T> {
pub fn new(store: StoreContextMut<T>) -> Self {
Self { id: store.id(), _phantom: PhantomData }
}
pub fn safe_cast<'a>(store: &'a mut dyn VMStore) -> StoreContextMut<'a, T> {
assert_eq!(store.store_opaque().id(), id);
// We know the store with this ID has data type parameter `T` because we witnessed that in `Self::new`:
unsafe { StoreContextMut::<T>(&mut *(store as *mut dyn VMStore).cast()) }
}
}
fn foo<T>(store: StoreContextMut<T>) { .. }
fn bar<T: 'static>(store: StoreContextMut<T>) -> Box<dyn Fn(&mut dyn VMStore) + Send + Sync + 'static {
let token = StoreToken::new(store);
Box::new(move |store| foo(token.safe_cast(store)))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment