### Example Calc Program Syntax Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/structure.md Illustrates the basic syntax of a simple calculation program that can be processed by the Salsa compiler. ```plaintext x = 5 y = 10 z = x + y * 3 print z ``` -------------------------------- ### Unit Test for Parser with expect-test Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/debug.md Write unit tests for the parser using the `expect-test` crate. This example demonstrates how to combine the `parse_string` function with `expect-test` to assert parser output. ```rust #[test] fn parse_print() { let mut db = crate::Db::default(); let expr = parse_string(&mut db, "1 + 2 * 3"); expect_test::expect_snapshot!("parse_print_snapshot", expr.debug(&db).to_string()); } ``` -------------------------------- ### Calc Language Program Example Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial.md This is an example program in the 'calc' language, demonstrating function definitions and print statements. It is used to illustrate the compiler/interpreter's functionality. ```plaintext fn area_rectangle(w, h) = w * h fn area_circle(r) = 3.14 * r * r print area_rectangle(3, 4) print area_circle(1) print 11 * 2 ``` -------------------------------- ### Configuring Fixed-Point Iteration for a Query Source: https://github.com/salsa-rs/salsa/blob/master/book/src/cycles.md Use `cycle_fn` and `cycle_initial` arguments in `salsa::tracked` to enable fixed-point iteration for a query. `cycle_initial` provides the starting value for the cycle, and `cycle_fn` handles provisional value updates during iteration. ```rust #[salsa::tracked(cycle_fn=cycle_fn, cycle_initial=cycle_initial)] fn query(db: &dyn salsa::Database) -> u32 { // ... } fn cycle_fn(_db: &dyn KnobsDatabase, _id: salsa::Id, _last_provisional_value: &u32, value: u32, _count: u32) -> u32 { value } fn cycle_initial(_db: &dyn KnobsDatabase, _id: salsa::Id) -> u32 { 0 } ``` -------------------------------- ### Query Struct Example Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/query_groups.md Represents a specific query within a query group. This struct implements the `plumbing::Query` trait, providing metadata about the query. ```rust struct LengthQuery { } ``` -------------------------------- ### Tracked Function Call Example Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/db_lifetime.md Demonstrates a typical usage pattern where a tracked function is called, and its input is updated across revisions, highlighting the need for robust lifetime management. ```rust let mut db = MyDatabase::default(); let input = MyInput::new(&db, ...); // Revision 1: let result1 = tracked_fn(&db, input); // Revision 2: input.set_field(&mut db).to (...); let result2 = tracked_fn(&db, input); ``` -------------------------------- ### Report Error Using Accumulator Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/accumulators.md An example of a memoized function `report_error` that pushes a `Diagnostic` onto the `Diagnostics` accumulator. This method is called when a parse error needs to be recorded. ```rust pub fn report_error(&mut self, error: Diagnostic) { self.diagnostics.push(error); } ``` -------------------------------- ### Define a Tracked Struct with Reference Return Source: https://github.com/salsa-rs/salsa/blob/master/book/src/overview.md Define a tracked struct 'Ast' with a field 'top_level_items' that is returned by reference. This allows callers to get an '&Ast' instead of an owned 'Ast'. ```rust #[salsa::tracked] struct Ast<'db> { #[returns(ref)] top_level_items: Vec, } ``` -------------------------------- ### Create Program Instance Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/ir.md Demonstrates creating a new 'Program' instance, which is a tracked struct. This involves providing a database reference and the value for the 'statements' field. ```rust Program::new(&db, some_statements) ``` -------------------------------- ### Creating a Salsa Input Instance Source: https://github.com/salsa-rs/salsa/blob/master/book/src/overview.md Demonstrates how to create a new instance of a Salsa input struct, `ProgramFile`, by providing the database reference and initial values for its fields. ```rust let file: ProgramFile = ProgramFile::new( &db, PathBuf::from("some_path.txt"), String::from("fn foo() { }"), ); ``` -------------------------------- ### Create SourceProgram Instance Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/ir.md Demonstrates how to create a new instance of the 'SourceProgram' input struct in the Salsa database. It requires a database reference and the value for the 'text' field. ```rust let source = SourceProgram::new(&db, "print 11 + 11".to_string()); ``` -------------------------------- ### Create and Compare Interned Structs Source: https://github.com/salsa-rs/salsa/blob/master/book/src/overview.md Create interned structs using `Word::new`. Creating structs with identical field values guarantees the same integer ID, enabling efficient equality checks. ```rust let w1 = Word::new(db, "foo".to_string()); let w2 = Word::new(db, "bar".to_string()); let w3 = Word::new(db, "foo".to_string()); ``` -------------------------------- ### Group Storage Dispatch Methods Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/query_groups.md Provides methods within the group storage to dispatch from a `DatabaseKeyIndex` to the appropriate query within the group. It matches on the query index and delegates to the query storage. ```rust {{#include ../../../components/salsa-macros/src/query_group.rs:group_storage_methods}} ``` -------------------------------- ### HelloWorld Trait Implementation for Database Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/query_groups.md Provides an implementation of the HelloWorld trait for a generic database type. Requires the database to implement `salsa::Database` and `salsa::plumbing::HasQueryGroup` for the specific query group. ```rust impl HelloWorld for DB where DB: salsa::Database, DB: salsa::plumbing::HasQueryGroup { ... fn length(&self, key: ()) -> Arc { >::get_query_table(self).get(()) } } ``` -------------------------------- ### Create a Tracked Struct Instance Source: https://github.com/salsa-rs/salsa/blob/master/book/src/overview.md Demonstrates creating an instance of a tracked struct 'Ast' within a tracked function. The 'Ast::new' function requires a database reference and the data for the struct's fields. ```rust #[salsa::tracked] fn parse_file(db: &dyn crate::Db, file: ProgramFile) -> Ast { let contents: &str = file.contents(db); let parser = Parser::new(contents); let mut top_level_items = vec![]; while let Some(item) = parser.parse_top_level_item() { top_level_items.push(item); } Ast::new(db, top_level_items) // <-- create an Ast! } ``` -------------------------------- ### Configuration for Tracked Structs Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/tracked_structs.md Illustrates the generated 'Configuration' for a tracked struct, including ID extraction and revision tracking logic. ```rust struct Configuration { // ... fields ... fn id(&self) -> Id { // ... } fn update_revisions(&mut self, new_values: &T) { // ... } } ``` -------------------------------- ### Main Driving Loop for File Watching and Recompilation Source: https://github.com/salsa-rs/salsa/blob/master/book/src/common_patterns/on_demand_inputs.md Implements a simple driving loop that recompiles code whenever a file changes. It demonstrates how to update Salsa inputs in response to file-change notifications, triggering recompilation only for affected queries. ```rust use std::sync::Arc; use std::time::Duration; use notify::{Watcher, RecursiveMode, watcher, Event, Error}; fn main() -> Result<(), Error> { let db = Arc::new(Db::new()); // Setup file watcher let db_clone = Arc::clone(&db); let mut watcher = watcher(move |event: Result| { match event { Ok(event) => { for path in event.paths { if let Some(path_str) = path.to_str() { // In a real app, you'd want to handle different event kinds // and potentially only update if the file content actually changed. // For simplicity, we re-read and update on any modification event. if let Ok(content) = std::fs::read_to_string(&path) { let file_input = File { path: path_str.to_string() }; let mut db_mut = db_clone.as_ref().clone(); // Clone to get a mutable handle db_mut.set_file(file_input, content); println!("Updated file: {}", path_str); } } } } Err(e) => println!("watch error: {:?}", e), } })?; // Watch the current directory for changes watcher.watch("./", RecursiveMode::NonRecursive)?; // Adjust path as needed println!("Watching for file changes. Press Ctrl+C to exit."); // Keep the main thread alive to process watcher events loop { std::thread::sleep(Duration::from_secs(1)); // You can perform periodic checks or other tasks here // For example, to trigger a top-level query: // let _ = db.some_query(); } } ``` -------------------------------- ### Access SourceProgram Field Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/ir.md Shows how to read the 'text' field of a 'SourceProgram' instance using its getter method. This requires a database reference. ```rust source.text(&db) ``` -------------------------------- ### Implementing DebugWithDb for an Enum Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/debug.md Forward the `DebugWithDb` implementation for ordinary enums like `Op` to maintain consistency. This allows `Op` types to be debugged using the Salsa database. ```rust impl DebugWithDb for Op { fn fmt_with_db(&self, f: &mut std::fmt::Formatter<'_>, _db: &dyn crate::Db) -> std::fmt::Result { f.debug_tuple(self.variant_name()).field(&self.to_value()).finish() } } ``` -------------------------------- ### Group Storage New Method Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/query_groups.md Generates a `new` method for the group storage struct. This method takes a group index and passes it to the `new` methods of each query storage. ```rust {{#include ../../../components/salsa-macros/src/query_group.rs:group_storage_new}} ``` -------------------------------- ### Define Input Struct for Source Program Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/ir.md Defines a simple input struct named 'SourceProgram' with a 'text' field to hold the program's source code. This struct is annotated with #[salsa::input] to indicate it's a base input for the computation. ```rust pub struct SourceProgram { text: String, } ``` -------------------------------- ### Setting Tracked Function Input with Durability Source: https://github.com/salsa-rs/salsa/blob/master/book/src/reference/algorithm.md Shows how to set the value of a tracked function with a specified durability level. Use this when certain inputs are known to be more stable than others. ```rust module_text::set_with_durability( db, module, "fn foo() { }".to_string(), salsa::Durability::HIGH ); ``` -------------------------------- ### Basic Incremental Recomputation Loop Source: https://github.com/salsa-rs/salsa/blob/master/book/src/overview.md Illustrates the fundamental loop of an incremental computation program where inputs are modified and the program is re-invoked, with the goal of faster subsequent calls. ```rust let mut input = ...; loop { let output = your_program(&input); modify(&mut input); } ``` -------------------------------- ### Accessing Input Struct Data Source: https://github.com/salsa-rs/salsa/blob/master/book/src/overview.md Shows how to retrieve the entire data associated with a Salsa input struct using the `data` method, which requires a database reference. ```rust file.data(&db) ``` -------------------------------- ### Access Program Field Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/ir.md Shows how to access the 'statements' field of a 'Program' instance using its getter. The #[returns(ref)] annotation ensures a reference is returned, avoiding unnecessary cloning. ```rust my_func.statements(db) ``` -------------------------------- ### Basic Tracked Functions: parse_module and module_text Source: https://github.com/salsa-rs/salsa/blob/master/book/src/reference/algorithm.md Defines two basic tracked functions. `parse_module` depends on `module_text`. Use these to understand fundamental dependency tracking. ```rust #[salsa::tracked] fn parse_module(db: &dyn Db, module: Module) -> Ast { let module_text: &String = module_text(db, module); Ast::parse_text(module_text) } #[salsa::tracked(returns(ref))] fn module_text(db: &dyn Db, module: Module) -> String { panic!("text for module `{module:?}` not set") } ``` -------------------------------- ### Define a Tracked Function Source: https://github.com/salsa-rs/salsa/blob/master/book/src/overview.md Define a tracked function that takes a database reference and a program file, returning an Abstract Syntax Tree (AST). Salsa tracks accessed inputs and memoizes the return value. ```rust #[salsa::tracked] fn parse_file(db: &dyn crate::Db, file: ProgramFile) -> Ast { let contents: &str = file.contents(db); ... } ``` -------------------------------- ### Implement `salsa::Database` Trait Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/db.md Implement the `salsa::Database` trait for your database struct. This is a required step for Salsa to manage your database. ```rust impl salsa::Database for Database {} ``` -------------------------------- ### Reading an Input Field Source: https://github.com/salsa-rs/salsa/blob/master/book/src/overview.md Illustrates how to read the value of a field from a Salsa input struct using its getter method, which requires a reference to the database. ```rust let contents: String = file.contents(&db); ``` -------------------------------- ### ProgramSource Struct Definition Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/structure.md Defines the basic structure to hold the source code text of a program. ```rust struct ProgramSource { text: String } ``` -------------------------------- ### QueryGroup Trait Implementation for Group Struct Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/query_groups.md The `HelloWorldStorage` struct implements the `salsa::plumbing::QueryGroup` trait, defining associated types like `DynDb` and `GroupStorage`. ```rust struct HelloWorldStorage { } impl salsa::plumbing::QueryGroup for HelloWorldStorage { type DynDb = dyn HelloWorld; type GroupStorage = HelloWorldGroupStorage__; } ``` -------------------------------- ### Generated Database Storage Struct Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/database.md Illustrates the internal storage struct generated by the `salsa::database` macro, which aggregates storage from all query groups. ```rust struct __SalsaDatabaseStorage { hello_world: >::GroupStorage } ``` -------------------------------- ### Push Values to an Accumulator Source: https://github.com/salsa-rs/salsa/blob/master/book/src/overview.md During a tracked function's execution, push values to an accumulator using `Diagnostics::push`. This collects information separately from the function's main return value. ```rust Diagnostics::push(db, "some_string".to_string()) ``` -------------------------------- ### Define `parse_statements` function with Salsa Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/parser.md This function is the entry point for parsing program source code. It is annotated with `#[salsa::tracked]` to enable memoization and input tracking by Salsa. The `returns(ref)` attribute optimizes performance by returning a reference instead of cloning the result. ```rust pub fn parse_statements(db: &dyn crate::Db, program_source: ProgramSource) -> ReadonlyVec { let mut parser = Parser::new(program_source.text(db).as_str()); parser.parse_statements() } ``` -------------------------------- ### Set SourceProgram Field Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/ir.md Illustrates how to update the 'text' field of a 'SourceProgram' instance. This operation requires a mutable database reference and increments the database revision. ```rust source.set_text(&mut db, "print 11 * 2".to_string()) ``` -------------------------------- ### Salsa Plumbing Diagram Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/diagram.md Mermaid diagram illustrating the structure of query groups, database structs, and their relationships within the Salsa crate. This diagram helps visualize the generated items and their purposes. ```mermaid graph LR classDef diagramNode text-align:left; subgraph query group HelloWorldTrait["trait HelloWorld: Database + HasQueryGroup(HelloWorldStorage)"] HelloWorldImpl["impl<DB> HelloWorld for DB
where DB: HasQueryGroup(HelloWorldStorage)"] click HelloWorldImpl "http:query_groups.html#impl-of-the-hello-world-trait" "more info" HelloWorldStorage["struct HelloWorldStorage"] click HelloWorldStorage "http:query_groups.html#the-group-struct-and-querygroup-trait" "more info" QueryGroupImpl["impl QueryGroup for HelloWorldStorage
  type DynDb = dyn HelloWorld
  type Storage = HelloWorldGroupStorage__;"] click QueryGroupImpl "http:query_groups.html#the-group-struct-and-querygroup-trait" "more info" HelloWorldGroupStorage["struct HelloWorldGroupStorage__"] click HelloWorldGroupStorage "http:query_groups.html#group-storage" "more info" subgraph for each query... LengthQuery[struct LengthQuery] LengthQueryImpl["impl Query for LengthQuery
  type Key = ()   type Value = usize   type Storage = salsa::DerivedStorage(Self)   type QueryGroup = HelloWorldStorage"] LengthQueryFunctionImpl["impl QueryFunction for LengthQuery
  fn execute(db: &dyn HelloWorld, key: ()) -> usize"] click LengthQuery "http:query_groups.html#for-each-query-a-query-struct" "more info" click LengthQueryImpl "http:query_groups.html#for-each-query-a-query-struct" "more info" click LengthQueryFunctionImpl "http:query_groups.html#for-each-query-a-query-struct" "more info" end class HelloWorldTrait,HelloWorldImpl,HelloWorldStorage,QueryGroupImpl,HelloWorldGroupStorage diagramNode; class LengthQuery,LengthQueryImpl,LengthQueryFunctionImpl diagramNode; end subgraph database DatabaseStruct["struct Database { .. storage: Storage(Self) .. }"] subgraph for each group... HasQueryGroup["impl plumbing::HasQueryGroup(HelloWorldStorage) for DatabaseStruct"] click HasQueryGroup "http:database.html#the-hasquerygroup-impl" "more info" end DatabaseStorageTypes["impl plumbing::DatabaseStorageTypes for DatabaseStruct
  type DatabaseStorage = __SalsaDatabaseStorage"] click DatabaseStorageTypes "http:database.html#the-databasestoragetypes-impl" "more info" DatabaseStorage["struct __SalsaDatabaseStorage"] click DatabaseStorage "http:database.html#the-database-storage-struct" "more info" DatabaseOps["impl plumbing::DatabaseOps for DatabaseStruct"] click DatabaseOps "http:database.html#the-databaseops-impl" "more info" class DatabaseStruct,DatabaseStorage,DatabaseStorageTypes,DatabaseOps,HasQueryGroup diagramNode; end subgraph salsa crate DerivedStorage["DerivedStorage"] class DerivedStorage diagramNode; end LengthQueryImpl --> DerivedStorage; DatabaseStruct -- "used by" --> HelloWorldImpl HasQueryGroup -- "used by" --> HelloWorldImpl ``` -------------------------------- ### Re-execution Triggered by Input Change Source: https://github.com/salsa-rs/salsa/blob/master/book/src/reference/algorithm.md Demonstrates how changing the input to `module_text` forces a re-execution of `parse_module`. Use this to observe the basic re-execution mechanism. ```rust module_text::set( db, module, "fn foo() { }".to_string(), ); parse_module(db, module); // executes // ...some time later... module_text::set( db, module, "fn foo() { /* add a comment */ }".to_string(), ); parse_module(db, module); // executes again! ``` -------------------------------- ### Define Query with Cycle Fallback Source: https://github.com/salsa-rs/salsa/blob/master/book/src/cycles.md Use `#[salsa::tracked(cycle_result=cycle_result)]` to define a query that will use a fallback value if a cycle is detected. The `cycle_result` function provides the fallback value. ```rust #[salsa::tracked(cycle_result=cycle_result)] fn query(db: &dyn salsa::Database) -> u32 { // ... } fn cycle_result(_db: &dyn KnobsDatabase, _id: salsa::Id) -> u32 { 42 } ``` -------------------------------- ### Salsa Database Trait for On-Demand Inputs Source: https://github.com/salsa-rs/salsa/blob/master/book/src/common_patterns/on_demand_inputs.md Defines a method on the `Db` trait to retrieve a `File` input on-demand. This method uses a cache (like `DashMap`) to store and retrieve file contents efficiently. ```rust use salsa::input; use std::collections::HashMap; #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct File { pub path: String, } #[salsa::database(constructor = Db::new)] pub trait Db: salsa::DbWithJar { #[input] fn file(&self, path: File) -> String; } pub struct FileJar; impl salsa::Storage for FileJar { fn get_value(&self, db: &dyn salsa::Db, key: File) -> Option { self.get(db, key) } fn set_value(&self, db: &mut dyn salsa::Db, key: File, value: String) { self.set(db, key, value) } } impl salsa::Jar for FileJar { type Database = Db; type Value = String; type Key = File; } impl Db { pub fn new() -> Self { Db { file_jar: FileJar::new() } } } ``` -------------------------------- ### Define Salsa Database Struct Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/db.md Define the main database struct for your Salsa application. This struct must be marked with `#[salsa::db]` and include a `storage` field of type `salsa::Storage`. You can add other custom fields as needed. ```rust pub struct Database { storage: salsa::Storage, // other fields can be added here } ``` -------------------------------- ### Parsing a String with Salsa Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/debug.md The `parse_string` function creates a Salsa database, sets the source text, and invokes the parser. This is a common pattern for testing parser logic. ```rust fn parse_string(db: &dyn crate::Db, s: &str) -> Expression { let id = db.allocator().alloc(s.to_string()); db.parser().parse_string(id) } ``` -------------------------------- ### Query Group Storage Structure Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/query_groups.md Defines the struct that holds all hashtables and storage for each query within a group. It is generic over the final database type. ```rust struct HelloWorldGroupStorage__ { input: ::Storage, } ``` -------------------------------- ### Declare Salsa Database Struct Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/database_and_runtime.md Declare your database struct with the `#[salsa::db]` annotation. It must include a `Storage` field for Salsa-governed data and can optionally include other user-defined fields. ```rust #[salsa::db] struct MyDatabase { storage: Storage, maybe_other_fields: u32, } ``` -------------------------------- ### Generated DatabaseStorageTypes Implementation Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/database.md Demonstrates the `DatabaseStorageTypes` trait implementation generated for the database struct. This provides essential type information for Salsa's internal operations. ```rust impl DatabaseStorageTypes for DatabaseStruct { type DynDatabase = dyn DatabaseOps; type DynamicQueryStorage = DynamicQueryStorage; type StaticQueryStorage = StaticQueryStorage; } ``` -------------------------------- ### Salsa Input Struct with `ref` Return Source: https://github.com/salsa-rs/salsa/blob/master/book/src/overview.md Defines a Salsa input struct where a specific field, `contents`, is annotated with `#[returns(ref)]` to return a reference into the database instead of cloning the value. ```rust #[salsa::input] pub struct ProgramFile { pub path: PathBuf, #[returns(ref)] pub contents: String, } ``` -------------------------------- ### Tracked Struct Wrapper with Raw Pointer Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/db_lifetime.md Illustrates the internal structure of a user-exposed tracked struct, which wraps actual fields with revision metadata using a raw pointer and PhantomData to manage lifetimes. ```rust use salsa::tracked_struct::ValueStruct; struct MyTrackedStruct<'db> { value: *const ValueStruct<..>, phantom: PhantomData<&'db ValueStruct<...>> } ``` -------------------------------- ### Enable LRU Cache Eviction for Tracked Functions Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tuning.md Specify a capacity for LRU cache eviction directly in the `salsa::tracked` attribute. This limits the number of memoized values stored for the function. ```rust #[salsa::tracked(lru = 128)] fn parse(db: &dyn Db, input: SourceFile) -> Ast { // ... } ``` -------------------------------- ### Define Salsa Database Structure Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/database.md Define the main database struct for your Salsa application. This struct will hold the storage for all query groups. ```rust struct HelloWorldStorage; #[salsa::database] struct DatabaseStruct; ``` -------------------------------- ### Modifying an Input Field Source: https://github.com/salsa-rs/salsa/blob/master/book/src/overview.md Demonstrates how to modify the value of an input field using its setter method. This operation requires a mutable reference to the database and returns a builder for advanced configurations. ```rust file.set_contents(&mut db).to(String::from("fn foo() { /* add a comment */ }")); ``` -------------------------------- ### QueryFunction Trait Implementation Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/query_groups.md Implementation of the `salsa::plumbing::QueryFunction` trait, which defines methods for executing the body of a query. Includes a call to the user's actual function. ```rust {{#include ../../../components/salsa-macros/src/query_group.rs:QueryFunction_impl}} ``` -------------------------------- ### Salsa Input Struct Definition Source: https://github.com/salsa-rs/salsa/blob/master/book/src/overview.md Defines a basic input struct for a Salsa program, specifying its path and contents. This struct will be managed by Salsa's input system. ```rust #[salsa::input] pub struct ProgramFile { pub path: PathBuf, pub contents: String, } ``` -------------------------------- ### Query Trait Implementation Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/query_groups.md Implementation of the `plumbing::Query` trait for a query struct. This provides metadata about the query and its containing group. ```rust {{#include ../../../components/salsa-macros/src/query_group.rs:Query_impl}} ``` -------------------------------- ### Generated DatabaseOps Implementation Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/database.md Presents the `DatabaseOps` trait implementation generated for the database struct. This enables operations across all query types within the database, typically by delegating to individual query groups. ```rust impl DatabaseOps for DatabaseStruct { fn for_each(&self, mut closure: &mut dyn FnMut(QueryOrigin, usize),) { self.hello_world.for_each(QueryOrigin::DATABASE, &mut closure) } } ``` -------------------------------- ### Generated HasQueryGroup Implementation Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/database.md Shows the `HasQueryGroup` trait implementation generated by the `salsa::database` macro. This allows query groups to access their definition within the database. ```rust impl HasQueryGroup for DB where DB: HasQueryGroup + ?Sized, { type GroupStorage = >::GroupStorage; fn salsa_inner_get_internal_storage( &self, ) -> &self::GroupStorage { let __self = self.salsa_inner_get_internal_storage(); __self.hello_world } } ``` -------------------------------- ### Function Struct Definition Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/structure.md Represents a function definition within the AST, including its name, arguments, and body. ```rust /// Defines `fn () = ` struct Function { name: FunctionId, args: Vec, body: Expression } ``` -------------------------------- ### Salsa Database Definition Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/generated_code.md Defines the database struct that holds the state for Salsa queries. This is essential for the runtime to manage and access query results. ```rust #[salsa::database(MyQueryGroup)] struct MyDatabase(salsa::Storage); impl MyDatabase { fn new() -> Self { Self(salsa::Storage::default()) } } ``` -------------------------------- ### Printing an interned Expression with DebugWithDb Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/debug.md Use the `debug` method from the `DebugWithDb` trait to print the value of an interned type like `Expression`. This requires access to the Salsa database. ```rust eprintln!("Expression = {:?}", expr.debug(db)); ``` -------------------------------- ### Adjust LRU Cache Capacity at Runtime Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tuning.md For functions with LRU enabled, you can dynamically change the cache capacity using the generated `set_lru_capacity` method. This method is only available on functions with the `lru` attribute. ```rust #[salsa::tracked(lru = 128)] fn my_query(db: &dyn Db, input: MyInput) -> Output { // ... } // Later, adjust the capacity: my_query::set_lru_capacity(db, 256); ``` -------------------------------- ### Generated Salsa Input Struct (Internal) Source: https://github.com/salsa-rs/salsa/blob/master/book/src/overview.md Shows the internal representation of a Salsa input struct after macro expansion, highlighting that it's a newtyped integer ID rather than a data-holding struct. ```rust // Generated by the `#[salsa::input]` macro: #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct ProgramFile(salsa::Id); ``` -------------------------------- ### Accessing Tracked Struct Field with Dynamic Reference Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/db_lifetime.md Shows how a raw pointer within a tracked struct is converted into a valid Rust reference to the field's data when an accessor method is invoked. ```rust impl<'db> MyTrackedStruct<'db> { fn field(self, db: &'db dyn DB) -> &'db FieldType { ... } } ``` -------------------------------- ### Op Enum Definition Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/structure.md Enumerates the supported arithmetic operations for expressions. ```rust enum Op { Add, Subtract, Multiply, Divide, } ``` -------------------------------- ### Generated Code for a Query Group Trait Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/query_groups.md This snippet shows the code generated by the `salsa::query_group` macro for a query group trait. It includes the trait itself, the group struct, blanket implementations, query structs, and group storage. ```rust trait HelloWorld: salsa::Database + salsa::plumbing::HasQueryGroup { fn input_string(&self, key: ()) -> Arc; fn set_input_string(&mut self, key: (), value: Arc); fn length(&self, key: ()) -> usize; } struct HelloWorldStorage { } impl salsa::plumbing::QueryGroup for HelloWorldStorage { type DynDb = dyn HelloWorld; type GroupStorage = HelloWorldGroupStorage__; } impl HelloWorld for DB where DB: salsa::Database, DB: salsa::plumbing::HasQueryGroup, { ... } pub struct InputQuery { } impl InputQuery { /* definition for `in_db`, etc */ } impl salsa::Query for InputQuery { /* associated types */ } pub struct LengthQuery { } impl salsa::Query for LengthQuery { ... } impl salsa::QueryFunction for LengthQuery { ... } struct HelloWorldGroupStorage__ { .. } ``` -------------------------------- ### Define Statements and Expressions Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/ir.md Defines the `Body`, `Expr`, and `Stmt` types for representing function bodies, expressions, and statements in the IR. These are not tracked by Salsa, meaning changes to a function body trigger re-execution of the entire body. ```rust pub type Body = Vec; #[derive(Debug, Clone)] pub enum Expr { Variable(VariableId), FunctionCall(FunctionId, Vec), } #[derive(Debug, Clone)] pub enum Stmt { Declaration(VariableId, Expr), Return(Expr), } ``` -------------------------------- ### Define Tracked Struct for Parsed Program Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/ir.md Defines a 'Program' struct annotated with #[salsa::tracked] to represent intermediate parsed program data. It contains an immutable 'statements' field. ```rust pub struct Program { statements: Vec, } ``` -------------------------------- ### Define an Accumulator for Diagnostics Source: https://github.com/salsa-rs/salsa/blob/master/book/src/overview.md Declare a type as an accumulator using `#[salsa::accumulator]` to collect side-channel information like errors. The accumulator must be a newtype of a primitive type. ```rust #[salsa::accumulator] pub struct Diagnostics(String); ``` -------------------------------- ### Define Function Struct Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/ir.md Defines the `Function` struct, a tracked struct used to represent user-defined functions in the IR. It includes fields for name, arguments, and body. ```rust pub struct Function { pub name: FunctionId, pub args: Vec, pub body: Body, } ``` -------------------------------- ### Statement Enum Definition Source: https://github.com/salsa-rs/salsa/blob/master/book/src/tutorial/structure.md Defines the possible types of statements within the calc program's abstract syntax tree (AST). ```rust enum Statement { /// Defines `fn () = ` Function(Function), /// Defines `print ` Print(Expression), } ``` -------------------------------- ### Define an Interned Struct Source: https://github.com/salsa-rs/salsa/blob/master/book/src/overview.md Define an interned struct using `#[salsa::interned]` for efficient equality comparisons, commonly used for strings or primitive values. The struct itself is a newtyped integer, with data stored in the database. ```rust #[salsa::interned] struct Word { #[returns(ref)] pub text: String, } ``` -------------------------------- ### Tracked Function with Diagnostics Accumulation Source: https://github.com/salsa-rs/salsa/blob/master/book/src/overview.md A tracked function can push diagnostic messages to an accumulator. These messages can be retrieved later using the `accumulated` function. ```rust #[salsa::tracked] fn type_check(db: &dyn Db, item: Item) { // ... Diagnostics::push(db, "some error message".to_string()) // ... } ``` -------------------------------- ### Define a Tracked Struct with an ID Field Source: https://github.com/salsa-rs/salsa/blob/master/book/src/overview.md Define a tracked struct 'Item' with a field 'name' tagged as `#[id]`. This field will be used by Salsa to match struct instances across executions, preventing unnecessary recomputation when only the order changes. ```rust #[salsa::tracked] struct Item { #[id] name: Word, // we'll define Word in a second! ... } ``` -------------------------------- ### Salsa Query Group Definition Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/generated_code.md Defines the query group trait for the Salsa runtime. This is a core part of how Salsa manages reactive queries. ```rust trait MyQueryGroup { #[salsa::query] fn foo(&self) -> u32; } ``` -------------------------------- ### ValueStruct Definition Source: https://github.com/salsa-rs/salsa/blob/master/book/src/plumbing/tracked_structs.md Defines the structure for storing field values and their revision history for tracked structs. ```rust struct ValueStruct { values: Vec, revisions: Vec, } ``` -------------------------------- ### Specify Tracked Function Results Source: https://github.com/salsa-rs/salsa/blob/master/book/src/overview.md Use the `specify` flag and method to externally set the result of a tracked function for specific structs. This is useful for hard-coding values or simulating initialized fields. ```rust #[salsa::tracked(specify)] // <-- specify flag required fn representation(db: &dyn crate::Db, item: Item) -> Representation { // read the user's input AST by default let ast = ast(db, item); // ... } fn create_builtin_item(db: &dyn crate::Db) -> Item { let i = Item::new(db, ...); let r = hardcoded_representation(); representation::specify(db, i, r); // <-- use the method! i } ```