mirror of
https://github.com/salsa-rs/salsa.git
synced 2025-01-22 21:05:11 +00:00
wip
This commit is contained in:
parent
4e295f2257
commit
daba89c278
7 changed files with 150 additions and 450 deletions
|
@ -21,8 +21,3 @@ mod setup_input_struct;
|
|||
mod setup_interned_struct;
|
||||
mod setup_tracked_struct;
|
||||
mod unexpected_cycle_recovery;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! setup_fn {
|
||||
() => {};
|
||||
}
|
||||
|
|
|
@ -6,4 +6,12 @@ macro_rules! macro_if {
|
|||
|
||||
(false => $($t:tt)*) => {
|
||||
};
|
||||
|
||||
(if true { $($t:tt)* } else { $($f:tt)*}) => {
|
||||
$($t)*
|
||||
};
|
||||
|
||||
(if false { $($t:tt)* } else { $($f:tt)*}) => {
|
||||
$($f)*
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,315 +1,6 @@
|
|||
/// Macro for setting up a function with no arguments (but the database).
|
||||
#[macro_export]
|
||||
macro_rules! setup_constant_fn {
|
||||
(
|
||||
// Attributes on the function
|
||||
attrs: [$(#[$attr:meta]),*],
|
||||
|
||||
// Visibility of the function
|
||||
vis: $vis:vis,
|
||||
|
||||
// Name of the function
|
||||
fn_name: $fn_name:ident,
|
||||
|
||||
// Name of the `'db` lifetime that the user gave; if they didn't, then defaults to `'db`
|
||||
db_lt: $db_lt:lifetime,
|
||||
|
||||
// Path to the database trait that the user's database parameter used
|
||||
Db: $Db:path,
|
||||
|
||||
// Name of the database parameter given by the user.
|
||||
db: $db:ident,
|
||||
|
||||
// Return type of the function (may reference `$generics`).
|
||||
output_ty: $output_ty:ty,
|
||||
|
||||
// Function body, may reference identifiers defined in `$input_pats` and the generics from `$generics`
|
||||
inner_fn: $inner_fn:item,
|
||||
|
||||
// Path to the cycle recovery function to use.
|
||||
cycle_recovery_fn: ($($cycle_recovery_fn:tt)*),
|
||||
|
||||
// Name of cycle recovery strategy variant to use.
|
||||
cycle_recovery_strategy: $cycle_recovery_strategy:ident,
|
||||
|
||||
// Annoyingly macro-rules hygiene does not extend to items defined in the macro.
|
||||
// We have the procedural macro generate names for those items that are
|
||||
// not used elsewhere in the user's code.
|
||||
unused_names: [
|
||||
$zalsa:ident,
|
||||
$Configuration:ident,
|
||||
$FN_CACHE:ident,
|
||||
$inner:ident,
|
||||
]
|
||||
) => {
|
||||
#[allow(non_camel_case_types)]
|
||||
$vis struct $fn_name {
|
||||
_priv: std::convert::Infallible,
|
||||
}
|
||||
|
||||
$(#[$attr])*
|
||||
$vis fn $fn_name<$db_lt>(
|
||||
$db: &$db_lt dyn $Db,
|
||||
) -> $output_ty {
|
||||
use salsa::plumbing as $zalsa;
|
||||
|
||||
struct $Configuration;
|
||||
|
||||
static $FN_CACHE: $zalsa::IngredientCache<$zalsa::function::IngredientImpl<$Configuration>> =
|
||||
$zalsa::IngredientCache::new();
|
||||
|
||||
impl $Configuration {
|
||||
fn fn_ingredient(db: &dyn $Db) -> &$zalsa::function::IngredientImpl<$Configuration> {
|
||||
$FN_CACHE.get_or_create(db.as_salsa_database(), || {
|
||||
<dyn $Db as $Db>::zalsa_db(db);
|
||||
db.add_or_lookup_jar_by_type(&$Configuration)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl $zalsa::function::Configuration for $Configuration {
|
||||
const DEBUG_NAME: &'static str = stringify!($fn_name);
|
||||
|
||||
type DbView = dyn $Db;
|
||||
|
||||
type SalsaStruct<$db_lt> = $zalsa::Singleton;
|
||||
|
||||
type Input<$db_lt> = ();
|
||||
|
||||
type Output<$db_lt> = $output_ty;
|
||||
|
||||
const CYCLE_STRATEGY: $zalsa::CycleRecoveryStrategy = $zalsa::CycleRecoveryStrategy::$cycle_recovery_strategy;
|
||||
|
||||
fn should_backdate_value(
|
||||
old_value: &Self::Output<'_>,
|
||||
new_value: &Self::Output<'_>,
|
||||
) -> bool {
|
||||
$zalsa::should_backdate_value(old_value, new_value)
|
||||
}
|
||||
|
||||
fn execute<'db>($db: &'db Self::DbView, (): ()) -> Self::Output<'db> {
|
||||
$inner_fn
|
||||
|
||||
$inner($db)
|
||||
}
|
||||
|
||||
fn recover_from_cycle<'db>(
|
||||
db: &$db_lt dyn $Db,
|
||||
cycle: &$zalsa::Cycle,
|
||||
(): (),
|
||||
) -> Self::Output<'db> {
|
||||
$($cycle_recovery_fn)*(
|
||||
db,
|
||||
cycle,
|
||||
)
|
||||
}
|
||||
|
||||
fn id_to_input<'db>(db: &'db Self::DbView, key: salsa::Id) -> Self::Input<'db> {
|
||||
()
|
||||
}
|
||||
}
|
||||
|
||||
impl $zalsa::Jar for $Configuration {
|
||||
fn create_ingredients(
|
||||
&self,
|
||||
first_index: $zalsa::IngredientIndex,
|
||||
) -> Vec<Box<dyn $zalsa::Ingredient>> {
|
||||
vec![
|
||||
Box::new(<$zalsa::function::IngredientImpl<$Configuration>>::new(
|
||||
first_index,
|
||||
)),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
impl $fn_name {
|
||||
pub fn accumulated<$db_lt, A: salsa::Accumulator>(
|
||||
$db: &$db_lt dyn $Db,
|
||||
) -> Vec<A> {
|
||||
use salsa::plumbing as $zalsa;
|
||||
let key = $zalsa::AsId::as_id(&$zalsa::Singleton);
|
||||
let database_key_index = $Configuration::fn_ingredient($db).database_key_index(key);
|
||||
$zalsa::accumulated_by($db.as_salsa_database(), database_key_index)
|
||||
}
|
||||
}
|
||||
|
||||
$zalsa::attach_database($db, || {
|
||||
$Configuration::fn_ingredient($db).fetch($db, $zalsa::AsId::as_id(&$zalsa::Singleton)).clone()
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Macro for setting up a function that must intern its arguments.
|
||||
#[macro_export]
|
||||
macro_rules! setup_struct_fn {
|
||||
(
|
||||
// Attributes on the function
|
||||
attrs: [$(#[$attr:meta]),*],
|
||||
|
||||
// Visibility of the function
|
||||
vis: $vis:vis,
|
||||
|
||||
// Name of the function
|
||||
fn_name: $fn_name:ident,
|
||||
|
||||
// Name of the `'db` lifetime that the user gave; if they didn't, then defaults to `'db`
|
||||
db_lt: $db_lt:lifetime,
|
||||
|
||||
// Path to the database trait that the user's database parameter used
|
||||
Db: $Db:path,
|
||||
|
||||
// Name of the database parameter given by the user.
|
||||
db: $db:ident,
|
||||
|
||||
// An identifier for each function argument EXCEPT the database.
|
||||
// We prefer to use the identifier the user gave, but if the user gave a pattern
|
||||
// (e.g., `(a, b): (u32, u32)`) we will synthesize an identifier.
|
||||
input_id: $input_id:ident,
|
||||
|
||||
// Types of the function arguments (may reference `$generics`).
|
||||
input_ty: $input_ty:ty,
|
||||
|
||||
// Return type of the function (may reference `$generics`).
|
||||
output_ty: $output_ty:ty,
|
||||
|
||||
// Function body, may reference identifiers defined in `$input_pats` and the generics from `$generics`
|
||||
inner_fn: $inner_fn:item,
|
||||
|
||||
// Path to the cycle recovery function to use.
|
||||
cycle_recovery_fn: ($($cycle_recovery_fn:tt)*),
|
||||
|
||||
// Name of cycle recovery strategy variant to use.
|
||||
cycle_recovery_strategy: $cycle_recovery_strategy:ident,
|
||||
|
||||
// If true, this is specifiable.
|
||||
is_specifiable: $is_specifiable:tt,
|
||||
|
||||
// Annoyingly macro-rules hygiene does not extend to items defined in the macro.
|
||||
// We have the procedural macro generate names for those items that are
|
||||
// not used elsewhere in the user's code.
|
||||
unused_names: [
|
||||
$zalsa:ident,
|
||||
$Configuration:ident,
|
||||
$FN_CACHE:ident,
|
||||
$inner:ident,
|
||||
]
|
||||
) => {
|
||||
#[allow(non_camel_case_types)]
|
||||
$vis struct $fn_name {
|
||||
_priv: std::convert::Infallible,
|
||||
}
|
||||
|
||||
$(#[$attr])*
|
||||
$vis fn $fn_name<$db_lt>(
|
||||
$db: &$db_lt dyn $Db,
|
||||
$input_id: $input_ty,
|
||||
) -> $output_ty {
|
||||
use salsa::plumbing as $zalsa;
|
||||
|
||||
struct $Configuration;
|
||||
|
||||
static $FN_CACHE: $zalsa::IngredientCache<$zalsa::function::IngredientImpl<$Configuration>> =
|
||||
$zalsa::IngredientCache::new();
|
||||
|
||||
impl $Configuration {
|
||||
fn fn_ingredient(db: &dyn $Db) -> &$zalsa::function::IngredientImpl<$Configuration> {
|
||||
$FN_CACHE.get_or_create(db.as_salsa_database(), || {
|
||||
<dyn $Db as $Db>::zalsa_db(db);
|
||||
db.add_or_lookup_jar_by_type(&$Configuration)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl $zalsa::function::Configuration for $Configuration {
|
||||
const DEBUG_NAME: &'static str = stringify!($fn_name);
|
||||
|
||||
type DbView = dyn $Db;
|
||||
|
||||
type SalsaStruct<$db_lt> = $input_ty;
|
||||
|
||||
type Input<$db_lt> = $input_ty;
|
||||
|
||||
type Output<$db_lt> = $output_ty;
|
||||
|
||||
const CYCLE_STRATEGY: $zalsa::CycleRecoveryStrategy = $zalsa::CycleRecoveryStrategy::$cycle_recovery_strategy;
|
||||
|
||||
fn should_backdate_value(
|
||||
old_value: &Self::Output<'_>,
|
||||
new_value: &Self::Output<'_>,
|
||||
) -> bool {
|
||||
$zalsa::should_backdate_value(old_value, new_value)
|
||||
}
|
||||
|
||||
fn execute<'db>($db: &'db Self::DbView, $input_id: $input_ty) -> Self::Output<'db> {
|
||||
$inner_fn
|
||||
|
||||
$inner($db, $input_id)
|
||||
}
|
||||
|
||||
fn recover_from_cycle<'db>(
|
||||
db: &$db_lt dyn $Db,
|
||||
cycle: &$zalsa::Cycle,
|
||||
$input_id: $input_ty,
|
||||
) -> Self::Output<'db> {
|
||||
$($cycle_recovery_fn)*(db, cycle, $input_id)
|
||||
}
|
||||
|
||||
fn id_to_input<'db>(db: &'db Self::DbView, key: salsa::Id) -> Self::Input<'db> {
|
||||
$zalsa::LookupId::lookup_id(key, db.as_salsa_database())
|
||||
}
|
||||
}
|
||||
|
||||
impl $zalsa::Jar for $Configuration {
|
||||
fn create_ingredients(
|
||||
&self,
|
||||
first_index: $zalsa::IngredientIndex,
|
||||
) -> Vec<Box<dyn $zalsa::Ingredient>> {
|
||||
vec![
|
||||
Box::new(<$zalsa::function::IngredientImpl<$Configuration>>::new(
|
||||
first_index,
|
||||
)),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
impl $fn_name {
|
||||
pub fn accumulated<$db_lt, A: salsa::Accumulator>(
|
||||
$db: &$db_lt dyn $Db,
|
||||
$input_id: $input_ty,
|
||||
) -> Vec<A> {
|
||||
use salsa::plumbing as $zalsa;
|
||||
let key = $zalsa::AsId::as_id(&$input_id);
|
||||
let database_key_index = $Configuration::fn_ingredient($db).database_key_index(key);
|
||||
$zalsa::accumulated_by($db.as_salsa_database(), database_key_index)
|
||||
}
|
||||
|
||||
$zalsa::macro_if! { $is_specifiable =>
|
||||
pub fn specify<$db_lt>(
|
||||
$db: &$db_lt dyn $Db,
|
||||
$input_id: $input_ty,
|
||||
value: $output_ty,
|
||||
) {
|
||||
let key = $zalsa::AsId::as_id(&$input_id);
|
||||
$Configuration::fn_ingredient($db).specify_and_record(
|
||||
$db,
|
||||
key,
|
||||
value,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$zalsa::attach_database($db, || {
|
||||
$Configuration::fn_ingredient($db).fetch($db, $zalsa::AsId::as_id(&$input_id)).clone()
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Macro for setting up a function that must intern its arguments.
|
||||
#[macro_export]
|
||||
macro_rules! setup_interned_fn {
|
||||
macro_rules! setup_fn {
|
||||
(
|
||||
// Attributes on the function
|
||||
attrs: [$(#[$attr:meta]),*],
|
||||
|
@ -349,6 +40,12 @@ macro_rules! setup_interned_fn {
|
|||
// Name of cycle recovery strategy variant to use.
|
||||
cycle_recovery_strategy: $cycle_recovery_strategy:ident,
|
||||
|
||||
// If true, this is specifiable.
|
||||
is_specifiable: $is_specifiable:tt,
|
||||
|
||||
// If true, the input needs an interner (because it has >1 argument).
|
||||
needs_interner: $needs_interner:tt,
|
||||
|
||||
// Annoyingly macro-rules hygiene does not extend to items defined in the macro.
|
||||
// We have the procedural macro generate names for those items that are
|
||||
// not used elsewhere in the user's code.
|
||||
|
@ -375,17 +72,45 @@ macro_rules! setup_interned_fn {
|
|||
|
||||
struct $Configuration;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct $InternedData<$db_lt>(
|
||||
std::ptr::NonNull<$zalsa::interned::Value<$Configuration>>,
|
||||
std::marker::PhantomData<&'db $zalsa::interned::Value<$Configuration>>,
|
||||
);
|
||||
|
||||
static $FN_CACHE: $zalsa::IngredientCache<$zalsa::function::IngredientImpl<$Configuration>> =
|
||||
$zalsa::IngredientCache::new();
|
||||
|
||||
static $INTERN_CACHE: $zalsa::IngredientCache<$zalsa::interned::IngredientImpl<$Configuration>> =
|
||||
$zalsa::IngredientCache::new();
|
||||
$zalsa::macro_if! {
|
||||
if $needs_interner {
|
||||
#[derive(Copy, Clone)]
|
||||
struct $InternedData<$db_lt>(
|
||||
std::ptr::NonNull<$zalsa::interned::Value<$Configuration>>,
|
||||
std::marker::PhantomData<&'db $zalsa::interned::Value<$Configuration>>,
|
||||
);
|
||||
|
||||
static $INTERN_CACHE: $zalsa::IngredientCache<$zalsa::interned::IngredientImpl<$Configuration>> =
|
||||
$zalsa::IngredientCache::new();
|
||||
|
||||
impl $zalsa::SalsaStructInDb for $InternedData<'_> {
|
||||
fn register_dependent_fn(_db: &dyn $zalsa::Database, _index: $zalsa::IngredientIndex) {}
|
||||
}
|
||||
|
||||
impl $zalsa::interned::Configuration for $Configuration {
|
||||
const DEBUG_NAME: &'static str = "Configuration";
|
||||
|
||||
type Data<$db_lt> = ($($input_ty),*);
|
||||
|
||||
type Struct<$db_lt> = $InternedData<$db_lt>;
|
||||
|
||||
unsafe fn struct_from_raw<'db>(
|
||||
ptr: std::ptr::NonNull<$zalsa::interned::Value<Self>>,
|
||||
) -> Self::Struct<'db> {
|
||||
$InternedData(ptr, std::marker::PhantomData)
|
||||
}
|
||||
|
||||
fn deref_struct(s: Self::Struct<'_>) -> &$zalsa::interned::Value<Self> {
|
||||
unsafe { s.0.as_ref() }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
type $InternedData<$db_lt> = ($($input_ty),*);
|
||||
}
|
||||
}
|
||||
|
||||
impl $Configuration {
|
||||
fn fn_ingredient(db: &dyn $Db) -> &$zalsa::function::IngredientImpl<$Configuration> {
|
||||
|
@ -395,19 +120,17 @@ macro_rules! setup_interned_fn {
|
|||
})
|
||||
}
|
||||
|
||||
fn intern_ingredient(
|
||||
db: &dyn $Db,
|
||||
) -> &$zalsa::interned::IngredientImpl<$Configuration> {
|
||||
$INTERN_CACHE.get_or_create(db.as_salsa_database(), || {
|
||||
db.add_or_lookup_jar_by_type(&$Configuration).successor(0)
|
||||
})
|
||||
$zalsa::macro_if! { $needs_interner =>
|
||||
fn intern_ingredient(
|
||||
db: &dyn $Db,
|
||||
) -> &$zalsa::interned::IngredientImpl<$Configuration> {
|
||||
$INTERN_CACHE.get_or_create(db.as_salsa_database(), || {
|
||||
db.add_or_lookup_jar_by_type(&$Configuration).successor(0)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl $zalsa::SalsaStructInDb for $InternedData<'_> {
|
||||
fn register_dependent_fn(_db: &dyn $zalsa::Database, _index: $zalsa::IngredientIndex) {}
|
||||
}
|
||||
|
||||
impl $zalsa::function::Configuration for $Configuration {
|
||||
const DEBUG_NAME: &'static str = stringify!($fn_name);
|
||||
|
||||
|
@ -443,25 +166,13 @@ macro_rules! setup_interned_fn {
|
|||
}
|
||||
|
||||
fn id_to_input<'db>(db: &'db Self::DbView, key: salsa::Id) -> Self::Input<'db> {
|
||||
$Configuration::intern_ingredient(db).data(key).clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl $zalsa::interned::Configuration for $Configuration {
|
||||
const DEBUG_NAME: &'static str = "Configuration";
|
||||
|
||||
type Data<$db_lt> = ($($input_ty),*);
|
||||
|
||||
type Struct<$db_lt> = $InternedData<$db_lt>;
|
||||
|
||||
unsafe fn struct_from_raw<'db>(
|
||||
ptr: std::ptr::NonNull<$zalsa::interned::Value<Self>>,
|
||||
) -> Self::Struct<'db> {
|
||||
$InternedData(ptr, std::marker::PhantomData)
|
||||
}
|
||||
|
||||
fn deref_struct(s: Self::Struct<'_>) -> &$zalsa::interned::Value<Self> {
|
||||
unsafe { s.0.as_ref() }
|
||||
$zalsa::macro_if! {
|
||||
if $needs_interner {
|
||||
$Configuration::intern_ingredient(db).data(key).clone()
|
||||
} else {
|
||||
$zalsa::LookupId::lookup_id(key, db.as_salsa_database())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -470,14 +181,24 @@ macro_rules! setup_interned_fn {
|
|||
&self,
|
||||
first_index: $zalsa::IngredientIndex,
|
||||
) -> Vec<Box<dyn $zalsa::Ingredient>> {
|
||||
vec![
|
||||
Box::new(<$zalsa::function::IngredientImpl<$Configuration>>::new(
|
||||
first_index,
|
||||
)),
|
||||
Box::new(<$zalsa::interned::IngredientImpl<$Configuration>>::new(
|
||||
first_index.successor(0)
|
||||
)),
|
||||
]
|
||||
$zalsa::macro_if! {
|
||||
if $needs_interner {
|
||||
vec![
|
||||
Box::new(<$zalsa::function::IngredientImpl<$Configuration>>::new(
|
||||
first_index,
|
||||
)),
|
||||
Box::new(<$zalsa::interned::IngredientImpl<$Configuration>>::new(
|
||||
first_index.successor(0)
|
||||
)),
|
||||
]
|
||||
} else {
|
||||
vec![
|
||||
Box::new(<$zalsa::function::IngredientImpl<$Configuration>>::new(
|
||||
first_index,
|
||||
)),
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -487,15 +208,42 @@ macro_rules! setup_interned_fn {
|
|||
$($input_id: $input_ty,)*
|
||||
) -> Vec<A> {
|
||||
use salsa::plumbing as $zalsa;
|
||||
let key = $Configuration::intern_ingredient($db).intern_id($db.runtime(), ($($input_id),*));
|
||||
let key = $zalsa::macro_if! {
|
||||
if $needs_interner {
|
||||
$Configuration::intern_ingredient($db).intern_id($db.runtime(), ($($input_id),*))
|
||||
} else {
|
||||
$zalsa::AsId::as_id(&($($input_id),*))
|
||||
}
|
||||
};
|
||||
let database_key_index = $Configuration::fn_ingredient($db).database_key_index(key);
|
||||
$zalsa::accumulated_by($db.as_salsa_database(), database_key_index)
|
||||
}
|
||||
|
||||
$zalsa::macro_if! { $is_specifiable =>
|
||||
pub fn specify<$db_lt>(
|
||||
$db: &$db_lt dyn $Db,
|
||||
$($input_id: $input_ty,)*
|
||||
value: $output_ty,
|
||||
) {
|
||||
let key = $zalsa::AsId::as_id(&($($input_id),*));
|
||||
$Configuration::fn_ingredient($db).specify_and_record(
|
||||
$db,
|
||||
key,
|
||||
value,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$zalsa::attach_database($db, || {
|
||||
let key = $Configuration::intern_ingredient($db).intern_id($db.runtime(), ($($input_id),*));
|
||||
$Configuration::fn_ingredient($db).fetch($db, key).clone()
|
||||
$zalsa::macro_if! {
|
||||
if $needs_interner {
|
||||
let key = $Configuration::intern_ingredient($db).intern_id($db.runtime(), ($($input_id),*));
|
||||
$Configuration::fn_ingredient($db).fetch($db, key).clone()
|
||||
} else {
|
||||
$Configuration::fn_ingredient($db).fetch($db, $zalsa::AsId::as_id(&($($input_id),*))).clone()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
|
|
|
@ -93,78 +93,38 @@ impl Macro {
|
|||
}
|
||||
}
|
||||
|
||||
match function_type {
|
||||
FunctionType::Constant => Ok(crate::debug::dump_tokens(
|
||||
fn_name,
|
||||
quote![salsa::plumbing::setup_constant_fn! {
|
||||
attrs: [#(#attrs),*],
|
||||
vis: #vis,
|
||||
fn_name: #fn_name,
|
||||
db_lt: #db_lt,
|
||||
Db: #db_path,
|
||||
db: #db_ident,
|
||||
output_ty: #output_ty,
|
||||
inner_fn: #inner_fn,
|
||||
cycle_recovery_fn: #cycle_recovery_fn,
|
||||
cycle_recovery_strategy: #cycle_recovery_strategy,
|
||||
unused_names: [
|
||||
#zalsa,
|
||||
#Configuration,
|
||||
#FN_CACHE,
|
||||
#inner,
|
||||
]
|
||||
}],
|
||||
)),
|
||||
FunctionType::RequiresInterning => Ok(crate::debug::dump_tokens(
|
||||
fn_name,
|
||||
quote![salsa::plumbing::setup_interned_fn! {
|
||||
attrs: [#(#attrs),*],
|
||||
vis: #vis,
|
||||
fn_name: #fn_name,
|
||||
db_lt: #db_lt,
|
||||
Db: #db_path,
|
||||
db: #db_ident,
|
||||
input_ids: [#(#input_ids),*],
|
||||
input_tys: [#(#input_tys),*],
|
||||
output_ty: #output_ty,
|
||||
inner_fn: #inner_fn,
|
||||
cycle_recovery_fn: #cycle_recovery_fn,
|
||||
cycle_recovery_strategy: #cycle_recovery_strategy,
|
||||
unused_names: [
|
||||
#zalsa,
|
||||
#Configuration,
|
||||
#InternedData,
|
||||
#FN_CACHE,
|
||||
#INTERN_CACHE,
|
||||
#inner,
|
||||
]
|
||||
}],
|
||||
)),
|
||||
FunctionType::SalsaStruct => Ok(crate::debug::dump_tokens(
|
||||
fn_name,
|
||||
quote![salsa::plumbing::setup_struct_fn! {
|
||||
attrs: [#(#attrs),*],
|
||||
vis: #vis,
|
||||
fn_name: #fn_name,
|
||||
db_lt: #db_lt,
|
||||
Db: #db_path,
|
||||
db: #db_ident,
|
||||
input_id: #(#input_ids,)*
|
||||
input_ty: #(#input_tys,)*
|
||||
output_ty: #output_ty,
|
||||
inner_fn: #inner_fn,
|
||||
cycle_recovery_fn: #cycle_recovery_fn,
|
||||
cycle_recovery_strategy: #cycle_recovery_strategy,
|
||||
is_specifiable: #is_specifiable,
|
||||
unused_names: [
|
||||
#zalsa,
|
||||
#Configuration,
|
||||
#FN_CACHE,
|
||||
#inner,
|
||||
]
|
||||
}],
|
||||
)),
|
||||
}
|
||||
let needs_interner = match function_type {
|
||||
FunctionType::RequiresInterning => true,
|
||||
FunctionType::Constant | FunctionType::SalsaStruct => false,
|
||||
};
|
||||
|
||||
Ok(crate::debug::dump_tokens(
|
||||
fn_name,
|
||||
quote![salsa::plumbing::setup_fn! {
|
||||
attrs: [#(#attrs),*],
|
||||
vis: #vis,
|
||||
fn_name: #fn_name,
|
||||
db_lt: #db_lt,
|
||||
Db: #db_path,
|
||||
db: #db_ident,
|
||||
input_ids: [#(#input_ids),*],
|
||||
input_tys: [#(#input_tys),*],
|
||||
output_ty: #output_ty,
|
||||
inner_fn: #inner_fn,
|
||||
cycle_recovery_fn: #cycle_recovery_fn,
|
||||
cycle_recovery_strategy: #cycle_recovery_strategy,
|
||||
is_specifiable: #is_specifiable,
|
||||
needs_interner: #needs_interner,
|
||||
unused_names: [
|
||||
#zalsa,
|
||||
#Configuration,
|
||||
#InternedData,
|
||||
#FN_CACHE,
|
||||
#INTERN_CACHE,
|
||||
#inner,
|
||||
]
|
||||
}],
|
||||
))
|
||||
}
|
||||
|
||||
fn validity_check<'item>(&self, item: &'item syn::ItemFn) -> syn::Result<ValidFn<'item>> {
|
||||
|
|
|
@ -114,16 +114,15 @@ impl FromId for Id {
|
|||
|
||||
/// As a special case, we permit `Singleton` to be converted to an `Id`.
|
||||
/// This is useful for declaring functions with no arguments.
|
||||
impl AsId for salsa_struct::Singleton {
|
||||
impl AsId for () {
|
||||
fn as_id(&self) -> Id {
|
||||
Id::from_u32(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromId for salsa_struct::Singleton {
|
||||
impl FromId for () {
|
||||
fn from_id(id: Id) -> Self {
|
||||
assert_eq!(0, id.as_u32());
|
||||
salsa_struct::Singleton
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,6 @@ pub mod plumbing {
|
|||
pub use crate::runtime::Stamp;
|
||||
pub use crate::runtime::StampedValue;
|
||||
pub use crate::salsa_struct::SalsaStructInDb;
|
||||
pub use crate::salsa_struct::Singleton;
|
||||
pub use crate::storage::views;
|
||||
pub use crate::storage::HasStorage;
|
||||
pub use crate::storage::IngredientCache;
|
||||
|
@ -95,11 +94,9 @@ pub mod plumbing {
|
|||
pub use salsa_macro_rules::maybe_clone;
|
||||
pub use salsa_macro_rules::maybe_cloned_ty;
|
||||
pub use salsa_macro_rules::setup_accumulator_impl;
|
||||
pub use salsa_macro_rules::setup_constant_fn;
|
||||
pub use salsa_macro_rules::setup_fn;
|
||||
pub use salsa_macro_rules::setup_input_struct;
|
||||
pub use salsa_macro_rules::setup_interned_fn;
|
||||
pub use salsa_macro_rules::setup_interned_struct;
|
||||
pub use salsa_macro_rules::setup_struct_fn;
|
||||
pub use salsa_macro_rules::setup_tracked_struct;
|
||||
pub use salsa_macro_rules::unexpected_cycle_recovery;
|
||||
|
||||
|
|
|
@ -4,13 +4,6 @@ pub trait SalsaStructInDb {
|
|||
fn register_dependent_fn(db: &dyn Database, index: IngredientIndex);
|
||||
}
|
||||
|
||||
/// A ZST that implements [`SalsaStructInDb`]
|
||||
///
|
||||
/// It is used for implementing "constant" tracked function
|
||||
/// (ones that only take a database as an argument).
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub struct Singleton;
|
||||
|
||||
impl SalsaStructInDb for Singleton {
|
||||
impl SalsaStructInDb for () {
|
||||
fn register_dependent_fn(_db: &dyn Database, _index: IngredientIndex) {}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue