Open nikomatsakis opened 2 months ago
Mentoring instructions:
TablePage
trait to access the ingredient index. The impl can just return this field -- remove the #[allow(dead_code]
annotation while you're at it.get_ingredient(&self, id: Id) -> IngredientIndex
to Table
, kind of like get
, which gets the ingredient index for a given Id
. It should call split_id
and just take the first page (the page
). It can then check self.pages.get(id)
-- note that it should not call self.page::<T>
because we don't know the T
-- and invoke the method you added in the previous step.Id
, is
and downcast
. This is the trickiest part because I think we want to tweak the traits. I would start by modifying SalsaStructInDb
-- probably rename it to SalsaStruct<'db>
and add some methods like fn ingredient_index(db: &'db dyn salsa::Database) -> IngredientIndex
and fn new(db: &'db dyn salsa::Database, id: Id) -> Self
. We'll need to tweak the implementations created in the various macros in salsa-macro-rules
and get everything to build. The ingredient_index
method should invoke the existing ingredient
method, which already has caching. The new
method should probably assert!
(maybe debug_assert!
) that the ingredient for id
matches Self::ingredient_index
.is
can be implemented by comparing S::ingredient_index()
with the result of db.table.ingredient_index(id)
. Downcasting can be implemented by checking is
and then invoking new
.SalsaStructInDb
something like is
and downcast
and just have salsa::Id
forward to them.I've assigned this issue to myself; I'll need this functionality in Salsa in order to migrate rust-analyzer.
I've noticed that I often have an enum whose variants are all different salsa structs:
I was thinking about how this enum will use 2 words and not 1 and I realized that, given that each variant is just storing an
Id
, and that we can go from anId
to anIngredientIndex
(it's stored on the page), we could have a proc-macro that takes such an enum and returns a special struct that just stores a singleId
. It could then be converted into an enum readily enough. You also downcast it.I'm imagining the following:
First, add two methods to
salsa::Id
,fn is<S>(self, db: &dyn Database) -> bool
andfn downcast<S>(self, db: &dyn Database) -> Option<S>
, whereS: SalsaStructInDb<'_>
. These methods can lookup the id indb.table
, identify the ingredient index on the from thePage
, compare that to the ingredient index forS
, and then do the appropriate thing. (We might also want to tweak theFromId
or other traits in a similar-ish way.)Next, create a proc macro named
supertype
(bikeshed) which expects an enum with one lifetime argument and where each variant has a single argument:we generate the following: