Skip to content

Commit 28acf8c

Browse files
committed
Do manual trait upcasting instead of downcasting
1 parent 87a730f commit 28acf8c

27 files changed

+363
-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
@@ -105,8 +105,7 @@ macro_rules! setup_input_struct {
105105
})
106106
}
107107

108-
pub fn ingredient_mut(db: &mut dyn $zalsa::Database) -> (&mut $zalsa_struct::IngredientImpl<Self>, &mut $zalsa::Runtime) {
109-
let zalsa_mut = db.zalsa_mut();
108+
pub fn ingredient_mut(zalsa_mut: &mut $zalsa::Zalsa) -> (&mut $zalsa_struct::IngredientImpl<Self>, &mut $zalsa::Runtime) {
110109
zalsa_mut.new_revision();
111110
let index = zalsa_mut.add_or_lookup_jar_by_type::<$zalsa_struct::JarImpl<$Configuration>>();
112111
let (ingredient, runtime) = zalsa_mut.lookup_ingredient_mut(index);
@@ -185,8 +184,10 @@ macro_rules! setup_input_struct {
185184
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
186185
$Db: ?Sized + $zalsa::Database,
187186
{
188-
let fields = $Configuration::ingredient_(db.zalsa()).field(
189-
db.as_dyn_database(),
187+
let (zalsa, zalsa_local) = db.zalsas();
188+
let fields = $Configuration::ingredient_(zalsa).field(
189+
zalsa,
190+
zalsa_local,
190191
self,
191192
$field_index,
192193
);
@@ -205,7 +206,8 @@ macro_rules! setup_input_struct {
205206
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
206207
$Db: ?Sized + $zalsa::Database,
207208
{
208-
let (ingredient, revision) = $Configuration::ingredient_mut(db.as_dyn_database_mut());
209+
let zalsa = db.zalsa_mut();
210+
let (ingredient, revision) = $Configuration::ingredient_mut(zalsa);
209211
$zalsa::input::SetterImpl::new(
210212
revision,
211213
self,
@@ -244,7 +246,8 @@ macro_rules! setup_input_struct {
244246
$(for<'__trivial_bounds> $field_ty: std::fmt::Debug),*
245247
{
246248
$zalsa::with_attached_database(|db| {
247-
let fields = $Configuration::ingredient(db).leak_fields(db, this);
249+
let zalsa = db.zalsa();
250+
let fields = $Configuration::ingredient_(zalsa).leak_fields(zalsa, this);
248251
let mut f = f.debug_struct(stringify!($Struct));
249252
let f = f.field("[salsa id]", &$zalsa::AsId::as_id(&this));
250253
$(
@@ -273,11 +276,11 @@ macro_rules! setup_input_struct {
273276
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
274277
$Db: ?Sized + salsa::Database
275278
{
276-
let zalsa = db.zalsa();
279+
let (zalsa, zalsa_local) = db.zalsas();
277280
let current_revision = zalsa.current_revision();
278281
let ingredient = $Configuration::ingredient_(zalsa);
279282
let (fields, revision, durabilities) = builder::builder_into_inner(self, current_revision);
280-
ingredient.new_input(db.as_dyn_database(), fields, revision, durabilities)
283+
ingredient.new_input(zalsa, zalsa_local, fields, revision, durabilities)
281284
}
282285
}
283286

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -140,14 +140,11 @@ macro_rules! setup_interned_struct {
140140
}
141141

142142
impl $Configuration {
143-
pub fn ingredient<Db>(db: &Db) -> &$zalsa_struct::IngredientImpl<Self>
144-
where
145-
Db: ?Sized + $zalsa::Database,
143+
pub fn ingredient(zalsa: &$zalsa::Zalsa) -> &$zalsa_struct::IngredientImpl<Self>
146144
{
147145
static CACHE: $zalsa::IngredientCache<$zalsa_struct::IngredientImpl<$Configuration>> =
148146
$zalsa::IngredientCache::new();
149147

150-
let zalsa = db.zalsa();
151148
CACHE.get_or_create(zalsa, || {
152149
zalsa.add_or_lookup_jar_by_type::<$zalsa_struct::JarImpl<$Configuration>>()
153150
})
@@ -215,7 +212,8 @@ macro_rules! setup_interned_struct {
215212
$field_ty: $zalsa::interned::HashEqLike<$indexed_ty>,
216213
)*
217214
{
218-
$Configuration::ingredient(db).intern(db.as_dyn_database(),
215+
let (zalsa, zalsa_local) = db.zalsas();
216+
$Configuration::ingredient(zalsa).intern(zalsa, zalsa_local,
219217
StructKey::<$db_lt>($($field_id,)* std::marker::PhantomData::default()), |_, data| ($($zalsa::interned::Lookup::into_owned(data.$field_index),)*))
220218
}
221219

@@ -226,7 +224,8 @@ macro_rules! setup_interned_struct {
226224
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
227225
$Db: ?Sized + $zalsa::Database,
228226
{
229-
let fields = $Configuration::ingredient(db).fields(db.as_dyn_database(), self);
227+
let zalsa = db.zalsa();
228+
let fields = $Configuration::ingredient(zalsa).fields(zalsa, self);
230229
$zalsa::return_mode_expression!(
231230
$field_option,
232231
$field_ty,
@@ -238,7 +237,8 @@ macro_rules! setup_interned_struct {
238237
/// Default debug formatting for this struct (may be useful if you define your own `Debug` impl)
239238
pub fn default_debug_fmt(this: Self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
240239
$zalsa::with_attached_database(|db| {
241-
let fields = $Configuration::ingredient(db).fields(db.as_dyn_database(), this);
240+
let zalsa = db.zalsa();
241+
let fields = $Configuration::ingredient(zalsa).fields(zalsa, this);
242242
let mut f = f.debug_struct(stringify!($Struct));
243243
$(
244244
let f = f.field(stringify!($field_id), &fields.$field_index);

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

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -150,14 +150,18 @@ macro_rules! setup_tracked_fn {
150150
impl $Configuration {
151151
fn fn_ingredient(db: &dyn $Db) -> &$zalsa::function::IngredientImpl<$Configuration> {
152152
let zalsa = db.zalsa();
153+
Self::fn_ingredient_(db, zalsa)
154+
}
155+
156+
fn fn_ingredient_<'z>(db: &dyn $Db, zalsa: &'z $zalsa::Zalsa) -> &'z $zalsa::function::IngredientImpl<$Configuration> {
153157
$FN_CACHE.get_or_create(zalsa, || {
154-
<dyn $Db as $Db>::zalsa_register_downcaster(db);
158+
<dyn $Db as $Db>::zalsa_register_upcaster(db);
155159
zalsa.add_or_lookup_jar_by_type::<$Configuration>()
156160
})
157161
}
158162

159163
pub fn fn_ingredient_mut(db: &mut dyn $Db) -> &mut $zalsa::function::IngredientImpl<Self> {
160-
<dyn $Db as $Db>::zalsa_register_downcaster(db);
164+
<dyn $Db as $Db>::zalsa_register_upcaster(db);
161165
let zalsa_mut = db.zalsa_mut();
162166
let index = zalsa_mut.add_or_lookup_jar_by_type::<$Configuration>();
163167
let (ingredient, _) = zalsa_mut.lookup_ingredient_mut(index);
@@ -169,8 +173,14 @@ macro_rules! setup_tracked_fn {
169173
db: &dyn $Db,
170174
) -> &$zalsa::interned::IngredientImpl<$Configuration> {
171175
let zalsa = db.zalsa();
176+
Self::intern_ingredient_(db, zalsa)
177+
}
178+
fn intern_ingredient_<'z>(
179+
db: &dyn $Db,
180+
zalsa: &'z $zalsa::Zalsa
181+
) -> &'z $zalsa::interned::IngredientImpl<$Configuration> {
172182
$INTERN_CACHE.get_or_create(zalsa, || {
173-
<dyn $Db as $Db>::zalsa_register_downcaster(db);
183+
<dyn $Db as $Db>::zalsa_register_upcaster(db);
174184
zalsa.add_or_lookup_jar_by_type::<$Configuration>().successor(0)
175185
})
176186
}
@@ -218,11 +228,12 @@ macro_rules! setup_tracked_fn {
218228
}
219229

220230
fn id_to_input<$db_lt>(db: &$db_lt Self::DbView, key: salsa::Id) -> Self::Input<$db_lt> {
231+
let zalsa = db.zalsa();
221232
$zalsa::macro_if! {
222233
if $needs_interner {
223-
$Configuration::intern_ingredient(db).data(db.as_dyn_database(), key).clone()
234+
$Configuration::intern_ingredient_(db, zalsa).data(zalsa, key).clone()
224235
} else {
225-
$zalsa::FromIdWithDb::from_id(key, db.zalsa())
236+
$zalsa::FromIdWithDb::from_id(key, zalsa)
226237
}
227238
}
228239
}
@@ -280,10 +291,10 @@ macro_rules! setup_tracked_fn {
280291
};
281292

282293
let fn_ingredient = <$zalsa::function::IngredientImpl<$Configuration>>::new(
294+
zalsa,
283295
first_index,
284296
memo_ingredient_indices,
285297
$lru,
286-
zalsa.views().downcaster_for::<dyn $Db>(),
287298
);
288299
$zalsa::macro_if! {
289300
if $needs_interner {
@@ -312,9 +323,10 @@ macro_rules! setup_tracked_fn {
312323
) -> Vec<&$db_lt A> {
313324
use salsa::plumbing as $zalsa;
314325
let key = $zalsa::macro_if! {
315-
if $needs_interner {
316-
$Configuration::intern_ingredient($db).intern_id($db.as_dyn_database(), ($($input_id),*), |_, data| data)
317-
} else {
326+
if $needs_interner {{
327+
let (zalsa, zalsa_local) = $db.zalsas();
328+
$Configuration::intern_ingredient($db).intern_id(zalsa, zalsa_local, ($($input_id),*), |_, data| data)
329+
}} else {
318330
$zalsa::AsId::as_id(&($($input_id),*))
319331
}
320332
};
@@ -355,11 +367,15 @@ macro_rules! setup_tracked_fn {
355367
let result = $zalsa::macro_if! {
356368
if $needs_interner {
357369
{
358-
let key = $Configuration::intern_ingredient($db).intern_id($db.as_dyn_database(), ($($input_id),*), |_, data| data);
359-
$Configuration::fn_ingredient($db).fetch($db, key)
370+
let (zalsa, zalsa_local) = $db.zalsas();
371+
let key = $Configuration::intern_ingredient_($db, zalsa).intern_id(zalsa, zalsa_local, ($($input_id),*), |_, data| data);
372+
$Configuration::fn_ingredient_($db, zalsa).fetch($db, zalsa, zalsa_local, key)
360373
}
361374
} else {
362-
$Configuration::fn_ingredient($db).fetch($db, $zalsa::AsId::as_id(&($($input_id),*)))
375+
{
376+
let (zalsa, zalsa_local) = $db.zalsas();
377+
$Configuration::fn_ingredient_($db, zalsa).fetch($db, zalsa, zalsa_local, $zalsa::AsId::as_id(&($($input_id),*)))
378+
}
363379
}
364380
};
365381

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

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,9 @@ macro_rules! setup_tracked_struct {
259259
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
260260
$Db: ?Sized + $zalsa::Database,
261261
{
262-
$Configuration::ingredient(db.as_dyn_database()).new_struct(
263-
db.as_dyn_database(),
262+
let (zalsa, zalsa_local) = db.zalsas();
263+
$Configuration::ingredient_(zalsa).new_struct(
264+
zalsa,zalsa_local,
264265
($($field_id,)*)
265266
)
266267
}
@@ -272,8 +273,8 @@ macro_rules! setup_tracked_struct {
272273
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
273274
$Db: ?Sized + $zalsa::Database,
274275
{
275-
let db = db.as_dyn_database();
276-
let fields = $Configuration::ingredient(db).tracked_field(db, self, $relative_tracked_index);
276+
let (zalsa, zalsa_local) = db.zalsas();
277+
let fields = $Configuration::ingredient_(zalsa).tracked_field(zalsa, zalsa_local, self, $relative_tracked_index);
277278
$crate::return_mode_expression!(
278279
$tracked_option,
279280
$tracked_ty,
@@ -289,8 +290,8 @@ macro_rules! setup_tracked_struct {
289290
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
290291
$Db: ?Sized + $zalsa::Database,
291292
{
292-
let db = db.as_dyn_database();
293-
let fields = $Configuration::ingredient(db).untracked_field(db, self);
293+
let zalsa = db.zalsa();
294+
let fields = $Configuration::ingredient_(zalsa).untracked_field(zalsa, self);
294295
$crate::return_mode_expression!(
295296
$untracked_option,
296297
$untracked_ty,
@@ -312,7 +313,8 @@ macro_rules! setup_tracked_struct {
312313
$(for<$db_lt> $field_ty: std::fmt::Debug),*
313314
{
314315
$zalsa::with_attached_database(|db| {
315-
let fields = $Configuration::ingredient(db).leak_fields(db, this);
316+
let zalsa = db.zalsa();
317+
let fields = $Configuration::ingredient_(zalsa).leak_fields(zalsa, this);
316318
let mut f = f.debug_struct(stringify!($Struct));
317319
let f = f.field("[salsa id]", &$zalsa::AsId::as_id(&this));
318320
$(

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);
113+
fn zalsa_register_upcaster(&self);
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
}
@@ -137,17 +133,15 @@ impl DbMacro {
137133
input.items.push(parse_quote! {
138134
#[doc(hidden)]
139135
#[inline(always)]
140-
fn zalsa_register_downcaster(&self) {
141-
salsa::plumbing::views(self).add(<Self as #TraitPath>::downcast);
136+
fn zalsa_register_upcaster(&self) {
137+
salsa::plumbing::views(self).add(<Self as #TraitPath>::upcast);
142138
}
143139
});
144140
input.items.push(parse_quote! {
145141
#[doc(hidden)]
146142
#[inline(always)]
147-
unsafe fn downcast(db: &dyn salsa::plumbing::Database) -> &dyn #TraitPath where Self: Sized {
148-
debug_assert_eq!(db.type_id(), ::core::any::TypeId::of::<Self>());
149-
// SAFETY: The input database must be of type `Self`.
150-
unsafe { &*salsa::plumbing::transmute_data_ptr::<dyn salsa::plumbing::Database, Self>(db) }
143+
fn upcast(&self) -> &dyn #TraitPath where Self: Sized {
144+
self
151145
}
152146
});
153147
Ok(())

src/accumulator.rs

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

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

src/attach.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl Attached {
4545

4646
impl<'s> DbGuard<'s> {
4747
#[inline]
48-
fn new(attached: &'s Attached, db: &dyn Database) -> Self {
48+
fn new<Db: ?Sized + Database>(attached: &'s Attached, db: &Db) -> Self {
4949
match attached.database.get() {
5050
Some(current_db) => {
5151
let new_db = NonNull::from(db);
@@ -56,7 +56,9 @@ impl Attached {
5656
}
5757
None => {
5858
// Otherwise, set the database.
59-
attached.database.set(Some(NonNull::from(db)));
59+
attached
60+
.database
61+
.set(Some(NonNull::from(db.dyn_database())));
6062
Self {
6163
state: Some(attached),
6264
}
@@ -75,7 +77,7 @@ impl Attached {
7577
}
7678
}
7779

78-
let _guard = DbGuard::new(self, db.as_dyn_database());
80+
let _guard = DbGuard::new(self, db);
7981
op()
8082
}
8183

0 commit comments

Comments
 (0)