fix: Access to tracked-struct that was freed during fixpoint (#817)

* Add test for untracked read on tracked struct created in previous cycle

* Initial fix

* Restrict seeding to memos from the same revision

* Reduce changes

* seed_outputs

* Cleanup test

* Add assertion

* Try

* Try merging outputs after query executed

* Assert logs from first execution

* Enable trace level logging

* Use `FxIndexSet` in `diff_outputs`

* Log more events

* Cleanup

* Append outputs only once
This commit is contained in:
Micha Reiser 2025-04-28 16:24:33 +02:00 committed by GitHub
parent 0cbe7f86ab
commit b27e3927e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 206 additions and 19 deletions

View file

@ -59,6 +59,18 @@ where
// Query was not previously executed, or value is potentially
// stale, or value is absent. Let's execute!
let mut new_value = C::execute(db, C::id_to_input(db, id));
if let Some(old_memo) = opt_old_memo {
// Copy over all outputs from a previous iteration.
// This is necessary to ensure that tracked struct created during the previous iteration
// (and are owned by the query) are alive even if the query in this iteration no longer creates them.
// The query not re-creating the tracked struct doesn't guarantee that there
// aren't any other queries depending on it.
if old_memo.may_be_provisional() && old_memo.verified_at.load() == revision_now {
active_query.append_outputs(old_memo.revisions.origin.outputs());
}
}
let mut revisions = active_query.pop();
// Did the new result we got depend on our own provisional value, in a cycle?