use std::{marker::PhantomData, sync::Arc};
use higher_kinded_types as hkt;
use crate::*;
mod rocksdb {
pub struct MultiThreaded;
pub type DBWithThreadMode<T> = std::marker::PhantomData<T>;
pub struct WriteBatch;
pub type SnapshotWithThreadMode<'a, T> = std::marker::PhantomData<T>;
pub type DBRawIteratorWithThreadMode<'a, T> = std::marker::PhantomData<T>;
pub type Error = ();
pub type DBPinnableSlice<'a> = &'a [u8];
pub type BoundColumnFamily<'a> = ();
pub type ReadOptions = ();
pub type Options = ();
pub type ColumnFamilyDescriptor = ();
}
// RocksDB Database Implementation:
#[derive(Clone)]
pub(crate) struct RocksDb(pub(crate) Arc<rocksdb::DBWithThreadMode<rocksdb::MultiThreaded>>);
impl WriteBatch for rocksdb::WriteBatch {
fn size(&self) -> usize {
0
}
}
pub(crate) struct RocksDbSnapshot(
rocksdb::SnapshotWithThreadMode<'static, rocksdb::DBWithThreadMode<rocksdb::MultiThreaded>>,
RocksDb,
);
pub(crate) struct RocksDbCursor<T> {
db: Arc<rocksdb::DBWithThreadMode<rocksdb::MultiThreaded>>,
pub(crate) iter: rocksdb::DBRawIteratorWithThreadMode<
'static,
rocksdb::DBWithThreadMode<rocksdb::MultiThreaded>,
>,
table: PhantomData<T>,
}
impl<T> Base for RocksDbCursor<T> {
type Error = rocksdb::Error;
type PinnedBytes<'a> = rocksdb::DBPinnableSlice<'a>;
}
impl<'k, 'v, T: Table<'k, 'v, Error = Self::Error>> Cursor<'k, 'v, T> for RocksDbCursor<T> {
fn move_next(&mut self) -> Result<(), Self::Error> {
unimplemented!()
}
fn move_prev(&mut self) -> Result<(), Self::Error> {
unimplemented!()
}
fn seek_to_first(&mut self) -> Result<(), Self::Error> {
unimplemented!()
}
fn seek<'a>(
&mut self,
key: &dyn KeyPrefix<'a, T::Key>,
arena: &'a Arena,
) -> Result<(), Self::Error> {
unimplemented!()
}
fn seek_before<'a>(
&mut self,
key: &dyn KeyPrefix<'a, T::Key>,
arena: &'a Arena,
) -> Result<(), Self::Error> {
unimplemented!()
}
fn seek_to_last(&mut self) -> Result<(), Self::Error> {
unimplemented!()
}
fn refresh(&mut self) -> Result<(), Self::Error> {
unimplemented!()
}
fn key(&'k self, arena: &'k Arena) -> Option<T::Key> {
unimplemented!()
}
fn value(&'v self, arena: &'v Arena) -> Option<T::Value> {
unimplemented!()
}
fn key_value<'a: 'k + 'v>(&'a self, arena: &'a Arena) -> Option<(T::Key, T::Value)> {
unimplemented!()
}
}
pub(crate) struct RocksDbTable<M, K, V> {
pub(crate) cf: Arc<rocksdb::BoundColumnFamily<'static>>,
pub(crate) db: RocksDb,
pub(crate) _pd: PhantomData<(M, K, V)>,
}
impl<M, K, V> Clone for RocksDbTable<M, K, V> {
fn clone(&self) -> Self {
Self {
cf: self.cf.clone(),
db: self.db.clone(),
_pd: PhantomData,
}
}
}
impl<M, K, V> Base for RocksDbTable<M, K, V> {
type Error = rocksdb::Error;
type PinnedBytes<'a> = rocksdb::DBPinnableSlice<'a>;
}
impl<'k, 'v, M, K: for<'a> hkt::ForLt<Of<'a>: Value<'a>>, V: for<'a> hkt::ForLt<Of<'a>: Value<'a>>>
Table<'k, 'v> for RocksDbTable<M, K, V>
{
type Snapshot = RocksDbSnapshot;
type WriteBatch = rocksdb::WriteBatch;
type Cursor = RocksDbCursor<Self>;
type Key = K::Of<'k>;
type Value = V::Of<'v>;
fn get<'this: 'v, 'a: 'k + 'v>(
&'this self,
snap: &Self::Snapshot,
key: &'k Self::Key,
arena: &'a Arena,
pinned: &'v mut Option<Self::PinnedBytes<'this>>,
) -> Result<Option<Self::Value>, Self::Error> {
unimplemented!()
}
fn put<'a: 'k + 'v>(
&self,
wb: &mut Self::WriteBatch,
arena: &'a Arena,
key: &'k Self::Key,
value: &'v Self::Value,
) -> Result<(), Self::Error> {
unimplemented!()
}
fn delete<'a: 'k>(
&self,
wb: &mut Self::WriteBatch,
arena: &'a Arena,
key: &'k Self::Key,
) -> Result<(), Self::Error> {
unimplemented!()
}
fn cursor(&self, snap: &Self::Snapshot) -> Self::Cursor {
unimplemented!()
}
}
pub(crate) struct RocksDbSingleton<M, V> {
pub(crate) key: &'static [u8],
pub(crate) table: RocksDbTable<(), hkt::ForLt!(&[u8]), V>,
pub(crate) _pd: PhantomData<M>,
}
impl<M, V> Clone for RocksDbSingleton<M, V> {
fn clone(&self) -> Self {
let Self {
key,
ref table,
_pd,
} = *self;
Self {
key,
table: table.clone(),
_pd,
}
}
}
impl<M, V> Base for RocksDbSingleton<M, V> {
type Error = rocksdb::Error;
type PinnedBytes<'a> = rocksdb::DBPinnableSlice<'a>;
}
impl<'v, M, V: for<'a> hkt::ForLt<Of<'a>: Value<'a>>> Singleton<'v> for RocksDbSingleton<M, V> {
type Snapshot = RocksDbSnapshot;
type WriteBatch = rocksdb::WriteBatch;
type Value = V::Of<'v>;
fn get<'this: 'v, 'a: 'v>(
&'this self,
snap: &Self::Snapshot,
arena: &'a Arena,
pinned: &'v mut Option<Self::PinnedBytes<'this>>,
) -> Result<Option<Self::Value>, Self::Error> {
unimplemented!()
}
fn put<'a: 'v>(
&self,
wb: &mut Self::WriteBatch,
arena: &'a Arena,
value: &'v Self::Value,
) -> Result<(), Self::Error> {
unimplemented!()
}
fn delete(&self, wb: &mut Self::WriteBatch, arena: &Arena) -> Result<(), Self::Error> {
unimplemented!()
}
}
impl Base for RocksDb {
type Error = rocksdb::Error;
type PinnedBytes<'a> = rocksdb::DBPinnableSlice<'a>;
}
impl Db for RocksDb {
type Snapshot = RocksDbSnapshot;
type WriteBatch = rocksdb::WriteBatch;
type Options = rocksdb::Options;
type TableParams = rocksdb::ColumnFamilyDescriptor;
fn new(
path: &std::path::Path,
opts: &Self::Options,
tables: &[&dyn TableParams<Self>],
) -> Result<Self, Self::Error> {
unimplemented!()
}
fn new_read_only(
path: &std::path::Path,
opts: &Self::Options,
tables: &[&dyn TableParams<Self>],
) -> Result<Self, Self::Error> {
unimplemented!()
}
fn snapshot(&self) -> Self::Snapshot {
unimplemented!()
}
fn new_write_batch(&self) -> Self::WriteBatch {
unimplemented!()
}
fn commit(&self, wb: Self::WriteBatch) -> Result<(), rocksdb::Error> {
unimplemented!()
}
fn commit_no_wal(&self, wb: Self::WriteBatch) -> Result<(), rocksdb::Error> {
unimplemented!()
}
}
rust-analyzer version:
rust-analyzer version: 0.4.2826-standalonerustc version:
rustc 1.91.0-nightly (2e2642e64 2025-08-16)editor or extension: VSCode, 0.4.2826
relevant settings: N/A
repository link (if public, optional): N/A
code snippet to reproduce:
This depends on the
higher-kinded-typescrate. The infinite loop happens whenrdb.rsis opened, or when the server starts withrdb.rsopened. Ifrdb.rsisn't opened then the infinite loop does not happen. Rarely, openingrdb.rsdoes not trigger the infinite loop.This requires two files (otherwise opening
lib.rswill hit the infinite loop), along with the hkt dependency.Cargo.tomlsrc/lib.rsDetails
src/rdb.rsDetails