From 44a8a2f41c90c474525869590a21df4fe06b781c Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 27 Apr 2024 10:33:54 -0400 Subject: [PATCH] make fn input/value a GAT --- .../salsa-2022-macros/src/configuration.rs | 14 ++--- components/salsa-2022-macros/src/lib.rs | 18 ++++-- .../salsa-2022-macros/src/tracked_fn.rs | 4 +- components/salsa-2022/src/function.rs | 35 +++++------ .../salsa-2022/src/function/accumulated.rs | 2 +- .../salsa-2022/src/function/backdate.rs | 4 +- components/salsa-2022/src/function/delete.rs | 27 ++++++++- .../salsa-2022/src/function/diff_outputs.rs | 2 +- components/salsa-2022/src/function/execute.rs | 10 ++-- components/salsa-2022/src/function/fetch.rs | 20 +++++-- .../src/function/maybe_changed_after.rs | 17 ++++-- components/salsa-2022/src/function/memo.rs | 59 ++++++++++++++----- components/salsa-2022/src/function/specify.rs | 12 ++-- components/salsa-2022/src/function/store.rs | 6 +- ...ot-work-if-the-key-is-a-salsa-input.stderr | 6 +- ...work-if-the-key-is-a-salsa-interned.stderr | 6 +- 16 files changed, 161 insertions(+), 81 deletions(-) diff --git a/components/salsa-2022-macros/src/configuration.rs b/components/salsa-2022-macros/src/configuration.rs index 7b79e51a..02276aaf 100644 --- a/components/salsa-2022-macros/src/configuration.rs +++ b/components/salsa-2022-macros/src/configuration.rs @@ -25,8 +25,8 @@ impl Configuration { impl salsa::function::Configuration for #self_ty { type Jar = #jar_ty; type SalsaStruct = #salsa_struct_ty; - type Input = #input_ty; - type Value = #value_ty; + type Input<'db> = #input_ty; + type Value<'db> = #value_ty; const CYCLE_STRATEGY: salsa::cycle::CycleRecoveryStrategy = #cycle_strategy; #backdate_fn #execute_fn @@ -59,13 +59,13 @@ impl quote::ToTokens for CycleRecoveryStrategy { pub(crate) fn should_backdate_value_fn(should_backdate: bool) -> syn::ImplItemMethod { if should_backdate { parse_quote! { - fn should_backdate_value(v1: &Self::Value, v2: &Self::Value) -> bool { + fn should_backdate_value(v1: &Self::Value<'_>, v2: &Self::Value<'_>) -> bool { salsa::function::should_backdate_value(v1, v2) } } } else { parse_quote! { - fn should_backdate_value(_v1: &Self::Value, _v2: &Self::Value) -> bool { + fn should_backdate_value(_v1: &Self::Value<'_>, _v2: &Self::Value<'_>) -> bool { false } } @@ -76,11 +76,11 @@ pub(crate) fn should_backdate_value_fn(should_backdate: bool) -> syn::ImplItemMe /// the cycle recovery is panic. pub(crate) fn panic_cycle_recovery_fn() -> syn::ImplItemMethod { parse_quote! { - fn recover_from_cycle( - _db: &salsa::function::DynDb, + fn recover_from_cycle<'db>( + _db: &'db salsa::function::DynDb<'db, Self>, _cycle: &salsa::Cycle, _key: salsa::Id, - ) -> Self::Value { + ) -> Self::Value<'db> { panic!() } } diff --git a/components/salsa-2022-macros/src/lib.rs b/components/salsa-2022-macros/src/lib.rs index 45b31e67..febac410 100644 --- a/components/salsa-2022-macros/src/lib.rs +++ b/components/salsa-2022-macros/src/lib.rs @@ -11,17 +11,23 @@ use proc_macro::TokenStream; macro_rules! parse_quote { ($($inp:tt)*) => { - syn::parse2(quote!{$($inp)*}).unwrap_or_else(|err| { - panic!("failed to parse at {}:{}:{}: {}", file!(), line!(), column!(), err) - }) + { + let tt = quote!{$($inp)*}; + syn::parse2(tt.clone()).unwrap_or_else(|err| { + panic!("failed to parse `{}` at {}:{}:{}: {}", tt, file!(), line!(), column!(), err) + }) + } } } macro_rules! parse_quote_spanned { ($($inp:tt)*) => { - syn::parse2(quote_spanned!{$($inp)*}).unwrap_or_else(|err| { - panic!("failed to parse at {}:{}:{}: {}", file!(), line!(), column!(), err) - }) + { + let tt = quote_spanned!{$($inp)*}; + syn::parse2(tt.clone()).unwrap_or_else(|err| { + panic!("failed to parse `{}` at {}:{}:{}: {}", tt, file!(), line!(), column!(), err) + }) + } } } diff --git a/components/salsa-2022-macros/src/tracked_fn.rs b/components/salsa-2022-macros/src/tracked_fn.rs index 819b662b..e7a03ccb 100644 --- a/components/salsa-2022-macros/src/tracked_fn.rs +++ b/components/salsa-2022-macros/src/tracked_fn.rs @@ -391,7 +391,7 @@ fn fn_configuration(args: &FnArgs, item_fn: &syn::ItemFn) -> Configuration { let cycle_strategy = CycleRecoveryStrategy::Fallback; let cycle_fullback = parse_quote! { - fn recover_from_cycle(__db: &salsa::function::DynDb, __cycle: &salsa::Cycle, __id: salsa::Id) -> Self::Value { + fn recover_from_cycle<'db>(__db: &'db salsa::function::DynDb<'db, Self>, __cycle: &salsa::Cycle, __id: salsa::Id) -> Self::Value<'db> { let (__jar, __runtime) = <_ as salsa::storage::HasJar<#jar_ty>>::jar(__db); let __ingredients = <_ as salsa::storage::HasIngredientsFor<#fn_ty>>::ingredient(__jar); @@ -422,7 +422,7 @@ fn fn_configuration(args: &FnArgs, item_fn: &syn::ItemFn) -> Configuration { // keys and then (b) invokes the function itself (which we embed within). let indices = (0..item_fn.sig.inputs.len() - 1).map(Literal::usize_unsuffixed); let execute_fn = parse_quote! { - fn execute(__db: &salsa::function::DynDb, __id: salsa::Id) -> Self::Value { + fn execute<'db>(__db: &'db salsa::function::DynDb<'db, Self>, __id: salsa::Id) -> Self::Value<'db> { #inner_fn let (__jar, __runtime) = <_ as salsa::storage::HasJar<#jar_ty>>::jar(__db); diff --git a/components/salsa-2022/src/function.rs b/components/salsa-2022/src/function.rs index 852577a6..469235a8 100644 --- a/components/salsa-2022/src/function.rs +++ b/components/salsa-2022/src/function.rs @@ -1,7 +1,6 @@ use std::{fmt, sync::Arc}; -use arc_swap::ArcSwap; -use crossbeam::{atomic::AtomicCell, queue::SegQueue}; +use crossbeam::atomic::AtomicCell; use crate::{ cycle::CycleRecoveryStrategy, @@ -13,6 +12,8 @@ use crate::{ Cycle, DbWithJar, Event, EventKind, Id, Revision, }; +use self::delete::DeletedEntries; + use super::{ingredient::Ingredient, routes::IngredientIndex, AsId}; mod accumulated; @@ -45,7 +46,7 @@ pub struct FunctionIngredient { index: IngredientIndex, /// Tracks the keys for which we have memoized values. - memo_map: memo::MemoMap, + memo_map: memo::MemoMap, /// Tracks the keys that are currently being processed; used to coordinate between /// worker threads. @@ -66,7 +67,7 @@ pub struct FunctionIngredient { /// current revision: you would be right, but we are being defensive, because /// we don't know that we can trust the database to give us the same runtime /// everytime and so forth. - deleted_entries: SegQueue>>, + deleted_entries: DeletedEntries, /// Set to true once we invoke `register_dependent_fn` for `C::SalsaStruct`. /// Prevents us from registering more than once. @@ -84,10 +85,10 @@ pub trait Configuration { type SalsaStruct: for<'db> SalsaStructInDb>; /// The input to the function - type Input; + type Input<'db>; /// The value computed by the function. - type Value: fmt::Debug; + type Value<'db>: fmt::Debug; /// Determines whether this function can recover from being a participant in a cycle /// (and, if so, how). @@ -99,19 +100,19 @@ pub trait Configuration { /// even though it was recomputed). /// /// This invokes user's code in form of the `Eq` impl. - fn should_backdate_value(old_value: &Self::Value, new_value: &Self::Value) -> bool; + fn should_backdate_value(old_value: &Self::Value<'_>, new_value: &Self::Value<'_>) -> bool; /// Invoked when we need to compute the value for the given key, either because we've never /// computed it before or because the old one relied on inputs that have changed. /// /// This invokes the function the user wrote. - fn execute(db: &DynDb, key: Id) -> Self::Value; + fn execute<'db>(db: &'db DynDb, key: Id) -> Self::Value<'db>; /// If the cycle strategy is `Recover`, then invoked when `key` is a participant /// in a cycle to find out what value it should have. /// /// This invokes the recovery function given by the user. - fn recover_from_cycle(db: &DynDb, cycle: &Cycle, key: Id) -> Self::Value; + fn recover_from_cycle<'db>(db: &'db DynDb, cycle: &Cycle, key: Id) -> Self::Value<'db>; } /// True if `old_value == new_value`. Invoked by the generated @@ -163,18 +164,18 @@ where /// only cleared with `&mut self`. unsafe fn extend_memo_lifetime<'this, 'memo>( &'this self, - memo: &'memo memo::Memo, - ) -> Option<&'this C::Value> { - let memo_value: Option<&'memo C::Value> = memo.value.as_ref(); + memo: &'memo memo::Memo>, + ) -> Option<&'this C::Value<'this>> { + let memo_value: Option<&'memo C::Value<'this>> = memo.value.as_ref(); std::mem::transmute(memo_value) } - fn insert_memo( - &self, - db: &DynDb<'_, C>, + fn insert_memo<'db>( + &'db self, + db: &'db DynDb<'db, C>, key: Id, - memo: memo::Memo, - ) -> Option<&C::Value> { + memo: memo::Memo>, + ) -> Option<&C::Value<'db>> { self.register(db); let memo = Arc::new(memo); let value = unsafe { diff --git a/components/salsa-2022/src/function/accumulated.rs b/components/salsa-2022/src/function/accumulated.rs index 66405892..ad4a95d4 100644 --- a/components/salsa-2022/src/function/accumulated.rs +++ b/components/salsa-2022/src/function/accumulated.rs @@ -14,7 +14,7 @@ where { /// Returns all the values accumulated into `accumulator` by this query and its /// transitive inputs. - pub fn accumulated<'db, A>(&self, db: &DynDb<'db, C>, key: Id) -> Vec + pub fn accumulated<'db, A>(&'db self, db: &'db DynDb<'db, C>, key: Id) -> Vec where DynDb<'db, C>: HasJar, A: Accumulator, diff --git a/components/salsa-2022/src/function/backdate.rs b/components/salsa-2022/src/function/backdate.rs index 9695eebf..5d9b4ece 100644 --- a/components/salsa-2022/src/function/backdate.rs +++ b/components/salsa-2022/src/function/backdate.rs @@ -11,9 +11,9 @@ where /// on an old memo when a new memo has been produced to check whether there have been changed. pub(super) fn backdate_if_appropriate( &self, - old_memo: &Memo, + old_memo: &Memo>, revisions: &mut QueryRevisions, - value: &C::Value, + value: &C::Value<'_>, ) { if let Some(old_value) = &old_memo.value { // Careful: if the value became less durable than it diff --git a/components/salsa-2022/src/function/delete.rs b/components/salsa-2022/src/function/delete.rs index 66f83182..0a4039d7 100644 --- a/components/salsa-2022/src/function/delete.rs +++ b/components/salsa-2022/src/function/delete.rs @@ -1,6 +1,9 @@ +use arc_swap::ArcSwap; +use crossbeam::queue::SegQueue; + use crate::{runtime::local_state::QueryOrigin, Id}; -use super::{Configuration, FunctionIngredient}; +use super::{memo, Configuration, FunctionIngredient}; impl FunctionIngredient where @@ -18,3 +21,25 @@ where } } } + +/// Stores the list of memos that have been deleted so they can be freed +/// once the next revision starts. See the comment on the field +/// `deleted_entries` of [`FunctionIngredient`][] for more details. +pub(super) struct DeletedEntries { + seg_queue: SegQueue>>>, +} + +impl Default for DeletedEntries { + fn default() -> Self { + Self { + seg_queue: Default::default(), + } + } +} + +impl DeletedEntries { + pub(super) fn push<'db>(&'db self, memo: ArcSwap>>) { + let memo = unsafe { std::mem::transmute(memo) }; + self.seg_queue.push(memo); + } +} diff --git a/components/salsa-2022/src/function/diff_outputs.rs b/components/salsa-2022/src/function/diff_outputs.rs index c8f8fc63..8a93a056 100644 --- a/components/salsa-2022/src/function/diff_outputs.rs +++ b/components/salsa-2022/src/function/diff_outputs.rs @@ -15,7 +15,7 @@ where &self, db: &DynDb<'_, C>, key: DatabaseKeyIndex, - old_memo: &Memo, + old_memo: &Memo>, revisions: &QueryRevisions, ) { // Iterate over the outputs of the `old_memo` and put them into a hashset diff --git a/components/salsa-2022/src/function/execute.rs b/components/salsa-2022/src/function/execute.rs index 32b940df..b79700e1 100644 --- a/components/salsa-2022/src/function/execute.rs +++ b/components/salsa-2022/src/function/execute.rs @@ -22,12 +22,12 @@ where /// * `db`, the database. /// * `active_query`, the active stack frame for the query to execute. /// * `opt_old_memo`, the older memo, if any existed. Used for backdated. - pub(super) fn execute( - &self, - db: &DynDb, + pub(super) fn execute<'db>( + &'db self, + db: &'db DynDb<'db, C>, active_query: ActiveQueryGuard<'_>, - opt_old_memo: Option>>, - ) -> StampedValue<&C::Value> { + opt_old_memo: Option>>>, + ) -> StampedValue<&C::Value<'db>> { let runtime = db.runtime(); let revision_now = runtime.current_revision(); let database_key_index = active_query.database_key_index; diff --git a/components/salsa-2022/src/function/fetch.rs b/components/salsa-2022/src/function/fetch.rs index 223fa0cf..55aa0eae 100644 --- a/components/salsa-2022/src/function/fetch.rs +++ b/components/salsa-2022/src/function/fetch.rs @@ -8,7 +8,7 @@ impl FunctionIngredient where C: Configuration, { - pub fn fetch(&self, db: &DynDb, key: Id) -> &C::Value { + pub fn fetch<'db>(&'db self, db: &'db DynDb<'db, C>, key: Id) -> &C::Value<'db> { let runtime = db.runtime(); runtime.unwind_if_revision_cancelled(db); @@ -33,7 +33,11 @@ where } #[inline] - fn compute_value(&self, db: &DynDb, key: Id) -> StampedValue<&C::Value> { + fn compute_value<'db>( + &'db self, + db: &'db DynDb<'db, C>, + key: Id, + ) -> StampedValue<&'db C::Value<'db>> { loop { if let Some(value) = self.fetch_hot(db, key).or_else(|| self.fetch_cold(db, key)) { return value; @@ -42,7 +46,11 @@ where } #[inline] - fn fetch_hot(&self, db: &DynDb, key: Id) -> Option> { + fn fetch_hot<'db>( + &'db self, + db: &'db DynDb<'db, C>, + key: Id, + ) -> Option>> { let memo_guard = self.memo_map.get(key); if let Some(memo) = &memo_guard { if memo.value.is_some() { @@ -59,7 +67,11 @@ where None } - fn fetch_cold(&self, db: &DynDb, key: Id) -> Option> { + fn fetch_cold<'db>( + &'db self, + db: &'db DynDb<'db, C>, + key: Id, + ) -> Option>> { let runtime = db.runtime(); let database_key_index = self.database_key_index(key); diff --git a/components/salsa-2022/src/function/maybe_changed_after.rs b/components/salsa-2022/src/function/maybe_changed_after.rs index 6f8a8c6d..c2a7cd75 100644 --- a/components/salsa-2022/src/function/maybe_changed_after.rs +++ b/components/salsa-2022/src/function/maybe_changed_after.rs @@ -18,7 +18,12 @@ impl FunctionIngredient where C: Configuration, { - pub(super) fn maybe_changed_after(&self, db: &DynDb, key: Id, revision: Revision) -> bool { + pub(super) fn maybe_changed_after<'db>( + &'db self, + db: &'db DynDb<'db, C>, + key: Id, + revision: Revision, + ) -> bool { let runtime = db.runtime(); runtime.unwind_if_revision_cancelled(db); @@ -50,9 +55,9 @@ where } } - fn maybe_changed_after_cold( - &self, - db: &DynDb, + fn maybe_changed_after_cold<'db>( + &'db self, + db: &'db DynDb<'db, C>, key_index: Id, revision: Revision, ) -> Option { @@ -104,7 +109,7 @@ where db: &DynDb, runtime: &Runtime, database_key_index: DatabaseKeyIndex, - memo: &Memo, + memo: &Memo>, ) -> bool { let verified_at = memo.verified_at.load(); let revision_now = runtime.current_revision(); @@ -142,7 +147,7 @@ where pub(super) fn deep_verify_memo( &self, db: &DynDb, - old_memo: &Memo, + old_memo: &Memo>, active_query: &ActiveQueryGuard<'_>, ) -> bool { let runtime = db.runtime(); diff --git a/components/salsa-2022/src/function/memo.rs b/components/salsa-2022/src/function/memo.rs index 20002949..45182b6e 100644 --- a/components/salsa-2022/src/function/memo.rs +++ b/components/salsa-2022/src/function/memo.rs @@ -4,18 +4,23 @@ use arc_swap::{ArcSwap, Guard}; use crossbeam_utils::atomic::AtomicCell; use crate::{ - hash::FxDashMap, key::DatabaseKeyIndex, runtime::local_state::QueryRevisions, AsId, Event, - EventKind, Revision, Runtime, + hash::FxDashMap, key::DatabaseKeyIndex, runtime::local_state::QueryRevisions, Event, EventKind, + Id, Revision, Runtime, }; +use super::Configuration; + /// The memo map maps from a key of type `K` to the memoized value for that `K`. /// The memoized value is a `Memo` which contains, in addition to the value `V`, /// dependency information. -pub(super) struct MemoMap { - map: FxDashMap>>, +pub(super) struct MemoMap { + map: FxDashMap>, } -impl Default for MemoMap { +#[allow(type_alias_bounds)] +type ArcMemo<'lt, C: Configuration> = ArcSwap::Value<'lt>>>; + +impl Default for MemoMap { fn default() -> Self { Self { map: Default::default(), @@ -23,30 +28,56 @@ impl Default for MemoMap { } } -impl MemoMap { +impl MemoMap { + /// Memos have to be stored internally using `'static` as the database lifetime. + /// This (unsafe) function call converts from something tied to self to static. + /// Values transmuted this way have to be transmuted back to being tied to self + /// when they are returned to the user. + unsafe fn to_static<'db>(&'db self, value: ArcMemo<'db, C>) -> ArcMemo<'static, C> { + unsafe { std::mem::transmute(value) } + } + + /// Convert from an internal memo (which uses statis) to one tied to self + /// so it can be publicly released. + unsafe fn to_self<'db>(&'db self, value: ArcMemo<'static, C>) -> ArcMemo<'db, C> { + unsafe { std::mem::transmute(value) } + } /// Inserts the memo for the given key; (atomically) overwrites any previously existing memo.- #[must_use] - pub(super) fn insert(&self, key: K, memo: Arc>) -> Option>> { - self.map.insert(key, ArcSwap::from(memo)) + pub(super) fn insert<'db>( + &'db self, + key: Id, + memo: Arc>>, + ) -> Option>>> { + unsafe { + let value = ArcSwap::from(memo); + let old_value = self.map.insert(key, self.to_static(value))?; + Some(self.to_self(old_value)) + } } /// Removes any existing memo for the given key. #[must_use] - pub(super) fn remove(&self, key: K) -> Option>> { - self.map.remove(&key).map(|o| o.1) + pub(super) fn remove<'db>(&'db self, key: Id) -> Option>>> { + unsafe { self.map.remove(&key).map(|o| self.to_self(o.1)) } } /// Loads the current memo for `key_index`. This does not hold any sort of /// lock on the `memo_map` once it returns, so this memo could immediately /// become outdated if other threads store into the `memo_map`. - pub(super) fn get(&self, key: K) -> Option>>> { - self.map.get(&key).map(|v| v.load()) + pub(super) fn get<'db>(&self, key: Id) -> Option>>>> { + self.map.get(&key).map(|v| unsafe { + std::mem::transmute::< + Guard>>>, + Guard>>>, + >(v.load()) + }) } /// Evicts the existing memo for the given key, replacing it /// with an equivalent memo that has no value. If the memo is untracked, BaseInput, /// or has values assigned as output of another query, this has no effect. - pub(super) fn evict(&self, key: K) { + pub(super) fn evict(&self, key: Id) { use crate::runtime::local_state::QueryOrigin; use dashmap::mapref::entry::Entry::*; @@ -64,7 +95,7 @@ impl MemoMap { QueryOrigin::Derived(_) => { let memo_evicted = Arc::new(Memo::new( - None::, + None::>, memo.verified_at.load(), memo.revisions.clone(), )); diff --git a/components/salsa-2022/src/function/specify.rs b/components/salsa-2022/src/function/specify.rs index 9916deba..3009635c 100644 --- a/components/salsa-2022/src/function/specify.rs +++ b/components/salsa-2022/src/function/specify.rs @@ -18,13 +18,13 @@ where /// This is a way to imperatively set the value of a function. /// It only works if the key is a tracked struct created in the current query. fn specify<'db>( - &self, + &'db self, db: &'db DynDb<'db, C>, key: Id, - value: C::Value, + value: C::Value<'db>, origin: impl Fn(DatabaseKeyIndex) -> QueryOrigin, ) where - C::Input: TrackedStructInDb>, + C::Input<'db>: TrackedStructInDb>, { let runtime = db.runtime(); @@ -45,7 +45,7 @@ where // * Q4 invokes Q2 and then Q1 // // Now, if We invoke Q3 first, We get one result for Q2, but if We invoke Q4 first, We get a different value. That's no good. - let database_key_index = ::database_key_index(db, key); + let database_key_index = >::database_key_index(db, key); let dependency_index = database_key_index.into(); if !runtime.is_output_of_active_query(dependency_index) { panic!("can only use `specfiy` on entities created during current query"); @@ -94,9 +94,9 @@ where /// Specify the value for `key` *and* record that we did so. /// Used for explicit calls to `specify`, but not needed for pre-declared tracked struct fields. - pub fn specify_and_record<'db>(&self, db: &'db DynDb<'db, C>, key: Id, value: C::Value) + pub fn specify_and_record<'db>(&'db self, db: &'db DynDb<'db, C>, key: Id, value: C::Value<'db>) where - C::Input: TrackedStructInDb>, + C::Input<'db>: TrackedStructInDb>, { self.specify(db, key, value, |database_key_index| { QueryOrigin::Assigned(database_key_index) diff --git a/components/salsa-2022/src/function/store.rs b/components/salsa-2022/src/function/store.rs index f09fca00..c0d17e50 100644 --- a/components/salsa-2022/src/function/store.rs +++ b/components/salsa-2022/src/function/store.rs @@ -14,11 +14,11 @@ impl FunctionIngredient where C: Configuration, { - pub fn store( - &mut self, + pub fn store<'db>( + &'db mut self, runtime: &mut Runtime, key: Id, - value: C::Value, + value: C::Value<'db>, durability: Durability, ) { let revision = runtime.current_revision(); diff --git a/salsa-2022-tests/tests/compile-fail/specify-does-not-work-if-the-key-is-a-salsa-input.stderr b/salsa-2022-tests/tests/compile-fail/specify-does-not-work-if-the-key-is-a-salsa-input.stderr index 60fb5631..9553bb0e 100644 --- a/salsa-2022-tests/tests/compile-fail/specify-does-not-work-if-the-key-is-a-salsa-input.stderr +++ b/salsa-2022-tests/tests/compile-fail/specify-does-not-work-if-the-key-is-a-salsa-input.stderr @@ -8,9 +8,9 @@ error[E0277]: the trait bound `MyInput: TrackedStructInDb` is not satisf note: required by a bound in `function::specify::>::specify_and_record` --> $WORKSPACE/components/salsa-2022/src/function/specify.rs | - | pub fn specify_and_record<'db>(&self, db: &'db DynDb<'db, C>, key: Id, value: C::Value) + | pub fn specify_and_record<'db>(&'db self, db: &'db DynDb<'db, C>, key: Id, value: C::Value<'db>) | ------------------ required by a bound in this associated function | where - | C::Input: TrackedStructInDb>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `function::specify::>::specify_and_record` + | C::Input<'db>: TrackedStructInDb>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `function::specify::>::specify_and_record` = note: this error originates in the attribute macro `salsa::tracked` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/salsa-2022-tests/tests/compile-fail/specify-does-not-work-if-the-key-is-a-salsa-interned.stderr b/salsa-2022-tests/tests/compile-fail/specify-does-not-work-if-the-key-is-a-salsa-interned.stderr index a6afbf0a..1b506438 100644 --- a/salsa-2022-tests/tests/compile-fail/specify-does-not-work-if-the-key-is-a-salsa-interned.stderr +++ b/salsa-2022-tests/tests/compile-fail/specify-does-not-work-if-the-key-is-a-salsa-interned.stderr @@ -8,9 +8,9 @@ error[E0277]: the trait bound `MyInterned: TrackedStructInDb` is not sat note: required by a bound in `function::specify::>::specify_and_record` --> $WORKSPACE/components/salsa-2022/src/function/specify.rs | - | pub fn specify_and_record<'db>(&self, db: &'db DynDb<'db, C>, key: Id, value: C::Value) + | pub fn specify_and_record<'db>(&'db self, db: &'db DynDb<'db, C>, key: Id, value: C::Value<'db>) | ------------------ required by a bound in this associated function | where - | C::Input: TrackedStructInDb>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `function::specify::>::specify_and_record` + | C::Input<'db>: TrackedStructInDb>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `function::specify::>::specify_and_record` = note: this error originates in the attribute macro `salsa::tracked` (in Nightly builds, run with -Z macro-backtrace for more info)