我实现了非 tracked structs 结构的, 或者说是递归型式的例子. 但不知道怎么来实现tracked的例子.
也许可能是手动展开如下代码? 另外,如果可行,那如何derive两次呢?
#[tracked]
fn data(&self, db: &DbType<'_>) -> SourceProgramData {
SourceProgramData {
// text: self.text(db).clone(),
text: Test::<String, DbType<'_>, String>::match_data_type(self.text(db), db),
}
}
递归型式的例子:
use derive_new::new;
use ordered_float::OrderedFloat;
use crate::db::{self, Database};
// ANCHOR: input
#[salsa::input]
pub struct SourceProgram {
#[return_ref]
text: String,
}
pub struct SourceProgramData {
text: String,
}
/// impl DataWithDb for T, for get TData
trait DataWithDb<Db: ?Sized, TData> {
fn data(&self, db: &Db) -> TData;
}
type DbType<'a> = <crate::Jar as salsa::jar::Jar<'a>>::DynDb;
impl DataWithDb<DbType<'_>, SourceProgramData> for SourceProgram {
fn data(&self, db: &DbType<'_>) -> SourceProgramData {
SourceProgramData {
// text: self.text(db).clone(),
text: Test::<String, DbType<'_>, String>::match_data_type(self.text(db), db),
}
}
}
trait Fallback<Db>
where
Db: ?Sized,
{
fn match_data_type<'a, 'b: 'a, T: Clone>(a: &T, db: &'b Db) -> T {
a.clone()
}
}
impl<T, Db> Fallback<Db> for T
where
T: ?Sized,
Db: ?Sized,
{
}
#[allow(dead_code)]
impl<T, Db, TData> Test<T, Db, TData>
where
T: DataWithDb<Db, TData>,
Db: ?Sized,
TData: Sized,
{
fn match_data_type<'a, 'b: 'a>(a: &'a T, db: &'b Db) -> TData {
a.data(db)
}
}
struct Test<T: ?Sized, Db: ?Sized, TData: Sized>(
core::marker::PhantomData<T>,
core::marker::PhantomData<Db>,
core::marker::PhantomData<TData>,
);
#[test]
fn getData() {
let mut db = db::Database::default();
let source_program = SourceProgram::new(&mut db, "aaa".into());
println!("{:#?}", source_program.data(&db).text);
}
1
共 2 条评论, 1 页
评论区
写评论https://github.com/salsa-rs/salsa/pull/392/files
无论声明宏还是过程宏,它们实际上只是处理手写的代码,生成手写的代码,不会知道那些代码是什么意思
请教一下, 想(属性)宏A展开得到B,B再去展开得到C. 这种有没有教程的?[捂脸]
不能这样套娃的
那可能解法是, 看看可不可以一起 写到salsa_macro里. 觉得 好像这样是有机会实现 增量的.