mirror of
https://github.com/salsa-rs/salsa.git
synced 2024-10-23 04:46:35 +00:00
wip
This commit is contained in:
parent
afd7bcfa78
commit
7443277381
19 changed files with 113 additions and 126 deletions
|
@ -12,6 +12,7 @@
|
|||
//! from a submodule is to use multiple crates, hence the existence
|
||||
//! of this crate.
|
||||
|
||||
mod macro_if;
|
||||
mod maybe_backdate;
|
||||
mod maybe_clone;
|
||||
mod setup_accumulator_impl;
|
||||
|
|
9
components/salsa-macro-rules/src/macro_if.rs
Normal file
9
components/salsa-macro-rules/src/macro_if.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
#[macro_export]
|
||||
macro_rules! macro_if {
|
||||
(true => $($t:tt)*) => {
|
||||
$($t)*
|
||||
};
|
||||
|
||||
(false => $($t:tt)*) => {
|
||||
};
|
||||
}
|
|
@ -35,10 +35,11 @@ macro_rules! setup_input_struct {
|
|||
// Number of fields
|
||||
num_fields: $N:literal,
|
||||
|
||||
// Control customization: each path below either appears or doesn't.
|
||||
customized: [
|
||||
$($DebugTrait:path)?, // std::fmt::Debug
|
||||
],
|
||||
// If true, this is a singleton input.
|
||||
is_singleton: $is_singleton:tt,
|
||||
|
||||
// If true, generate a debug impl.
|
||||
generate_debug_impl: $generate_debug_impl: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
|
||||
|
@ -64,6 +65,7 @@ macro_rules! setup_input_struct {
|
|||
impl $zalsa_struct::Configuration for $Configuration {
|
||||
const DEBUG_NAME: &'static str = stringify!($Struct);
|
||||
const FIELD_DEBUG_NAMES: &'static [&'static str] = &[$(stringify!($field_id)),*];
|
||||
const IS_SINGLETON: bool = $is_singleton;
|
||||
|
||||
/// The input struct (which wraps an `Id`)
|
||||
type Struct = $Struct;
|
||||
|
@ -104,13 +106,13 @@ macro_rules! setup_input_struct {
|
|||
}
|
||||
}
|
||||
|
||||
$(
|
||||
impl $DebugTrait for $Struct {
|
||||
$zalsa::macro_if! { $generate_debug_impl =>
|
||||
impl std::fmt::Debug for $Struct {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
Self::default_debug_fmt(*self, f)
|
||||
}
|
||||
}
|
||||
)?
|
||||
}
|
||||
|
||||
impl $zalsa::SalsaStructInDb for $Struct {
|
||||
fn register_dependent_fn(_db: &dyn $zalsa::Database, _index: $zalsa::IngredientIndex) {
|
||||
|
@ -163,6 +165,25 @@ macro_rules! setup_input_struct {
|
|||
}
|
||||
)*
|
||||
|
||||
$zalsa::macro_if! { $is_singleton =>
|
||||
pub fn try_get<$Db>(db: &$Db) -> Option<Self>
|
||||
where
|
||||
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
|
||||
$Db: ?Sized + salsa::Database,
|
||||
{
|
||||
$Configuration::ingredient(db.as_salsa_database()).get_singleton_input()
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn get<$Db>(db: &$Db) -> Self
|
||||
where
|
||||
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
|
||||
$Db: ?Sized + salsa::Database,
|
||||
{
|
||||
Self::try_get(db).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// Default debug formatting for this struct (may be useful if you define your own `Debug` impl)
|
||||
pub fn default_debug_fmt(this: Self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
$zalsa::with_attached_database(|db| {
|
||||
|
|
|
@ -35,10 +35,8 @@ macro_rules! setup_interned_struct {
|
|||
// Number of fields
|
||||
num_fields: $N:literal,
|
||||
|
||||
// Control customization: each path below either appears or doesn't.
|
||||
customized: [
|
||||
$($DebugTrait:path)?, // std::fmt::Debug
|
||||
],
|
||||
// If true, generate a debug impl.
|
||||
generate_debug_impl: $generate_debug_impl: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
|
||||
|
@ -99,13 +97,13 @@ macro_rules! setup_interned_struct {
|
|||
|
||||
unsafe impl Sync for $Struct<'_> {}
|
||||
|
||||
$(
|
||||
impl $DebugTrait for $Struct<'_> {
|
||||
$zalsa::macro_if! { $generate_debug_impl =>
|
||||
impl std::fmt::Debug for $Struct<'_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
Self::default_debug_fmt(*self, f)
|
||||
}
|
||||
}
|
||||
)?
|
||||
}
|
||||
|
||||
impl $zalsa::SalsaStructInDb for $Struct<'_> {
|
||||
fn register_dependent_fn(_db: &dyn $zalsa::Database, _index: $zalsa::IngredientIndex) {
|
||||
|
|
|
@ -44,10 +44,8 @@ macro_rules! setup_tracked_struct {
|
|||
// Number of fields
|
||||
num_fields: $N:literal,
|
||||
|
||||
// Control customization: each path below either appears or doesn't.
|
||||
customized: [
|
||||
$($DebugTrait:path)?, // std::fmt::Debug
|
||||
],
|
||||
// If true, generate a debug impl.
|
||||
generate_debug_impl: $generate_debug_impl: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
|
||||
|
@ -167,13 +165,13 @@ macro_rules! setup_tracked_struct {
|
|||
|
||||
unsafe impl Sync for $Struct<'_> {}
|
||||
|
||||
$(
|
||||
impl $DebugTrait for $Struct<'_> {
|
||||
$zalsa::macro_if! { $generate_debug_impl =>
|
||||
impl std::fmt::Debug for $Struct<'_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
Self::default_debug_fmt(*self, f)
|
||||
}
|
||||
}
|
||||
)?
|
||||
}
|
||||
|
||||
impl<$db_lt> $Struct<$db_lt> {
|
||||
pub fn $new_fn<$Db>(db: &$db_lt $Db, $($field_id: $field_ty),*) -> Self
|
||||
|
|
|
@ -84,8 +84,8 @@ impl Macro {
|
|||
let field_setter_ids = salsa_struct.field_setter_ids();
|
||||
let field_options = salsa_struct.field_options();
|
||||
let field_tys = salsa_struct.field_tys();
|
||||
|
||||
let DebugTrait = salsa_struct.customized_debug_trait();
|
||||
let is_singleton = self.args.singleton.is_some();
|
||||
let generate_debug_impl = salsa_struct.generate_debug_impl();
|
||||
|
||||
let zalsa = self.hygiene.ident("zalsa");
|
||||
let zalsa_struct = self.hygiene.ident("zalsa_struct");
|
||||
|
@ -108,9 +108,8 @@ impl Macro {
|
|||
field_tys: [#(#field_tys),*],
|
||||
field_indices: [#(#field_indices),*],
|
||||
num_fields: #num_fields,
|
||||
customized: [
|
||||
#DebugTrait,
|
||||
],
|
||||
is_singleton: #is_singleton,
|
||||
generate_debug_impl: #generate_debug_impl,
|
||||
unused_names: [
|
||||
#zalsa,
|
||||
#zalsa_struct,
|
||||
|
|
|
@ -85,8 +85,7 @@ impl Macro {
|
|||
let field_getter_ids = salsa_struct.field_getter_ids();
|
||||
let field_options = salsa_struct.field_options();
|
||||
let field_tys = salsa_struct.field_tys();
|
||||
|
||||
let DebugTrait = salsa_struct.customized_debug_trait();
|
||||
let generate_debug_impl = salsa_struct.generate_debug_impl();
|
||||
|
||||
let zalsa = self.hygiene.ident("zalsa");
|
||||
let zalsa_struct = self.hygiene.ident("zalsa_struct");
|
||||
|
@ -109,9 +108,7 @@ impl Macro {
|
|||
field_tys: [#(#field_tys),*],
|
||||
field_indices: [#(#field_indices),*],
|
||||
num_fields: #num_fields,
|
||||
customized: [
|
||||
#DebugTrait,
|
||||
],
|
||||
generate_debug_impl: #generate_debug_impl,
|
||||
unused_names: [
|
||||
#zalsa,
|
||||
#zalsa_struct,
|
||||
|
|
|
@ -213,12 +213,8 @@ where
|
|||
.collect()
|
||||
}
|
||||
|
||||
pub fn customized_debug_trait(&self) -> TokenStream {
|
||||
if self.args.no_debug.is_some() {
|
||||
quote!()
|
||||
} else {
|
||||
quote!(std::fmt::Debug)
|
||||
}
|
||||
pub fn generate_debug_impl(&self) -> bool {
|
||||
self.args.no_debug.is_none()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -81,8 +81,7 @@ impl Macro {
|
|||
let num_fields = salsa_struct.num_fields();
|
||||
let field_options = salsa_struct.field_options();
|
||||
let field_tys = salsa_struct.field_tys();
|
||||
|
||||
let DebugTrait = salsa_struct.customized_debug_trait();
|
||||
let generate_debug_impl = salsa_struct.generate_debug_impl();
|
||||
|
||||
let zalsa = self.hygiene.ident("zalsa");
|
||||
let zalsa_struct = self.hygiene.ident("zalsa_struct");
|
||||
|
@ -108,9 +107,7 @@ impl Macro {
|
|||
id_field_indices: [#(#id_field_indices),*],
|
||||
field_options: [#(#field_options),*],
|
||||
num_fields: #num_fields,
|
||||
customized: [
|
||||
#DebugTrait,
|
||||
],
|
||||
generate_debug_impl: #generate_debug_impl,
|
||||
unused_names: [
|
||||
#zalsa,
|
||||
#zalsa_struct,
|
||||
|
|
25
src/input.rs
25
src/input.rs
|
@ -26,6 +26,7 @@ use crate::{
|
|||
pub trait Configuration: Any {
|
||||
const DEBUG_NAME: &'static str;
|
||||
const FIELD_DEBUG_NAMES: &'static [&'static str];
|
||||
const IS_SINGLETON: bool;
|
||||
|
||||
/// The input struct (which wraps an `Id`)
|
||||
type Struct: FromId + 'static + Send + Sync;
|
||||
|
@ -94,6 +95,11 @@ impl<C: Configuration> IngredientImpl<C> {
|
|||
}
|
||||
|
||||
pub fn new_input(&self, fields: C::Fields, stamps: C::Stamps) -> C::Struct {
|
||||
// If declared as a singleton, only allow a single instance
|
||||
if C::IS_SINGLETON && self.counter.load(Ordering::Relaxed) >= 1 {
|
||||
panic!("singleton struct may not be duplicated");
|
||||
}
|
||||
|
||||
let next_id = Id::from_u32(self.counter.fetch_add(1, Ordering::Relaxed));
|
||||
let value = Value {
|
||||
struct_ingredient_index: self.ingredient_index,
|
||||
|
@ -130,19 +136,12 @@ impl<C: Configuration> IngredientImpl<C> {
|
|||
setter(&mut r.fields)
|
||||
}
|
||||
|
||||
/// Creates a new singleton input.
|
||||
pub fn new_singleton_input(&self, _runtime: &Runtime) -> C::Struct {
|
||||
// when one exists already, panic
|
||||
if self.counter.load(Ordering::Relaxed) >= 1 {
|
||||
panic!("singleton struct may not be duplicated");
|
||||
}
|
||||
// fresh new ingredient
|
||||
self.counter.store(1, Ordering::Relaxed);
|
||||
C::Struct::from_id(Id::from_u32(0))
|
||||
}
|
||||
|
||||
/// Get the singleton input previously created.
|
||||
pub fn get_singleton_input(&self, _runtime: &Runtime) -> Option<C::Struct> {
|
||||
/// Get the singleton input previously created (if any).
|
||||
pub fn get_singleton_input(&self) -> Option<C::Struct> {
|
||||
assert!(
|
||||
C::IS_SINGLETON,
|
||||
"get_singleton_input invoked on a non-singleton"
|
||||
);
|
||||
(self.counter.load(Ordering::Relaxed) > 0).then(|| C::Struct::from_id(Id::from_u32(0)))
|
||||
}
|
||||
|
||||
|
|
|
@ -90,6 +90,7 @@ pub mod plumbing {
|
|||
pub use crate::update::helper::Dispatch as UpdateDispatch;
|
||||
pub use crate::update::helper::Fallback as UpdateFallback;
|
||||
|
||||
pub use salsa_macro_rules::macro_if;
|
||||
pub use salsa_macro_rules::maybe_backdate;
|
||||
pub use salsa_macro_rules::maybe_clone;
|
||||
pub use salsa_macro_rules::maybe_cloned_ty;
|
||||
|
|
|
@ -1,26 +1,20 @@
|
|||
//! Test that creating a tracked struct outside of a
|
||||
//! tracked function panics with an assert message.
|
||||
|
||||
#[salsa::jar(db = Db)]
|
||||
struct Jar(MyTracked<'_>);
|
||||
|
||||
trait Db: salsa::DbWithJar<Jar> {}
|
||||
|
||||
#[salsa::tracked]
|
||||
struct MyTracked<'db> {
|
||||
field: u32,
|
||||
}
|
||||
|
||||
#[salsa::db(Jar)]
|
||||
#[salsa::db]
|
||||
#[derive(Default)]
|
||||
struct Database {
|
||||
storage: salsa::Storage<Self>,
|
||||
}
|
||||
|
||||
#[salsa::db]
|
||||
impl salsa::Database for Database {}
|
||||
|
||||
impl Db for Database {}
|
||||
|
||||
#[test]
|
||||
#[should_panic(
|
||||
expected = "cannot create a tracked struct disambiguator outside of a tracked function"
|
||||
|
|
|
@ -3,33 +3,32 @@
|
|||
//! Singleton structs are created only once. Subsequent `get`s and `new`s after creation return the same `Id`.
|
||||
|
||||
use expect_test::expect;
|
||||
use salsa::DebugWithDb;
|
||||
mod common;
|
||||
use common::{HasLogger, Logger};
|
||||
|
||||
use salsa::Database as _;
|
||||
use test_log::test;
|
||||
|
||||
#[salsa::jar(db = Db)]
|
||||
struct Jar(MyInput);
|
||||
|
||||
trait Db: salsa::DbWithJar<Jar> + HasLogger {}
|
||||
#[salsa::db]
|
||||
trait Db: salsa::Database + HasLogger {}
|
||||
|
||||
#[salsa::input(singleton)]
|
||||
struct MyInput {
|
||||
field: u32,
|
||||
#[id]
|
||||
id_field: u16,
|
||||
}
|
||||
|
||||
#[salsa::db(Jar)]
|
||||
#[salsa::db]
|
||||
#[derive(Default)]
|
||||
struct Database {
|
||||
storage: salsa::Storage<Self>,
|
||||
logger: Logger,
|
||||
}
|
||||
|
||||
#[salsa::db]
|
||||
impl salsa::Database for Database {}
|
||||
|
||||
#[salsa::db]
|
||||
impl Db for Database {}
|
||||
|
||||
impl HasLogger for Database {
|
||||
|
@ -65,9 +64,10 @@ fn twice() {
|
|||
|
||||
#[test]
|
||||
fn debug() {
|
||||
let db = Database::default();
|
||||
let input = MyInput::new(&db, 3, 4);
|
||||
let actual = format!("{:?}", input.debug(&db));
|
||||
let expected = expect!["MyInput { [salsa id]: 0, field: 3, id_field: 4 }"];
|
||||
expected.assert_eq(&actual);
|
||||
Database::default().attach(|db| {
|
||||
let input = MyInput::new(db, 3, 4);
|
||||
let actual = format!("{:?}", input);
|
||||
let expected = expect!["MyInput { [salsa id]: 0, field: 3, id_field: 4 }"];
|
||||
expected.assert_eq(&actual);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2,28 +2,22 @@
|
|||
//! compiles and executes successfully.
|
||||
#![allow(warnings)]
|
||||
|
||||
#[salsa::jar(db = Db)]
|
||||
struct Jar(tracked_fn);
|
||||
|
||||
trait Db: salsa::DbWithJar<Jar> {}
|
||||
|
||||
#[salsa::tracked]
|
||||
fn tracked_fn(db: &dyn Db) -> u32 {
|
||||
fn tracked_fn(db: &dyn salsa::Database) -> u32 {
|
||||
44
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn execute() {
|
||||
#[salsa::db(Jar)]
|
||||
#[salsa::db]
|
||||
#[derive(Default)]
|
||||
struct Database {
|
||||
storage: salsa::Storage<Self>,
|
||||
}
|
||||
|
||||
#[salsa::db]
|
||||
impl salsa::Database for Database {}
|
||||
|
||||
impl Db for Database {}
|
||||
|
||||
let mut db = Database::default();
|
||||
assert_eq!(tracked_fn(&db), 44);
|
||||
}
|
||||
|
|
|
@ -2,33 +2,27 @@
|
|||
//! compiles and executes successfully.
|
||||
#![allow(warnings)]
|
||||
|
||||
#[salsa::jar(db = Db)]
|
||||
struct Jar(MyInput, tracked_fn);
|
||||
|
||||
trait Db: salsa::DbWithJar<Jar> {}
|
||||
|
||||
#[salsa::input]
|
||||
struct MyInput {
|
||||
field: u32,
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
fn tracked_fn(db: &dyn Db, input: MyInput) -> u32 {
|
||||
fn tracked_fn(db: &dyn salsa::Database, input: MyInput) -> u32 {
|
||||
input.field(db) * 2
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn execute() {
|
||||
#[salsa::db(Jar)]
|
||||
#[salsa::db]
|
||||
#[derive(Default)]
|
||||
struct Database {
|
||||
storage: salsa::Storage<Self>,
|
||||
}
|
||||
|
||||
#[salsa::db]
|
||||
impl salsa::Database for Database {}
|
||||
|
||||
impl Db for Database {}
|
||||
|
||||
let mut db = Database::default();
|
||||
let input = MyInput::new(&db, 22);
|
||||
assert_eq!(tracked_fn(&db, input), 44);
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
//! Test that a `tracked` fn on a `salsa::input`
|
||||
//! compiles and executes successfully.
|
||||
|
||||
#[salsa::jar(db = Db)]
|
||||
struct Jar(MyInput, MyTracked<'_>, tracked_fn);
|
||||
|
||||
trait Db: salsa::DbWithJar<Jar> {}
|
||||
|
||||
#[salsa::input]
|
||||
struct MyInput {
|
||||
field: u32,
|
||||
|
@ -17,20 +12,19 @@ struct MyTracked<'db> {
|
|||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
fn tracked_fn<'db>(db: &'db dyn Db, input: MyInput) -> MyTracked<'db> {
|
||||
fn tracked_fn<'db>(db: &'db dyn salsa::Database, input: MyInput) -> MyTracked<'db> {
|
||||
MyTracked::new(db, input.field(db) * 2)
|
||||
}
|
||||
|
||||
#[salsa::db(Jar)]
|
||||
#[salsa::db]
|
||||
#[derive(Default)]
|
||||
struct Database {
|
||||
storage: salsa::Storage<Self>,
|
||||
}
|
||||
|
||||
#[salsa::db]
|
||||
impl salsa::Database for Database {}
|
||||
|
||||
impl Db for Database {}
|
||||
|
||||
#[test]
|
||||
fn execute() {
|
||||
let db = Database::default();
|
||||
|
|
|
@ -2,11 +2,6 @@
|
|||
//! compiles and executes successfully.
|
||||
#![allow(warnings)]
|
||||
|
||||
#[salsa::jar(db = Db)]
|
||||
struct Jar(MyInput, MyTracked<'_>, tracked_fn, tracked_fn_extra);
|
||||
|
||||
trait Db: salsa::DbWithJar<Jar> {}
|
||||
|
||||
#[salsa::input]
|
||||
struct MyInput {
|
||||
field: u32,
|
||||
|
@ -18,7 +13,7 @@ struct MyTracked<'db> {
|
|||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
fn tracked_fn<'db>(db: &'db dyn Db, input: MyInput) -> MyTracked<'db> {
|
||||
fn tracked_fn<'db>(db: &'db dyn salsa::Database, input: MyInput) -> MyTracked<'db> {
|
||||
let t = MyTracked::new(db, input.field(db) * 2);
|
||||
if input.field(db) != 0 {
|
||||
tracked_fn_extra::specify(db, t, 2222);
|
||||
|
@ -26,21 +21,20 @@ fn tracked_fn<'db>(db: &'db dyn Db, input: MyInput) -> MyTracked<'db> {
|
|||
t
|
||||
}
|
||||
|
||||
#[salsa::tracked(jar = Jar, specify)]
|
||||
fn tracked_fn_extra<'db>(_db: &'db dyn Db, _input: MyTracked<'db>) -> u32 {
|
||||
#[salsa::tracked(specify)]
|
||||
fn tracked_fn_extra<'db>(_db: &'db dyn salsa::Database, _input: MyTracked<'db>) -> u32 {
|
||||
0
|
||||
}
|
||||
|
||||
#[salsa::db(Jar)]
|
||||
#[salsa::db]
|
||||
#[derive(Default)]
|
||||
struct Database {
|
||||
storage: salsa::Storage<Self>,
|
||||
}
|
||||
|
||||
#[salsa::db]
|
||||
impl salsa::Database for Database {}
|
||||
|
||||
impl Db for Database {}
|
||||
|
||||
#[test]
|
||||
fn execute_when_specified() {
|
||||
let mut db = Database::default();
|
||||
|
|
|
@ -4,12 +4,11 @@
|
|||
use expect_test::expect;
|
||||
mod common;
|
||||
use common::{HasLogger, Logger};
|
||||
use salsa::Setter;
|
||||
use test_log::test;
|
||||
|
||||
#[salsa::jar(db = Db)]
|
||||
struct Jar(MyInput, MyTracked<'_>, final_result, intermediate_result);
|
||||
|
||||
trait Db: salsa::DbWithJar<Jar> + HasLogger {}
|
||||
#[salsa::db]
|
||||
trait Db: salsa::Database + HasLogger {}
|
||||
|
||||
#[salsa::input]
|
||||
struct MyInput {
|
||||
|
@ -35,15 +34,17 @@ fn intermediate_result<'db>(db: &'db dyn Db, input: MyInput) -> MyTracked<'db> {
|
|||
tracked
|
||||
}
|
||||
|
||||
#[salsa::db(Jar)]
|
||||
#[salsa::db]
|
||||
#[derive(Default)]
|
||||
struct Database {
|
||||
storage: salsa::Storage<Self>,
|
||||
logger: Logger,
|
||||
}
|
||||
|
||||
#[salsa::db]
|
||||
impl salsa::Database for Database {}
|
||||
|
||||
#[salsa::db]
|
||||
impl Db for Database {}
|
||||
|
||||
impl HasLogger for Database {
|
||||
|
|
|
@ -3,10 +3,8 @@ use salsa::{Database as SalsaDatabase, DebugWithDb};
|
|||
mod common;
|
||||
use common::{HasLogger, Logger};
|
||||
|
||||
#[salsa::jar(db = Db)]
|
||||
struct Jar(MyInput, MyTracked<'_>, tracked_fn, tracked_fn_extra);
|
||||
|
||||
trait Db: salsa::DbWithJar<Jar> + HasLogger {}
|
||||
#[salsa::db]
|
||||
trait Db: salsa::Database + HasLogger {}
|
||||
|
||||
#[salsa::input]
|
||||
struct MyInput {
|
||||
|
@ -20,27 +18,29 @@ struct MyTracked<'db> {
|
|||
|
||||
#[salsa::tracked]
|
||||
fn tracked_fn<'db>(db: &'db dyn Db, input: MyInput) -> u32 {
|
||||
db.push_log(format!("tracked_fn({:?})", input.debug(db)));
|
||||
db.push_log(format!("tracked_fn({input:?})"));
|
||||
let t = MyTracked::new(db, input.field(db) * 2);
|
||||
tracked_fn_extra::specify(db, t, 2222);
|
||||
tracked_fn_extra(db, t)
|
||||
}
|
||||
|
||||
#[salsa::tracked(jar = Jar, specify)]
|
||||
#[salsa::tracked(specify)]
|
||||
fn tracked_fn_extra<'db>(db: &dyn Db, input: MyTracked<'db>) -> u32 {
|
||||
db.push_log(format!("tracked_fn_extra({:?})", input.debug(db)));
|
||||
db.push_log(format!("tracked_fn_extra({input:?})"));
|
||||
0
|
||||
}
|
||||
|
||||
#[salsa::db(Jar)]
|
||||
#[salsa::db]
|
||||
#[derive(Default)]
|
||||
struct Database {
|
||||
storage: salsa::Storage<Self>,
|
||||
logger: Logger,
|
||||
}
|
||||
|
||||
#[salsa::db]
|
||||
impl salsa::Database for Database {}
|
||||
|
||||
#[salsa::db]
|
||||
impl Db for Database {}
|
||||
|
||||
impl HasLogger for Database {
|
||||
|
|
Loading…
Reference in a new issue