From 4c4096e39bb4b2563eb4b644b5cdd4177289ee8b Mon Sep 17 00:00:00 2001 From: XFFXFF <1247714429@qq.com> Date: Tue, 13 Sep 2022 08:18:19 +0800 Subject: [PATCH] panic when reading fields of tracked structs from older revisions --- .../src/function/maybe_changed_after.rs | 14 ++++-- ...of-tracked-structs-from-older-revisions.rs | 46 +++++++++++++++++++ 2 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 salsa-2022-tests/tests/panic-when-reading-fields-of-tracked-structs-from-older-revisions.rs diff --git a/components/salsa-2022/src/function/maybe_changed_after.rs b/components/salsa-2022/src/function/maybe_changed_after.rs index 2888b451..391d7068 100644 --- a/components/salsa-2022/src/function/maybe_changed_after.rs +++ b/components/salsa-2022/src/function/maybe_changed_after.rs @@ -170,12 +170,18 @@ where // during this revision or is otherwise stale. return false; } - QueryOrigin::BaseInput | QueryOrigin::Field => { - // BaseInput: This value was `set` by the mutator thread -- ie, it's a base input and it cannot be out of date. - // Field: This value is the value of a field of some tracked struct S. It is always updated whenever S is created. - // So if a query has access to S, then they will have an up-to-date value. + QueryOrigin::BaseInput => { + // This value was `set` by the mutator thread -- ie, it's a base input and it cannot be out of date. return true; } + QueryOrigin::Field => { + // This value is the value of a field of some tracked struct S. + // The fact that we are here means that we are accessing fields from old revisions, which is not allowed. + panic!( + "accessing fields of tracked struct {:?} from older revisions", + std::any::type_name::<::SalsaStruct>() + ) + } QueryOrigin::DerivedUntracked(_) => { // Untracked inputs? Have to assume that it changed. return false; diff --git a/salsa-2022-tests/tests/panic-when-reading-fields-of-tracked-structs-from-older-revisions.rs b/salsa-2022-tests/tests/panic-when-reading-fields-of-tracked-structs-from-older-revisions.rs new file mode 100644 index 00000000..92304133 --- /dev/null +++ b/salsa-2022-tests/tests/panic-when-reading-fields-of-tracked-structs-from-older-revisions.rs @@ -0,0 +1,46 @@ +use test_log::test; + +#[salsa::jar(db = Db)] +struct Jar(MyInput, MyTracked, tracked_fn); + +trait Db: salsa::DbWithJar {} + +#[salsa::input(jar = Jar)] +struct MyInput { + field: u32, +} + +#[salsa::tracked(jar = Jar)] +struct MyTracked { + field: u32, +} + +#[salsa::tracked(jar = Jar)] +fn tracked_fn(db: &dyn Db, input: MyInput) -> MyTracked { + MyTracked::new(db, input.field(db) / 2) +} + +#[salsa::db(Jar)] +#[derive(Default)] +struct Database { + storage: salsa::Storage, +} + +impl salsa::Database for Database {} + +impl Db for Database {} + +#[test] +#[should_panic(expected = "accessing fields of tracked struct")] +fn execute() { + let mut db = Database::default(); + + let input = MyInput::new(&mut db, 22); + let tracked = tracked_fn(&db, input); + + // modify the input and change the revision + input.set_field(&mut db).to(24); + + // panic when reading fields of tracked structs from older revisions + tracked.field(&db); +}