Allow "constant" tracked functions

This adds support for tracked functions with only a database as input,
that is, it does not take a salsa struct.
This commit is contained in:
Jack Rickard 2022-08-28 13:43:14 +01:00
parent bd7f27d72b
commit a9e24d8b0d
No known key found for this signature in database
GPG key ID: 88084D7D08A72C8A
3 changed files with 41 additions and 5 deletions

View file

@ -11,10 +11,10 @@ pub(crate) fn tracked_fn(
mut item_fn: syn::ItemFn,
) -> syn::Result<TokenStream> {
let args: FnArgs = syn::parse(args)?;
if item_fn.sig.inputs.len() <= 1 {
if item_fn.sig.inputs.is_empty() {
return Err(syn::Error::new(
item_fn.sig.ident.span(),
"tracked functions must have at least a database and salsa struct argument",
"tracked functions must have at least a database argument",
));
}
@ -332,16 +332,19 @@ fn requires_interning(item_fn: &syn::ItemFn) -> bool {
/// Every tracked fn takes a salsa struct as its second argument.
/// This fn returns the type of that second argument.
fn salsa_struct_ty(item_fn: &syn::ItemFn) -> &syn::Type {
fn salsa_struct_ty(item_fn: &syn::ItemFn) -> syn::Type {
if item_fn.sig.inputs.len() == 1 {
return parse_quote! { () };
}
match &item_fn.sig.inputs[1] {
syn::FnArg::Receiver(_) => panic!("receiver not expected"),
syn::FnArg::Typed(pat_ty) => &pat_ty.ty,
syn::FnArg::Typed(pat_ty) => (*pat_ty.ty).clone(),
}
}
fn fn_configuration(args: &FnArgs, item_fn: &syn::ItemFn) -> Configuration {
let jar_ty = args.jar_ty();
let salsa_struct_ty = salsa_struct_ty(item_fn).clone();
let salsa_struct_ty = salsa_struct_ty(item_fn);
let key_ty = if requires_interning(item_fn) {
parse_quote!(salsa::id::Id)
} else {

View file

@ -3,3 +3,7 @@ use crate::{Database, IngredientIndex};
pub trait SalsaStructInDb<DB: ?Sized + Database> {
fn register_dependent_fn(db: &DB, index: IngredientIndex);
}
impl<DB: ?Sized + Database> SalsaStructInDb<DB> for () {
fn register_dependent_fn(_db: &DB, _index: IngredientIndex) {}
}

View file

@ -0,0 +1,29 @@
//! Test that a constant `tracked` fn (has no inputs)
//! compiles and executes successfully.
#![allow(warnings)]
#[salsa::jar(db = Db)]
struct Jar(tracked_fn);
trait Db: salsa::DbWithJar<Jar> {}
#[salsa::tracked(jar = Jar)]
fn tracked_fn(db: &dyn Db) -> u32 {
44
}
#[test]
fn execute() {
#[salsa::db(Jar)]
#[derive(Default)]
struct Database {
storage: salsa::Storage<Self>,
}
impl salsa::Database for Database {}
impl Db for Database {}
let mut db = Database::default();
assert_eq!(tracked_fn(&db), 44);
}