Skip to content

Do manual trait upcasting instead of downcasting #922

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions components/salsa-macro-rules/src/setup_input_struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,7 @@ macro_rules! setup_input_struct {
})
}

pub fn ingredient_mut(db: &mut dyn $zalsa::Database) -> (&mut $zalsa_struct::IngredientImpl<Self>, &mut $zalsa::Runtime) {
let zalsa_mut = db.zalsa_mut();
pub fn ingredient_mut(zalsa_mut: &mut $zalsa::Zalsa) -> (&mut $zalsa_struct::IngredientImpl<Self>, &mut $zalsa::Runtime) {
zalsa_mut.new_revision();
let index = zalsa_mut.add_or_lookup_jar_by_type::<$zalsa_struct::JarImpl<$Configuration>>();
let (ingredient, runtime) = zalsa_mut.lookup_ingredient_mut(index);
Expand Down Expand Up @@ -185,8 +184,10 @@ macro_rules! setup_input_struct {
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
$Db: ?Sized + $zalsa::Database,
{
let fields = $Configuration::ingredient_(db.zalsa()).field(
db.as_dyn_database(),
let (zalsa, zalsa_local) = db.zalsas();
let fields = $Configuration::ingredient_(zalsa).field(
zalsa,
zalsa_local,
self,
$field_index,
);
Expand All @@ -205,7 +206,8 @@ macro_rules! setup_input_struct {
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
$Db: ?Sized + $zalsa::Database,
{
let (ingredient, revision) = $Configuration::ingredient_mut(db.as_dyn_database_mut());
let zalsa = db.zalsa_mut();
let (ingredient, revision) = $Configuration::ingredient_mut(zalsa);
$zalsa::input::SetterImpl::new(
revision,
self,
Expand Down Expand Up @@ -244,7 +246,8 @@ macro_rules! setup_input_struct {
$(for<'__trivial_bounds> $field_ty: std::fmt::Debug),*
{
$zalsa::with_attached_database(|db| {
let fields = $Configuration::ingredient(db).leak_fields(db, this);
let zalsa = db.zalsa();
let fields = $Configuration::ingredient_(zalsa).leak_fields(zalsa, this);
let mut f = f.debug_struct(stringify!($Struct));
let f = f.field("[salsa id]", &$zalsa::AsId::as_id(&this));
$(
Expand Down Expand Up @@ -273,11 +276,11 @@ macro_rules! setup_input_struct {
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
$Db: ?Sized + salsa::Database
{
let zalsa = db.zalsa();
let (zalsa, zalsa_local) = db.zalsas();
let current_revision = zalsa.current_revision();
let ingredient = $Configuration::ingredient_(zalsa);
let (fields, revision, durabilities) = builder::builder_into_inner(self, current_revision);
ingredient.new_input(db.as_dyn_database(), fields, revision, durabilities)
ingredient.new_input(zalsa, zalsa_local, fields, revision, durabilities)
}
}

Expand Down
14 changes: 7 additions & 7 deletions components/salsa-macro-rules/src/setup_interned_struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,11 @@ macro_rules! setup_interned_struct {
}

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

let zalsa = db.zalsa();
CACHE.get_or_create(zalsa, || {
zalsa.add_or_lookup_jar_by_type::<$zalsa_struct::JarImpl<$Configuration>>()
})
Expand Down Expand Up @@ -215,7 +212,8 @@ macro_rules! setup_interned_struct {
$field_ty: $zalsa::interned::HashEqLike<$indexed_ty>,
)*
{
$Configuration::ingredient(db).intern(db.as_dyn_database(),
let (zalsa, zalsa_local) = db.zalsas();
$Configuration::ingredient(zalsa).intern(zalsa, zalsa_local,
StructKey::<$db_lt>($($field_id,)* std::marker::PhantomData::default()), |_, data| ($($zalsa::interned::Lookup::into_owned(data.$field_index),)*))
}

Expand All @@ -226,7 +224,8 @@ macro_rules! setup_interned_struct {
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
$Db: ?Sized + $zalsa::Database,
{
let fields = $Configuration::ingredient(db).fields(db.as_dyn_database(), self);
let zalsa = db.zalsa();
let fields = $Configuration::ingredient(zalsa).fields(zalsa, self);
$zalsa::return_mode_expression!(
$field_option,
$field_ty,
Expand All @@ -238,7 +237,8 @@ macro_rules! setup_interned_struct {
/// 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| {
let fields = $Configuration::ingredient(db).fields(db.as_dyn_database(), this);
let zalsa = db.zalsa();
let fields = $Configuration::ingredient(zalsa).fields(zalsa, this);
let mut f = f.debug_struct(stringify!($Struct));
$(
let f = f.field(stringify!($field_id), &fields.$field_index);
Expand Down
40 changes: 28 additions & 12 deletions components/salsa-macro-rules/src/setup_tracked_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,18 @@ macro_rules! setup_tracked_fn {
impl $Configuration {
fn fn_ingredient(db: &dyn $Db) -> &$zalsa::function::IngredientImpl<$Configuration> {
let zalsa = db.zalsa();
Self::fn_ingredient_(db, zalsa)
}

fn fn_ingredient_<'z>(db: &dyn $Db, zalsa: &'z $zalsa::Zalsa) -> &'z $zalsa::function::IngredientImpl<$Configuration> {
$FN_CACHE.get_or_create(zalsa, || {
<dyn $Db as $Db>::zalsa_register_downcaster(db);
<dyn $Db as $Db>::zalsa_register_upcaster(db);
zalsa.add_or_lookup_jar_by_type::<$Configuration>()
})
}

pub fn fn_ingredient_mut(db: &mut dyn $Db) -> &mut $zalsa::function::IngredientImpl<Self> {
<dyn $Db as $Db>::zalsa_register_downcaster(db);
<dyn $Db as $Db>::zalsa_register_upcaster(db);
let zalsa_mut = db.zalsa_mut();
let index = zalsa_mut.add_or_lookup_jar_by_type::<$Configuration>();
let (ingredient, _) = zalsa_mut.lookup_ingredient_mut(index);
Expand All @@ -169,8 +173,14 @@ macro_rules! setup_tracked_fn {
db: &dyn $Db,
) -> &$zalsa::interned::IngredientImpl<$Configuration> {
let zalsa = db.zalsa();
Self::intern_ingredient_(db, zalsa)
}
fn intern_ingredient_<'z>(
db: &dyn $Db,
zalsa: &'z $zalsa::Zalsa
) -> &'z $zalsa::interned::IngredientImpl<$Configuration> {
$INTERN_CACHE.get_or_create(zalsa, || {
<dyn $Db as $Db>::zalsa_register_downcaster(db);
<dyn $Db as $Db>::zalsa_register_upcaster(db);
zalsa.add_or_lookup_jar_by_type::<$Configuration>().successor(0)
})
}
Expand Down Expand Up @@ -218,11 +228,12 @@ macro_rules! setup_tracked_fn {
}

fn id_to_input<$db_lt>(db: &$db_lt Self::DbView, key: salsa::Id) -> Self::Input<$db_lt> {
let zalsa = db.zalsa();
$zalsa::macro_if! {
if $needs_interner {
$Configuration::intern_ingredient(db).data(db.as_dyn_database(), key).clone()
$Configuration::intern_ingredient_(db, zalsa).data(zalsa, key).clone()
} else {
$zalsa::FromIdWithDb::from_id(key, db.zalsa())
$zalsa::FromIdWithDb::from_id(key, zalsa)
}
}
}
Expand Down Expand Up @@ -280,10 +291,10 @@ macro_rules! setup_tracked_fn {
};

let fn_ingredient = <$zalsa::function::IngredientImpl<$Configuration>>::new(
zalsa,
first_index,
memo_ingredient_indices,
$lru,
zalsa.views().downcaster_for::<dyn $Db>(),
);
$zalsa::macro_if! {
if $needs_interner {
Expand Down Expand Up @@ -312,9 +323,10 @@ macro_rules! setup_tracked_fn {
) -> Vec<&$db_lt A> {
use salsa::plumbing as $zalsa;
let key = $zalsa::macro_if! {
if $needs_interner {
$Configuration::intern_ingredient($db).intern_id($db.as_dyn_database(), ($($input_id),*), |_, data| data)
} else {
if $needs_interner {{
let (zalsa, zalsa_local) = $db.zalsas();
$Configuration::intern_ingredient($db).intern_id(zalsa, zalsa_local, ($($input_id),*), |_, data| data)
}} else {
$zalsa::AsId::as_id(&($($input_id),*))
}
};
Expand Down Expand Up @@ -355,11 +367,15 @@ macro_rules! setup_tracked_fn {
let result = $zalsa::macro_if! {
if $needs_interner {
{
let key = $Configuration::intern_ingredient($db).intern_id($db.as_dyn_database(), ($($input_id),*), |_, data| data);
$Configuration::fn_ingredient($db).fetch($db, key)
let (zalsa, zalsa_local) = $db.zalsas();
let key = $Configuration::intern_ingredient_($db, zalsa).intern_id(zalsa, zalsa_local, ($($input_id),*), |_, data| data);
$Configuration::fn_ingredient_($db, zalsa).fetch($db, zalsa, zalsa_local, key)
}
} else {
$Configuration::fn_ingredient($db).fetch($db, $zalsa::AsId::as_id(&($($input_id),*)))
{
let (zalsa, zalsa_local) = $db.zalsas();
$Configuration::fn_ingredient_($db, zalsa).fetch($db, zalsa, zalsa_local, $zalsa::AsId::as_id(&($($input_id),*)))
}
}
};

Expand Down
16 changes: 9 additions & 7 deletions components/salsa-macro-rules/src/setup_tracked_struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,9 @@ macro_rules! setup_tracked_struct {
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
$Db: ?Sized + $zalsa::Database,
{
$Configuration::ingredient(db.as_dyn_database()).new_struct(
db.as_dyn_database(),
let (zalsa, zalsa_local) = db.zalsas();
$Configuration::ingredient_(zalsa).new_struct(
zalsa,zalsa_local,
($($field_id,)*)
)
}
Expand All @@ -272,8 +273,8 @@ macro_rules! setup_tracked_struct {
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
$Db: ?Sized + $zalsa::Database,
{
let db = db.as_dyn_database();
let fields = $Configuration::ingredient(db).tracked_field(db, self, $relative_tracked_index);
let (zalsa, zalsa_local) = db.zalsas();
let fields = $Configuration::ingredient_(zalsa).tracked_field(zalsa, zalsa_local, self, $relative_tracked_index);
$crate::return_mode_expression!(
$tracked_option,
$tracked_ty,
Expand All @@ -289,8 +290,8 @@ macro_rules! setup_tracked_struct {
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
$Db: ?Sized + $zalsa::Database,
{
let db = db.as_dyn_database();
let fields = $Configuration::ingredient(db).untracked_field(db, self);
let zalsa = db.zalsa();
let fields = $Configuration::ingredient_(zalsa).untracked_field(zalsa, self);
$crate::return_mode_expression!(
$untracked_option,
$untracked_ty,
Expand All @@ -312,7 +313,8 @@ macro_rules! setup_tracked_struct {
$(for<$db_lt> $field_ty: std::fmt::Debug),*
{
$zalsa::with_attached_database(|db| {
let fields = $Configuration::ingredient(db).leak_fields(db, this);
let zalsa = db.zalsa();
let fields = $Configuration::ingredient_(zalsa).leak_fields(zalsa, this);
let mut f = f.debug_struct(stringify!($Struct));
let f = f.field("[salsa id]", &$zalsa::AsId::as_id(&this));
$(
Expand Down
20 changes: 7 additions & 13 deletions components/salsa-macros/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,18 +110,14 @@ impl DbMacro {
let trait_name = &input.ident;
input.items.push(parse_quote! {
#[doc(hidden)]
fn zalsa_register_downcaster(&self);
fn zalsa_register_upcaster(&self);
});

let comment = format!(" Downcast a [`dyn Database`] to a [`dyn {trait_name}`]");
let comment = format!(" upcast `Self` to a [`dyn {trait_name}`]");
input.items.push(parse_quote! {
#[doc = #comment]
///
/// # Safety
///
/// The input database must be of type `Self`.
#[doc(hidden)]
unsafe fn downcast(db: &dyn salsa::plumbing::Database) -> &dyn #trait_name where Self: Sized;
fn upcast(&self) -> &dyn #trait_name where Self: Sized;
});
Ok(())
}
Expand All @@ -137,17 +133,15 @@ impl DbMacro {
input.items.push(parse_quote! {
#[doc(hidden)]
#[inline(always)]
fn zalsa_register_downcaster(&self) {
salsa::plumbing::views(self).add(<Self as #TraitPath>::downcast);
fn zalsa_register_upcaster(&self) {
salsa::plumbing::views(self).add(<Self as #TraitPath>::upcast);
}
});
input.items.push(parse_quote! {
#[doc(hidden)]
#[inline(always)]
unsafe fn downcast(db: &dyn salsa::plumbing::Database) -> &dyn #TraitPath where Self: Sized {
debug_assert_eq!(db.type_id(), ::core::any::TypeId::of::<Self>());
// SAFETY: The input database must be of type `Self`.
unsafe { &*salsa::plumbing::transmute_data_ptr::<dyn salsa::plumbing::Database, Self>(db) }
fn upcast(&self) -> &dyn #TraitPath where Self: Sized {
self
}
});
Ok(())
Expand Down
3 changes: 2 additions & 1 deletion src/accumulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ impl<A: Accumulator> Ingredient for IngredientImpl<A> {

unsafe fn maybe_changed_after(
&self,
_db: &dyn Database,
_zalsa: &crate::zalsa::Zalsa,
_db: crate::database::RawDatabasePointer<'_>,
_input: Id,
_revision: Revision,
_cycle_heads: &mut CycleHeads,
Expand Down
8 changes: 5 additions & 3 deletions src/attach.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl Attached {

impl<'s> DbGuard<'s> {
#[inline]
fn new(attached: &'s Attached, db: &dyn Database) -> Self {
fn new<Db: ?Sized + Database>(attached: &'s Attached, db: &Db) -> Self {
match attached.database.get() {
Some(current_db) => {
let new_db = NonNull::from(db);
Expand All @@ -56,7 +56,9 @@ impl Attached {
}
None => {
// Otherwise, set the database.
attached.database.set(Some(NonNull::from(db)));
attached
.database
.set(Some(NonNull::from(db.dyn_database())));
Self {
state: Some(attached),
}
Expand All @@ -75,7 +77,7 @@ impl Attached {
}
}

let _guard = DbGuard::new(self, db.as_dyn_database());
let _guard = DbGuard::new(self, db);
op()
}

Expand Down
Loading