Skip to content

Commit 523d4c8

Browse files
committed
Do manual trait upcasting instead of downcasting
1 parent 8b6d12b commit 523d4c8

26 files changed

+376
-258
lines changed

components/salsa-macro-rules/src/setup_input_struct.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,7 @@ macro_rules! setup_input_struct {
118118
}
119119
}
120120

121-
pub fn ingredient_mut(db: &mut dyn $zalsa::Database) -> (&mut $zalsa_struct::IngredientImpl<Self>, &mut $zalsa::Runtime) {
122-
let zalsa_mut = db.zalsa_mut();
121+
pub fn ingredient_mut(zalsa_mut: &mut $zalsa::Zalsa) -> (&mut $zalsa_struct::IngredientImpl<Self>, &mut $zalsa::Runtime) {
123122
zalsa_mut.new_revision();
124123
let index = zalsa_mut.lookup_jar_by_type::<$zalsa_struct::JarImpl<$Configuration>>();
125124
let (ingredient, runtime) = zalsa_mut.lookup_ingredient_mut(index);
@@ -208,8 +207,10 @@ macro_rules! setup_input_struct {
208207
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
209208
$Db: ?Sized + $zalsa::Database,
210209
{
211-
let fields = $Configuration::ingredient_(db.zalsa()).field(
212-
db.as_dyn_database(),
210+
let (zalsa, zalsa_local) = db.zalsas();
211+
let fields = $Configuration::ingredient_(zalsa).field(
212+
zalsa,
213+
zalsa_local,
213214
self,
214215
$field_index,
215216
);
@@ -228,7 +229,8 @@ macro_rules! setup_input_struct {
228229
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
229230
$Db: ?Sized + $zalsa::Database,
230231
{
231-
let (ingredient, revision) = $Configuration::ingredient_mut(db.as_dyn_database_mut());
232+
let zalsa = db.zalsa_mut();
233+
let (ingredient, revision) = $Configuration::ingredient_mut(zalsa);
232234
$zalsa::input::SetterImpl::new(
233235
revision,
234236
self,
@@ -267,7 +269,8 @@ macro_rules! setup_input_struct {
267269
$(for<'__trivial_bounds> $field_ty: std::fmt::Debug),*
268270
{
269271
$zalsa::with_attached_database(|db| {
270-
let fields = $Configuration::ingredient(db).leak_fields(db, this);
272+
let zalsa = db.zalsa();
273+
let fields = $Configuration::ingredient_(zalsa).leak_fields(zalsa, this);
271274
let mut f = f.debug_struct(stringify!($Struct));
272275
let f = f.field("[salsa id]", &$zalsa::AsId::as_id(&this));
273276
$(
@@ -296,11 +299,11 @@ macro_rules! setup_input_struct {
296299
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
297300
$Db: ?Sized + salsa::Database
298301
{
299-
let zalsa = db.zalsa();
302+
let (zalsa, zalsa_local) = db.zalsas();
300303
let current_revision = zalsa.current_revision();
301304
let ingredient = $Configuration::ingredient_(zalsa);
302305
let (fields, revision, durabilities) = builder::builder_into_inner(self, current_revision);
303-
ingredient.new_input(db.as_dyn_database(), fields, revision, durabilities)
306+
ingredient.new_input(zalsa, zalsa_local, fields, revision, durabilities)
304307
}
305308
}
306309

components/salsa-macro-rules/src/setup_interned_struct.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -149,15 +149,11 @@ macro_rules! setup_interned_struct {
149149
}
150150

151151
impl $Configuration {
152-
pub fn ingredient<Db>(db: &Db) -> &$zalsa_struct::IngredientImpl<Self>
153-
where
154-
Db: ?Sized + $zalsa::Database,
152+
pub fn ingredient(zalsa: &$zalsa::Zalsa) -> &$zalsa_struct::IngredientImpl<Self>
155153
{
156154
static CACHE: $zalsa::IngredientCache<$zalsa_struct::IngredientImpl<$Configuration>> =
157155
$zalsa::IngredientCache::new();
158156

159-
let zalsa = db.zalsa();
160-
161157
// SAFETY: `lookup_jar_by_type` returns a valid ingredient index, and the only
162158
// ingredient created by our jar is the struct ingredient.
163159
unsafe {
@@ -239,7 +235,8 @@ macro_rules! setup_interned_struct {
239235
$field_ty: $zalsa::interned::HashEqLike<$indexed_ty>,
240236
)*
241237
{
242-
$Configuration::ingredient(db).intern(db.as_dyn_database(),
238+
let (zalsa, zalsa_local) = db.zalsas();
239+
$Configuration::ingredient(zalsa).intern(zalsa, zalsa_local,
243240
StructKey::<$db_lt>($($field_id,)* std::marker::PhantomData::default()), |_, data| ($($zalsa::interned::Lookup::into_owned(data.$field_index),)*))
244241
}
245242

@@ -250,7 +247,8 @@ macro_rules! setup_interned_struct {
250247
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
251248
$Db: ?Sized + $zalsa::Database,
252249
{
253-
let fields = $Configuration::ingredient(db).fields(db.as_dyn_database(), self);
250+
let zalsa = db.zalsa();
251+
let fields = $Configuration::ingredient(zalsa).fields(zalsa, self);
254252
$zalsa::return_mode_expression!(
255253
$field_option,
256254
$field_ty,
@@ -262,7 +260,8 @@ macro_rules! setup_interned_struct {
262260
/// Default debug formatting for this struct (may be useful if you define your own `Debug` impl)
263261
pub fn default_debug_fmt(this: Self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
264262
$zalsa::with_attached_database(|db| {
265-
let fields = $Configuration::ingredient(db).fields(db.as_dyn_database(), this);
263+
let zalsa = db.zalsa();
264+
let fields = $Configuration::ingredient(zalsa).fields(zalsa, this);
266265
let mut f = f.debug_struct(stringify!($Struct));
267266
$(
268267
let f = f.field(stringify!($field_id), &fields.$field_index);

components/salsa-macro-rules/src/setup_tracked_fn.rs

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -175,17 +175,21 @@ macro_rules! setup_tracked_fn {
175175
impl $Configuration {
176176
fn fn_ingredient(db: &dyn $Db) -> &$zalsa::function::IngredientImpl<$Configuration> {
177177
let zalsa = db.zalsa();
178+
Self::fn_ingredient_(db, zalsa)
179+
}
178180

181+
#[inline]
182+
fn fn_ingredient_<'z>(db: &dyn $Db, zalsa: &'z $zalsa::Zalsa) -> &'z $zalsa::function::IngredientImpl<$Configuration> {
179183
// SAFETY: `lookup_jar_by_type` returns a valid ingredient index, and the first
180184
// ingredient created by our jar is the function ingredient.
181185
unsafe {
182186
$FN_CACHE.get_or_create(zalsa, || zalsa.lookup_jar_by_type::<$fn_name>())
183187
}
184-
.get_or_init(|| <dyn $Db as $Db>::zalsa_register_downcaster(db))
188+
.get_or_init(|| *<dyn $Db as $Db>::zalsa_register_upcaster(db))
185189
}
186190

187191
pub fn fn_ingredient_mut(db: &mut dyn $Db) -> &mut $zalsa::function::IngredientImpl<Self> {
188-
let view = <dyn $Db as $Db>::zalsa_register_downcaster(db);
192+
let view = *<dyn $Db as $Db>::zalsa_register_upcaster(db);
189193
let zalsa_mut = db.zalsa_mut();
190194
let index = zalsa_mut.lookup_jar_by_type::<$fn_name>();
191195
let (ingredient, _) = zalsa_mut.lookup_ingredient_mut(index);
@@ -199,7 +203,13 @@ macro_rules! setup_tracked_fn {
199203
db: &dyn $Db,
200204
) -> &$zalsa::interned::IngredientImpl<$Configuration> {
201205
let zalsa = db.zalsa();
202-
206+
Self::intern_ingredient_(db, zalsa)
207+
}
208+
#[inline]
209+
fn intern_ingredient_<'z>(
210+
db: &dyn $Db,
211+
zalsa: &'z $zalsa::Zalsa
212+
) -> &'z $zalsa::interned::IngredientImpl<$Configuration> {
203213
// SAFETY: `lookup_jar_by_type` returns a valid ingredient index, and the second
204214
// ingredient created by our jar is the interned ingredient (given `needs_interner`).
205215
unsafe {
@@ -258,11 +268,12 @@ macro_rules! setup_tracked_fn {
258268
}
259269

260270
fn id_to_input<$db_lt>(db: &$db_lt Self::DbView, key: salsa::Id) -> Self::Input<$db_lt> {
271+
let zalsa = db.zalsa();
261272
$zalsa::macro_if! {
262273
if $needs_interner {
263-
$Configuration::intern_ingredient(db).data(db.as_dyn_database(), key).clone()
274+
$Configuration::intern_ingredient_(db, zalsa).data(zalsa, key).clone()
264275
} else {
265-
$zalsa::FromIdWithDb::from_id(key, db.zalsa())
276+
$zalsa::FromIdWithDb::from_id(key, zalsa)
266277
}
267278
}
268279
}
@@ -309,6 +320,7 @@ macro_rules! setup_tracked_fn {
309320
};
310321

311322
let fn_ingredient = <$zalsa::function::IngredientImpl<$Configuration>>::new(
323+
zalsa,
312324
first_index,
313325
memo_ingredient_indices,
314326
$lru,
@@ -340,9 +352,10 @@ macro_rules! setup_tracked_fn {
340352
) -> Vec<&$db_lt A> {
341353
use salsa::plumbing as $zalsa;
342354
let key = $zalsa::macro_if! {
343-
if $needs_interner {
344-
$Configuration::intern_ingredient($db).intern_id($db.as_dyn_database(), ($($input_id),*), |_, data| data)
345-
} else {
355+
if $needs_interner {{
356+
let (zalsa, zalsa_local) = $db.zalsas();
357+
$Configuration::intern_ingredient($db).intern_id(zalsa, zalsa_local, ($($input_id),*), |_, data| data)
358+
}} else {
346359
$zalsa::AsId::as_id(&($($input_id),*))
347360
}
348361
};
@@ -383,11 +396,15 @@ macro_rules! setup_tracked_fn {
383396
let result = $zalsa::macro_if! {
384397
if $needs_interner {
385398
{
386-
let key = $Configuration::intern_ingredient($db).intern_id($db.as_dyn_database(), ($($input_id),*), |_, data| data);
387-
$Configuration::fn_ingredient($db).fetch($db, key)
399+
let (zalsa, zalsa_local) = $db.zalsas();
400+
let key = $Configuration::intern_ingredient_($db, zalsa).intern_id(zalsa, zalsa_local, ($($input_id),*), |_, data| data);
401+
$Configuration::fn_ingredient_($db, zalsa).fetch($db, zalsa, zalsa_local, key)
388402
}
389403
} else {
390-
$Configuration::fn_ingredient($db).fetch($db, $zalsa::AsId::as_id(&($($input_id),*)))
404+
{
405+
let (zalsa, zalsa_local) = $db.zalsas();
406+
$Configuration::fn_ingredient_($db, zalsa).fetch($db, zalsa, zalsa_local, $zalsa::AsId::as_id(&($($input_id),*)))
407+
}
391408
}
392409
};
393410

components/salsa-macro-rules/src/setup_tracked_struct.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,9 @@ macro_rules! setup_tracked_struct {
282282
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
283283
$Db: ?Sized + $zalsa::Database,
284284
{
285-
$Configuration::ingredient(db.as_dyn_database()).new_struct(
286-
db.as_dyn_database(),
285+
let (zalsa, zalsa_local) = db.zalsas();
286+
$Configuration::ingredient_(zalsa).new_struct(
287+
zalsa,zalsa_local,
287288
($($field_id,)*)
288289
)
289290
}
@@ -295,8 +296,8 @@ macro_rules! setup_tracked_struct {
295296
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
296297
$Db: ?Sized + $zalsa::Database,
297298
{
298-
let db = db.as_dyn_database();
299-
let fields = $Configuration::ingredient(db).tracked_field(db, self, $relative_tracked_index);
299+
let (zalsa, zalsa_local) = db.zalsas();
300+
let fields = $Configuration::ingredient_(zalsa).tracked_field(zalsa, zalsa_local, self, $relative_tracked_index);
300301
$crate::return_mode_expression!(
301302
$tracked_option,
302303
$tracked_ty,
@@ -312,8 +313,8 @@ macro_rules! setup_tracked_struct {
312313
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
313314
$Db: ?Sized + $zalsa::Database,
314315
{
315-
let db = db.as_dyn_database();
316-
let fields = $Configuration::ingredient(db).untracked_field(db, self);
316+
let zalsa = db.zalsa();
317+
let fields = $Configuration::ingredient_(zalsa).untracked_field(zalsa, self);
317318
$crate::return_mode_expression!(
318319
$untracked_option,
319320
$untracked_ty,
@@ -335,7 +336,8 @@ macro_rules! setup_tracked_struct {
335336
$(for<$db_lt> $field_ty: std::fmt::Debug),*
336337
{
337338
$zalsa::with_attached_database(|db| {
338-
let fields = $Configuration::ingredient(db).leak_fields(db, this);
339+
let zalsa = db.zalsa();
340+
let fields = $Configuration::ingredient_(zalsa).leak_fields(zalsa, this);
339341
let mut f = f.debug_struct(stringify!($Struct));
340342
let f = f.field("[salsa id]", &$zalsa::AsId::as_id(&this));
341343
$(

components/salsa-macros/src/db.rs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -110,18 +110,14 @@ impl DbMacro {
110110
let trait_name = &input.ident;
111111
input.items.push(parse_quote! {
112112
#[doc(hidden)]
113-
fn zalsa_register_downcaster(&self) -> salsa::plumbing::DatabaseDownCaster<dyn #trait_name>;
113+
fn zalsa_register_upcaster(&self) -> &salsa::plumbing::DatabaseUpCaster<dyn #trait_name>;
114114
});
115115

116-
let comment = format!(" Downcast a [`dyn Database`] to a [`dyn {trait_name}`]");
116+
let comment = format!(" upcast `Self` to a [`dyn {trait_name}`]");
117117
input.items.push(parse_quote! {
118118
#[doc = #comment]
119-
///
120-
/// # Safety
121-
///
122-
/// The input database must be of type `Self`.
123119
#[doc(hidden)]
124-
unsafe fn downcast(db: &dyn salsa::plumbing::Database) -> &dyn #trait_name where Self: Sized;
120+
fn upcast(&self) -> &dyn #trait_name where Self: Sized;
125121
});
126122
Ok(())
127123
}
@@ -138,17 +134,15 @@ impl DbMacro {
138134
#[cold]
139135
#[inline(never)]
140136
#[doc(hidden)]
141-
fn zalsa_register_downcaster(&self) -> salsa::plumbing::DatabaseDownCaster<dyn #TraitPath> {
142-
salsa::plumbing::views(self).add(<Self as #TraitPath>::downcast)
137+
fn zalsa_register_upcaster(&self) -> &salsa::plumbing::DatabaseUpCaster<dyn #TraitPath> {
138+
salsa::plumbing::views(self).add(<Self as #TraitPath>::upcast)
143139
}
144140
});
145141
input.items.push(parse_quote! {
146142
#[doc(hidden)]
147143
#[inline(always)]
148-
unsafe fn downcast(db: &dyn salsa::plumbing::Database) -> &dyn #TraitPath where Self: Sized {
149-
debug_assert_eq!(db.type_id(), ::core::any::TypeId::of::<Self>());
150-
// SAFETY: The input database must be of type `Self`.
151-
unsafe { &*salsa::plumbing::transmute_data_ptr::<dyn salsa::plumbing::Database, Self>(db) }
144+
fn upcast(&self) -> &dyn #TraitPath where Self: Sized {
145+
self
152146
}
153147
});
154148
Ok(())

src/accumulator.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ impl<A: Accumulator> Ingredient for IngredientImpl<A> {
102102

103103
unsafe fn maybe_changed_after(
104104
&self,
105-
_db: &dyn Database,
105+
_zalsa: &crate::zalsa::Zalsa,
106+
_db: crate::database::RawDatabasePointer<'_>,
106107
_input: Id,
107108
_revision: Revision,
108109
_cycle_heads: &mut CycleHeads,

0 commit comments

Comments
 (0)