make the QueryTable impl totally generic

This commit is contained in:
Niko Matsakis 2019-01-24 05:28:46 -05:00
parent 2924e98f40
commit 8ad5051a74
3 changed files with 33 additions and 60 deletions

View file

@ -49,12 +49,6 @@ pub(crate) fn database_storage(input: TokenStream) -> TokenStream {
})
.collect();
let each_query = || {
query_groups
.iter()
.flat_map(|query_group| query_group.queries.iter().map(move |q| (query_group, q)))
};
// For each query group `foo::MyGroup` create a link to its
// `foo::MyGroupGroupStorage`
let mut storage_fields = proc_macro2::TokenStream::new();
@ -187,52 +181,6 @@ pub(crate) fn database_storage(input: TokenStream) -> TokenStream {
}
});
let mut for_each_query_table = proc_macro2::TokenStream::new();
for (
query_group,
Query {
query_name,
query_type,
},
) in each_query()
{
let group_storage = query_group.group_storage();
let group_descriptor = query_group.group_descriptor();
for_each_query_table.extend(quote! {
impl ::salsa::plumbing::GetQueryTable<#query_type> for #database_name {
fn get_query_table(
db: &Self,
) -> ::salsa::QueryTable<'_, Self, #query_type> {
let storage: &#group_storage<#database_name> = ::salsa::plumbing::GetQueryGroupStorage::from(db);
::salsa::QueryTable::new(
db,
&storage.#query_name,
)
}
fn get_query_table_mut(
db: &mut Self,
) -> ::salsa::QueryTableMut<'_, Self, #query_type> {
let db = &*db;
let storage: &#group_storage<#database_name> = ::salsa::plumbing::GetQueryGroupStorage::from(db);
::salsa::QueryTableMut::new(
db,
&storage.#query_name,
)
}
fn descriptor(
db: &Self,
key: <#query_type as ::salsa::Query<Self>>::Key,
) -> <Self as ::salsa::plumbing::DatabaseStorageTypes>::QueryDescriptor {
<Self as ::salsa::plumbing::GetDatabaseDescriptor<_>>::from(#group_descriptor::#query_name(key))
}
}
});
}
output.extend(for_each_query_table);
output.extend(storage_impls);
output.extend(descriptor_impls);
@ -254,7 +202,6 @@ struct DatabaseStorage {
struct QueryGroup {
query_group: Path,
queries: Vec<Query>,
}
impl QueryGroup {
@ -299,6 +246,7 @@ impl QueryGroup {
}
}
#[allow(dead_code)]
struct Query {
query_name: Ident,
query_type: Path,
@ -336,11 +284,8 @@ impl Parse for QueryGroup {
let query_group: Path = input.parse()?;
let content;
syn::braced!(content in input);
let queries: Vec<Query> = parse_while(Token![fn ], &content)?;
Ok(QueryGroup {
query_group,
queries,
})
let _queries: Vec<Query> = parse_while(Token![fn ], &content)?;
Ok(QueryGroup { query_group })
}
}

View file

@ -199,12 +199,11 @@ pub(crate) fn query_group(args: TokenStream, input: TokenStream) -> TokenStream
// Emit an impl of the trait
output.extend({
let qts = queries.iter().map(|q| &q.query_type);
let bounds = &input.supertraits;
quote! {
impl<T> #trait_name for T
where
T: #(salsa::plumbing::GetQueryTable<#qts> +)* #bounds,
T: #bounds,
T: ::salsa::plumbing::GetQueryGroupStorage<#group_storage<T>>,
T: ::salsa::plumbing::GetDatabaseDescriptor<#group_descriptor>,
{

View file

@ -81,6 +81,35 @@ pub trait GetQueryTable<Q: Query<Self>>: Database {
fn descriptor(db: &Self, key: Q::Key) -> Self::QueryDescriptor;
}
impl<DB, Q> GetQueryTable<Q> for DB
where
DB: Database,
Q: Query<DB>,
DB: GetQueryGroupStorage<Q::GroupStorage>,
DB: GetDatabaseDescriptor<Q::GroupDescriptor>,
{
fn get_query_table(db: &DB) -> QueryTable<'_, DB, Q> {
let group_storage: &Q::GroupStorage = GetQueryGroupStorage::from(db);
let query_storage = Q::storage(group_storage);
QueryTable::new(db, query_storage)
}
fn get_query_table_mut(db: &mut DB) -> QueryTableMut<'_, DB, Q> {
let db = &*db;
let group_storage: &Q::GroupStorage = GetQueryGroupStorage::from(db);
let query_storage = Q::storage(group_storage);
QueryTableMut::new(db, query_storage)
}
fn descriptor(
_db: &DB,
key: <Q as Query<DB>>::Key,
) -> <DB as DatabaseStorageTypes>::QueryDescriptor {
let group_descriptor = Q::descriptor(key);
<DB as GetDatabaseDescriptor<_>>::from(group_descriptor)
}
}
/// Access the "group storage" with type `S` from the database.
///
/// This basically moves from the full context of the database to the context