diff --git a/src/interned.rs b/src/interned.rs index e4223d17..8348bd9a 100644 --- a/src/interned.rs +++ b/src/interned.rs @@ -19,8 +19,7 @@ use std::hash::Hash; pub struct InternedStorage where Q: Query, - Q::Value: From, - Q::Value: Into, + Q::Value: InternKey, DB: Database, { tables: RwLock>, @@ -39,6 +38,38 @@ struct InternTables { first_free: Option, } +/// Trait implemented for the "key" that results from a +/// `#[salsa::intern]` query. This is basically meant to be a +/// "newtype"'d `u32`. +pub trait InternKey { + /// Create an instance of the intern-key from a `u32` value. + fn from_u32(v: u32) -> Self; + + /// Extract the `u32` with which the intern-key was created. + fn as_u32(&self) -> u32; +} + +impl InternKey for u32 { + fn from_u32(v: u32) -> Self { + v + } + + fn as_u32(&self) -> u32 { + *self + } +} + +impl InternKey for usize { + fn from_u32(v: u32) -> Self { + v as usize + } + + fn as_u32(&self) -> u32 { + assert!(*self < (std::u32::MAX as usize)); + *self as u32 + } +} + /// Newtype indicating an index into the intern table. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] struct InternIndex { @@ -83,8 +114,7 @@ where Q: Query, DB: Database, Q::Key: std::panic::RefUnwindSafe, - Q::Value: From, - Q::Value: Into, + Q::Value: InternKey, Q::Value: std::panic::RefUnwindSafe, { } @@ -93,8 +123,7 @@ impl Default for InternedStorage where Q: Query, Q::Key: Eq + Hash, - Q::Value: From, - Q::Value: Into, + Q::Value: InternKey, DB: Database, { fn default() -> Self { @@ -121,8 +150,7 @@ impl InternedStorage where Q: Query, Q::Key: Eq + Hash + Clone, - Q::Value: From, - Q::Value: Into, + Q::Value: InternKey, DB: Database, { fn intern_index(&self, db: &DB, key: &Q::Key) -> StampedValue { @@ -326,10 +354,7 @@ where impl QueryStorageOps for InternedStorage where Q: Query, - Q::Key: ToOwned, - ::Owned: Eq + Hash + Clone, - Q::Value: From, - Q::Value: Into, + Q::Value: InternKey, DB: Database, { fn try_fetch( @@ -343,7 +368,7 @@ where db.salsa_runtime() .report_query_read(database_key, changed_at); - Ok(::from(value.index)) + Ok(::from_u32(value.index)) } fn maybe_changed_since( @@ -374,7 +399,9 @@ where tables .map .iter() - .map(|(key, index)| TableEntry::new(key.clone(), Some(::from(index.index)))) + .map(|(key, index)| { + TableEntry::new(key.clone(), Some(::from_u32(index.index))) + }) .collect() } } @@ -382,14 +409,11 @@ where impl InternedQueryStorageOps for InternedStorage where Q: Query, - Q::Key: ToOwned, - ::Owned: Eq + Hash + Clone, - Q::Value: From, - Q::Value: Into, + Q::Value: InternKey, DB: Database, { fn lookup(&self, db: &DB, value: Q::Value) -> Q::Key { - let index: u32 = value.into(); + let index: u32 = value.as_u32(); let StampedValue { value, changed_at: _, @@ -408,9 +432,7 @@ where impl QueryStorageMassOps for InternedStorage where Q: Query, - Q::Key: ToOwned, - Q::Value: From, - Q::Value: Into, + Q::Value: InternKey, DB: Database, { fn sweep(&self, db: &DB, strategy: SweepStrategy) { diff --git a/src/lib.rs b/src/lib.rs index 7bf2204e..fa526cf7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,6 +28,7 @@ use derive_new::new; use std::fmt::{self, Debug}; use std::hash::Hash; +pub use crate::interned::InternKey; pub use crate::runtime::Runtime; pub use crate::runtime::RuntimeId; @@ -470,7 +471,7 @@ where pub fn lookup(&self, value: Q::Value) -> Q::Key where Q::Storage: plumbing::InternedQueryStorageOps, - Q::Value: Into, + Q::Value: InternKey, { self.storage.lookup(self.db, value) } diff --git a/src/plumbing.rs b/src/plumbing.rs index d668cba9..d4ac11d5 100644 --- a/src/plumbing.rs +++ b/src/plumbing.rs @@ -189,7 +189,6 @@ pub trait InternedQueryStorageOps: Default where DB: Database, Q: Query, - Q::Value: Into, { fn lookup(&self, db: &DB, value: Q::Value) -> Q::Key; } diff --git a/tests/interned.rs b/tests/interned.rs index ad5e175b..13c6ce7b 100644 --- a/tests/interned.rs +++ b/tests/interned.rs @@ -27,14 +27,12 @@ trait Intern { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub struct InternKey(u32); -impl From for InternKey { - fn from(v: u32) -> Self { +impl salsa::InternKey for InternKey { + fn from_u32(v: u32) -> Self { InternKey(v) } -} -impl Into for InternKey { - fn into(self) -> u32 { + fn as_u32(&self) -> u32 { self.0 } }