support methods with 'db lifetimes

This commit is contained in:
Niko Matsakis 2024-05-23 20:52:06 -04:00
parent b005820494
commit 1560634f96
2 changed files with 21 additions and 9 deletions

View file

@ -142,6 +142,7 @@ pub(crate) fn tracked_impl(
}; };
let name = format!("{}_{}", name_prefix, item_method.sig.ident); let name = format!("{}_{}", name_prefix, item_method.sig.ident);
Some(tracked_method( Some(tracked_method(
&item_impl.generics,
&args, &args,
inner_args, inner_args,
item_method, item_method,
@ -160,11 +161,14 @@ pub(crate) fn tracked_impl(
acc acc
})?; })?;
Ok(quote! { Ok(crate::debug::dump_tokens(
#item_impl self_type_name,
quote! {
#item_impl
#(#extra_impls)* #(#extra_impls)*
}) },
))
} }
struct TrackedImpl; struct TrackedImpl;
@ -192,6 +196,7 @@ impl crate::options::AllowedOptions for TrackedImpl {
} }
fn tracked_method( fn tracked_method(
impl_generics: &syn::Generics,
outer_args: &ImplArgs, outer_args: &ImplArgs,
mut args: FnArgs, mut args: FnArgs,
item_method: &mut syn::ImplItemFn, item_method: &mut syn::ImplItemFn,
@ -214,6 +219,12 @@ fn tracked_method(
block: Box::new(rename_self_in_block(item_method.block.clone())?), block: Box::new(rename_self_in_block(item_method.block.clone())?),
}; };
item_fn.sig.ident = syn::Ident::new(name, item_fn.sig.ident.span()); item_fn.sig.ident = syn::Ident::new(name, item_fn.sig.ident.span());
// Insert the generics from impl at the start of the fn generics
for parameter in impl_generics.params.iter().rev() {
item_fn.sig.generics.params.insert(0, parameter.clone());
}
// Flip the first and second arguments as the rest of the code expects the // Flip the first and second arguments as the rest of the code expects the
// database to come first and the struct to come second. We also need to // database to come first and the struct to come second. We also need to
// change the self argument to a normal typed argument called __salsa_self. // change the self argument to a normal typed argument called __salsa_self.
@ -222,6 +233,7 @@ fn tracked_method(
syn::FnArg::Receiver(r) if r.reference.is_none() => r, syn::FnArg::Receiver(r) if r.reference.is_none() => r,
arg => return Err(syn::Error::new(arg.span(), "first argument must be self")), arg => return Err(syn::Error::new(arg.span(), "first argument must be self")),
}; };
let db_param = original_inputs.next().unwrap().into_value(); let db_param = original_inputs.next().unwrap().into_value();
let mut inputs = syn::punctuated::Punctuated::new(); let mut inputs = syn::punctuated::Punctuated::new();
inputs.push(db_param); inputs.push(db_param);

View file

@ -1,24 +1,24 @@
pub trait Db: salsa::DbWithJar<Jar> {} pub trait Db: salsa::DbWithJar<Jar> {}
#[salsa::jar(db = Db)] #[salsa::jar(db = Db)]
pub struct Jar(SourceTree, SourceTree_all_items, use_tree); pub struct Jar(SourceTree<'_>, SourceTree_all_items, use_tree);
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
pub struct Item {} pub struct Item {}
#[salsa::tracked(jar = Jar)] #[salsa::tracked(jar = Jar)]
pub struct SourceTree {} pub struct SourceTree<'db> {}
#[salsa::tracked(jar = Jar)] #[salsa::tracked(jar = Jar)]
impl SourceTree { impl<'db> SourceTree<'db> {
#[salsa::tracked(return_ref)] #[salsa::tracked(return_ref)]
pub fn all_items(self, _db: &dyn Db) -> Vec<Item> { pub fn all_items(self, _db: &'db dyn Db) -> Vec<Item> {
todo!() todo!()
} }
} }
#[salsa::tracked(jar = Jar, return_ref)] #[salsa::tracked(jar = Jar, return_ref)]
fn use_tree(_db: &dyn Db, _tree: SourceTree) {} fn use_tree<'db>(_db: &'db dyn Db, _tree: SourceTree<'db>) {}
#[allow(unused)] #[allow(unused)]
fn use_it(db: &dyn Db, tree: SourceTree) { fn use_it(db: &dyn Db, tree: SourceTree) {