Skip to content

Commit f7d13a9

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

26 files changed

+334
-251
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: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,13 @@ macro_rules! setup_tracked_fn {
151151
fn fn_ingredient(db: &dyn $Db) -> &$zalsa::function::IngredientImpl<$Configuration> {
152152
let zalsa = db.zalsa();
153153
$FN_CACHE.get_or_create(zalsa, || {
154-
<dyn $Db as $Db>::zalsa_register_downcaster(db);
154+
<dyn $Db as $Db>::zalsa_register_upcaster(db);
155155
zalsa.add_or_lookup_jar_by_type::<$Configuration>()
156156
})
157157
}
158158

159159
pub fn fn_ingredient_mut(db: &mut dyn $Db) -> &mut $zalsa::function::IngredientImpl<Self> {
160-
<dyn $Db as $Db>::zalsa_register_downcaster(db);
160+
<dyn $Db as $Db>::zalsa_register_upcaster(db);
161161
let zalsa_mut = db.zalsa_mut();
162162
let index = zalsa_mut.add_or_lookup_jar_by_type::<$Configuration>();
163163
let (ingredient, _) = zalsa_mut.lookup_ingredient_mut(index);
@@ -170,7 +170,7 @@ macro_rules! setup_tracked_fn {
170170
) -> &$zalsa::interned::IngredientImpl<$Configuration> {
171171
let zalsa = db.zalsa();
172172
$INTERN_CACHE.get_or_create(zalsa, || {
173-
<dyn $Db as $Db>::zalsa_register_downcaster(db);
173+
<dyn $Db as $Db>::zalsa_register_upcaster(db);
174174
zalsa.add_or_lookup_jar_by_type::<$Configuration>().successor(0)
175175
})
176176
}
@@ -220,7 +220,7 @@ macro_rules! setup_tracked_fn {
220220
fn id_to_input<$db_lt>(db: &$db_lt Self::DbView, key: salsa::Id) -> Self::Input<$db_lt> {
221221
$zalsa::macro_if! {
222222
if $needs_interner {
223-
$Configuration::intern_ingredient(db).data(db.as_dyn_database(), key).clone()
223+
$Configuration::intern_ingredient(db).data(db.zalsa(), key).clone()
224224
} else {
225225
$zalsa::FromIdWithDb::from_id(key, db.zalsa())
226226
}
@@ -280,10 +280,10 @@ macro_rules! setup_tracked_fn {
280280
};
281281

282282
let fn_ingredient = <$zalsa::function::IngredientImpl<$Configuration>>::new(
283+
zalsa,
283284
first_index,
284285
memo_ingredient_indices,
285286
$lru,
286-
zalsa.views().downcaster_for::<dyn $Db>(),
287287
);
288288
$zalsa::macro_if! {
289289
if $needs_interner {
@@ -312,9 +312,10 @@ macro_rules! setup_tracked_fn {
312312
) -> Vec<&$db_lt A> {
313313
use salsa::plumbing as $zalsa;
314314
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 {
315+
if $needs_interner {{
316+
let (zalsa, zalsa_local) = $db.zalsas();
317+
$Configuration::intern_ingredient($db).intern_id(zalsa, zalsa_local, ($($input_id),*), |_, data| data)
318+
}} else {
318319
$zalsa::AsId::as_id(&($($input_id),*))
319320
}
320321
};
@@ -355,7 +356,8 @@ macro_rules! setup_tracked_fn {
355356
let result = $zalsa::macro_if! {
356357
if $needs_interner {
357358
{
358-
let key = $Configuration::intern_ingredient($db).intern_id($db.as_dyn_database(), ($($input_id),*), |_, data| data);
359+
let (zalsa, zalsa_local) = $db.zalsas();
360+
let key = $Configuration::intern_ingredient($db).intern_id(zalsa, zalsa_local, ($($input_id),*), |_, data| data);
359361
$Configuration::fn_ingredient($db).fetch($db, key)
360362
}
361363
} else {

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)