diff --git a/components/salsa-macro-rules/src/setup_interned_struct.rs b/components/salsa-macro-rules/src/setup_interned_struct.rs index 39b795e62..0de14b30c 100644 --- a/components/salsa-macro-rules/src/setup_interned_struct.rs +++ b/components/salsa-macro-rules/src/setup_interned_struct.rs @@ -124,15 +124,6 @@ macro_rules! setup_interned_struct { const DEBUG_NAME: &'static str = stringify!($Struct); type Fields<'a> = $StructDataIdent<'a>; type Struct<'db> = $Struct< $($db_lt_arg)? >; - fn struct_from_id<'db>(id: salsa::Id) -> Self::Struct<'db> { - use salsa::plumbing::FromId; - $Struct(<$Id>::from_id(id), std::marker::PhantomData) - } - - fn deref_struct(s: Self::Struct<'_>) -> salsa::Id { - use salsa::plumbing::AsId; - s.0.as_id() - } } impl $Configuration { diff --git a/components/salsa-macro-rules/src/setup_tracked_fn.rs b/components/salsa-macro-rules/src/setup_tracked_fn.rs index e49e3f067..39f7740ae 100644 --- a/components/salsa-macro-rules/src/setup_tracked_fn.rs +++ b/components/salsa-macro-rules/src/setup_tracked_fn.rs @@ -120,22 +120,26 @@ macro_rules! setup_tracked_fn { } } + impl $zalsa::AsId for $InternedData<'_> { + #[inline] + fn as_id(&self) -> salsa::Id { + self.0 + } + } + + impl $zalsa::FromId for $InternedData<'_> { + #[inline] + fn from_id(id: salsa::Id) -> Self { + Self(id, ::core::marker::PhantomData) + } + } + impl $zalsa::interned::Configuration for $Configuration { const DEBUG_NAME: &'static str = "Configuration"; type Fields<$db_lt> = ($($input_ty),*); type Struct<$db_lt> = $InternedData<$db_lt>; - - fn struct_from_id<$db_lt>( - id: salsa::Id, - ) -> Self::Struct<$db_lt> { - $InternedData(id, std::marker::PhantomData) - } - - fn deref_struct(s: Self::Struct<'_>) -> salsa::Id { - s.0 - } } } else { type $InternedData<$db_lt> = ($($input_ty),*); diff --git a/components/salsa-macro-rules/src/setup_tracked_struct.rs b/components/salsa-macro-rules/src/setup_tracked_struct.rs index 622230bea..afccf3a01 100644 --- a/components/salsa-macro-rules/src/setup_tracked_struct.rs +++ b/components/salsa-macro-rules/src/setup_tracked_struct.rs @@ -125,14 +125,6 @@ macro_rules! setup_tracked_struct { type Struct<$db_lt> = $Struct<$db_lt>; - fn struct_from_id<$db_lt>(id: salsa::Id) -> Self::Struct<$db_lt> { - $Struct(id, std::marker::PhantomData) - } - - fn deref_struct(s: Self::Struct<'_>) -> salsa::Id { - s.0 - } - fn untracked_fields(fields: &Self::Fields<'_>) -> impl std::hash::Hash { ( $( &fields.$absolute_untracked_index ),* ) } @@ -187,12 +179,14 @@ macro_rules! setup_tracked_struct { } impl<$db_lt> $zalsa::FromId for $Struct<$db_lt> { + #[inline] fn from_id(id: salsa::Id) -> Self { $Struct(id, std::marker::PhantomData) } } impl $zalsa::AsId for $Struct<'_> { + #[inline] fn as_id(&self) -> $zalsa::Id { self.0 } diff --git a/src/id.rs b/src/id.rs index 2cd785dab..6b8242758 100644 --- a/src/id.rs +++ b/src/id.rs @@ -69,17 +69,19 @@ pub trait AsId: Sized { } /// Internal Salsa trait for types that are just a newtype'd [`Id`][]. -pub trait FromId: AsId + Copy + Eq + Hash { +pub trait FromId { fn from_id(id: Id) -> Self; } impl AsId for Id { + #[inline] fn as_id(&self) -> Id { *self } } impl FromId for Id { + #[inline] fn from_id(id: Id) -> Self { id } @@ -87,7 +89,7 @@ impl FromId for Id { /// Enums cannot use [`FromId`] because they need access to the DB to tell the `TypeId` of the variant, /// so they use this trait instead, that has a blanket implementation for `FromId`. -pub trait FromIdWithDb: AsId + Copy + Eq + Hash { +pub trait FromIdWithDb { fn from_id(id: Id, db: &(impl ?Sized + Database)) -> Self; } diff --git a/src/input.rs b/src/input.rs index 529cb230e..c3707c5b2 100644 --- a/src/input.rs +++ b/src/input.rs @@ -10,7 +10,7 @@ pub mod singleton; use input_field::FieldIngredientImpl; use crate::function::VerifyResult; -use crate::id::{AsId, FromIdWithDb}; +use crate::id::{AsId, FromId, FromIdWithDb}; use crate::ingredient::{fmt_index, Ingredient}; use crate::input::singleton::{Singleton, SingletonChoice}; use crate::key::DatabaseKeyIndex; @@ -28,7 +28,7 @@ pub trait Configuration: Any { type Singleton: SingletonChoice + Send + Sync; /// The input struct (which wraps an `Id`) - type Struct: FromIdWithDb + 'static + Send + Sync; + type Struct: FromId + AsId + 'static + Send + Sync; /// A (possibly empty) tuple of the fields for this struct. type Fields: Send + Sync; diff --git a/src/interned.rs b/src/interned.rs index 4a6d1b414..67ba3bfb6 100644 --- a/src/interned.rs +++ b/src/interned.rs @@ -14,6 +14,7 @@ use dashmap::SharedValue; use crate::durability::Durability; use crate::function::VerifyResult; use crate::hash::FxDashMap; +use crate::id::{AsId, FromId}; use crate::ingredient::{fmt_index, Ingredient}; use crate::plumbing::{IngredientIndices, Jar}; use crate::revision::AtomicRevision; @@ -29,18 +30,7 @@ pub trait Configuration: Sized + 'static { type Fields<'db>: InternedData; /// The end user struct - type Struct<'db>: Copy; - - /// Create an end-user struct from the salsa id - /// - /// This call is an "end-step" to the tracked struct lookup/creation - /// process in a given revision: it occurs only when the struct is newly - /// created or, if a struct is being reused, after we have updated its - /// fields (or confirmed it is green and no updates are required). - fn struct_from_id<'db>(id: Id) -> Self::Struct<'db>; - - /// Deref the struct to yield the underlying id. - fn deref_struct(s: Self::Struct<'_>) -> Id; + type Struct<'db>: Copy + FromId + AsId; } pub trait InternedData: Sized + Eq + Hash + Clone + Sync + Send {} @@ -169,7 +159,7 @@ where Key: Hash, C::Fields<'db>: HashEqLike, { - C::struct_from_id(self.intern_id(db, key, assemble)) + FromId::from_id(self.intern_id(db, key, assemble)) } /// Intern data to a unique reference. @@ -367,7 +357,7 @@ where /// Lookup the fields from an interned struct. /// Note that this is not "leaking" since no dependency edge is required. pub fn fields<'db>(&'db self, db: &'db dyn Database, s: C::Struct<'db>) -> &'db C::Fields<'db> { - self.data(db, C::deref_struct(s)) + self.data(db, AsId::as_id(&s)) } pub fn reset(&mut self, db: &mut dyn Database) { diff --git a/src/tracked_struct.rs b/src/tracked_struct.rs index cbb6ab8ee..0d2b82c1c 100644 --- a/src/tracked_struct.rs +++ b/src/tracked_struct.rs @@ -11,6 +11,7 @@ use crossbeam_queue::SegQueue; use tracked_field::FieldIngredientImpl; use crate::function::VerifyResult; +use crate::id::{AsId, FromId}; use crate::ingredient::{fmt_index, Ingredient, Jar}; use crate::key::DatabaseKeyIndex; use crate::plumbing::ZalsaLocal; @@ -47,18 +48,7 @@ pub trait Configuration: Sized + 'static { /// values have changed (or if the field is marked as `#[no_eq]`). type Revisions: Send + Sync + Index; - type Struct<'db>: Copy; - - /// Create an end-user struct from the underlying raw pointer. - /// - /// This call is an "end-step" to the tracked struct lookup/creation - /// process in a given revision: it occurs only when the struct is newly - /// created or, if a struct is being reused, after we have updated its - /// fields (or confirmed it is green and no updates are required). - fn struct_from_id<'db>(id: Id) -> Self::Struct<'db>; - - /// Deref the struct to yield the underlying id. - fn deref_struct(s: Self::Struct<'_>) -> Id; + type Struct<'db>: Copy + FromId + AsId; fn untracked_fields(fields: &Self::Fields<'_>) -> impl Hash; @@ -419,7 +409,7 @@ where // The struct already exists in the intern map. zalsa_local.add_output(self.database_key_index(id)); self.update(zalsa, current_revision, id, ¤t_deps, fields); - C::struct_from_id(id) + FromId::from_id(id) } None => { @@ -428,7 +418,7 @@ where let key = self.database_key_index(id); zalsa_local.add_output(key); zalsa_local.store_tracked_struct_id(identity, id); - C::struct_from_id(id) + FromId::from_id(id) } } } @@ -667,7 +657,7 @@ where db: &'db dyn Database, s: C::Struct<'db>, ) -> &'db C::Fields<'db> { - let id = C::deref_struct(s); + let id = AsId::as_id(&s); let value = Self::data(db.zalsa().table(), id); unsafe { self.to_self_ref(&value.fields) } } @@ -683,7 +673,7 @@ where relative_tracked_index: usize, ) -> &'db C::Fields<'db> { let (zalsa, zalsa_local) = db.zalsas(); - let id = C::deref_struct(s); + let id = AsId::as_id(&s); let field_ingredient_index = self.ingredient_index.successor(relative_tracked_index); let data = Self::data(zalsa.table(), id); @@ -710,7 +700,7 @@ where s: C::Struct<'db>, ) -> &'db C::Fields<'db> { let (zalsa, zalsa_local) = db.zalsas(); - let id = C::deref_struct(s); + let id = AsId::as_id(&s); let data = Self::data(zalsa.table(), id); data.read_lock(zalsa.current_revision()); diff --git a/tests/interned-structs_self_ref.rs b/tests/interned-structs_self_ref.rs index 0a39049cd..56db7ec33 100644 --- a/tests/interned-structs_self_ref.rs +++ b/tests/interned-structs_self_ref.rs @@ -72,12 +72,6 @@ const _: () = { const DEBUG_NAME: &'static str = "InternedString"; type Fields<'a> = StructData<'a>; type Struct<'a> = InternedString<'a>; - fn struct_from_id<'db>(id: salsa::Id) -> Self::Struct<'db> { - InternedString(id, std::marker::PhantomData) - } - fn deref_struct(s: Self::Struct<'_>) -> salsa::Id { - s.0 - } } impl Configuration_ { pub fn ingredient(db: &Db) -> &zalsa_struct_::IngredientImpl