Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
nikomatsakis committed Jul 12, 2024
1 parent 2cfb758 commit a1651c8
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 182 deletions.
85 changes: 63 additions & 22 deletions components/salsa-macros/src/db.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use proc_macro2::TokenStream;
use syn::{parse::Nothing, ItemStruct};
use syn::parse::Nothing;

use crate::hygiene::Hygiene;

// Source:
//
// #[salsa::db(Jar0, Jar1, Jar2)]
// #[salsa::db]
// pub struct Database {
// storage: salsa::Storage<Self>,
// }
Expand All @@ -15,34 +15,54 @@ pub(crate) fn db(
input: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
let _nothing = syn::parse_macro_input!(args as Nothing);
let db_macro = DbMacro {
hygiene: Hygiene::from(&input),
input: syn::parse_macro_input!(input as syn::ItemStruct),
};
match db_macro.try_db() {
let hygiene = Hygiene::from(&input);
let input = syn::parse_macro_input!(input as syn::Item);
let db_macro = DbMacro { hygiene };
match db_macro.try_db(input) {
Ok(v) => v.into(),
Err(e) => e.to_compile_error().into(),
}
}

struct DbMacro {
hygiene: Hygiene,
input: ItemStruct,
}

#[allow(non_snake_case)]
impl DbMacro {
fn try_db(self) -> syn::Result<TokenStream> {
let has_storage_impl = self.has_storage_impl()?;
let input = self.input;
Ok(quote! {
#has_storage_impl
#input
})
fn try_db(self, input: syn::Item) -> syn::Result<TokenStream> {
match input {
syn::Item::Struct(input) => {
let has_storage_impl = self.has_storage_impl(&input)?;
Ok(quote! {
#has_storage_impl
#input
})
}
syn::Item::Trait(mut input) => {
self.add_salsa_view_method(&mut input)?;
Ok(quote! {
#input
})
}
syn::Item::Impl(mut input) => {
self.add_salsa_view_method_impl(&mut input)?;
Ok(quote! {
#input
})
}
_ => {
return Err(syn::Error::new_spanned(
input,
"`db` must be applied to a struct, trait, or impl",
));
}
}
}

fn find_storage_field(&self) -> syn::Result<syn::Ident> {
fn find_storage_field(&self, input: &syn::ItemStruct) -> syn::Result<syn::Ident> {
let storage = "storage";
for field in self.input.fields.iter() {
for field in input.fields.iter() {
if let Some(i) = &field.ident {
if i == storage {
return Ok(i.clone());
Expand All @@ -56,15 +76,14 @@ impl DbMacro {
}

return Err(syn::Error::new_spanned(
&self.input.ident,
&input.ident,
"database struct must be a braced struct (`{}`) with a field named `storage`",
));
}

#[allow(non_snake_case)]
fn has_storage_impl(&self) -> syn::Result<TokenStream> {
let storage = self.find_storage_field()?;
let db = &self.input.ident;
fn has_storage_impl(&self, input: &syn::ItemStruct) -> syn::Result<TokenStream> {
let storage = self.find_storage_field(input)?;
let db = &input.ident;

let SalsaHasStorage = self.hygiene.ident("SalsaHasStorage");
let SalsaStorage = self.hygiene.ident("SalsaStorage");
Expand All @@ -86,4 +105,26 @@ impl DbMacro {
};
})
}

fn add_salsa_view_method(&self, input: &mut syn::ItemTrait) -> syn::Result<()> {
input.items.push(parse_quote! {
fn __salsa_add_view__(&self);
});
Ok(())
}

fn add_salsa_view_method_impl(&self, input: &mut syn::ItemImpl) -> syn::Result<()> {
let Some((_, TraitPath, _)) = &input.trait_ else {
return Err(syn::Error::new_spanned(
&input.self_ty,
"impl must be on a trait",
));
};
input.items.push(parse_quote! {
fn __salsa_add_view__(&self) {
salsa::storage::views(self).add::<dyn #TraitPath>(|t| t, |t| t);
}
});
Ok(())
}
}
153 changes: 0 additions & 153 deletions components/salsa-macros/src/db_view.rs

This file was deleted.

1 change: 0 additions & 1 deletion components/salsa-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ mod accumulator;
mod configuration;
mod db;
mod db_lifetime;
mod db_view;
mod debug;
mod debug_with_db;
mod input;
Expand Down
1 change: 0 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ pub use self::runtime::Runtime;
pub use self::storage::Storage;
pub use salsa_macros::accumulator;
pub use salsa_macros::db;
pub use salsa_macros::db_view;
pub use salsa_macros::input;
pub use salsa_macros::interned;
pub use salsa_macros::jar;
Expand Down
9 changes: 4 additions & 5 deletions src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ use crate::Database;

use super::ParallelDatabase;

pub fn views<Db: ?Sized + Database>(db: &Db) -> &Views {
DatabaseGen::views(db)
}

/// Salsa database methods whose implementation is generated by
/// the `#[salsa::database]` procedural macro.
///
Expand Down Expand Up @@ -43,11 +47,6 @@ pub unsafe trait DatabaseGen: Any + Send + Sync {
/// Returns a reference to the underlying.
fn views(&self) -> &Views;

/// Returns the upcasts database, tied to the type of `Self`; cannot be used from `dyn DatabaseGen` objects.
fn views_of_self(&self) -> &ViewsOf<Self>
where
Self: Sized + Database;

/// Returns the nonce for the underyling storage.
///
/// # Safety
Expand Down

0 comments on commit a1651c8

Please sign in to comment.