# 2025-06-11 ## Niko's schedule / enabling changes? * Niko to be offline for about 3 weeks from end of June to July 15 or so * Add Micha and Carl as admins to the github org and whatever else ## Agenda * What version are we at * Updates on what has changed recently * Open discussion topics * How we panic (on cycles without cycle handling) * Context: https://salsa.zulipchat.com/#narrow/channel/333573-Contributing-to-Salsa/topic/Cycle.20panic.20debug.20info/with/522204789 * Persistent caching * `salsa::one_big_query` * Lukas and David realized at RustWeek that we could probably save a bunch of memory in rust-analyzer if we're able to throw away fine-grained tracking for queries/crates that we know don't need need fine-grained invalidation (e.g., crates from `crates.io`). * This is an evolution of Matklad's idea to optimize durability: https://salsa.zulipchat.com/#narrow/channel/145099-Using-Salsa/topic/Optimizing.20Durability/near/486964262, which is "After durability of a query is determined, remove all dependencies with higher durability from the list of dependencies." ## Recent changes Muiltithreaded fixed point issues resolved Garbage collection of interned values: Increased size of an id to 64 bits. Decided to create fresh ids whenever a slot is reused. Which in turn allowed removing some things from tracked structs and reduced memory usage in some cases but not for rust-analyzer. Why was it needed? Niko thought it wouldn't be because the interning task would be re-executed, but the problem was that this interacted poorly with backdating since reads are not tracked. Side note for Niko: think again about modeling this stuff formally and reasoning about why it is sound for tracked structs. Need to be careful about high-durability values, we can't collect them because it would require mutable access to bump the "durability changed" index. For low durability it's ok because the value will have changed. ## How we panic * Why do we want more data anyway? Why not just a string? * For better error reporting, but you can capture the query backtrace * doesn't "completely work" because of "the refcell stuff" * sometimes doesn't capture anything if the query is mutably borrowed * currently put that query stack into the string message by default * Conclusion: * leave it as it is until we have a strong motivation ## One Big Query * Can we improve memory usage by discarding dependency data? * Maybe we unify this with durability * Maybe with `salsa::durability::High`, we'll need to re-execute everything and discard dependency tracking informaton. * alternative formulation: flatten list of dependencies * Can we do things more efficiently in a batch fashion rather than doing them one-by-one * Outdated branch of a MVP implementation of a fourth durability `Immutable`: https://github.com/Veykril/salsa/tree/lw-vrslyxmrynxn ```rust #[salsa::tracked] struct Struct { fields: Vec<Field> } #[salsa::tracked] struct Field { } fn get_struct(db: &dyn crate::Db, path: Path) -> Struct { if /* path is in external crate */ { let all_structs = process_eternal_crate(); all_structs.find(|s| s.name() == name) } else { process_one_struct(...) } } #[salsa::tracked] fn process_external_crate(db: &dyn crate::Db, source: CrateId) -> Vec<Struct> { for item in source.all_asts(db) { let item = Struct::new(db, ...); } ... } #[salsa::tracked] fn process_one_struct(db: &dyn crate::Db, struct_ast: StructAst) -> Struct { Struct::new(db, ...) } ``` David also realized that this would be nice for lazily loading things in an IDE: ```rust #[salsa::tracked] gen fn process_external_crate(db: &dyn crate::Db, source: CrateId) -> Struct { for item in source.all_asts(db) { yield Struct::new(db, ...); } ... } ``` ## Serialization - Prior work: https://hackmd.io/pFbiXVsuTTK4pakI___MTA ## Option to disable LRU for interneds on a per interned basis