diff --git a/book/src/overview.md b/book/src/overview.md index 2909aed5..4bf6056c 100644 --- a/book/src/overview.md +++ b/book/src/overview.md @@ -56,16 +56,18 @@ pub struct ProgramFile { ``` You create an input by using the `new` method. -Because the values of input fields are stored in the database, you also give an `&mut`-reference to the database: +Because the values of input fields are stored in the database, you also give an `&`-reference to the database: ```rust let file: ProgramFile = ProgramFile::new( - &mut db, + &db, PathBuf::from("some_path.txt"), String::from("fn foo() { }"), ); ``` +Mutable access is not needed since creating a new input cannot affect existing tracked data in the database. + ### Salsa structs are just integers The `ProgramFile` struct generated by the `salsa::input` macro doesn't actually store any data. It's just a newtyped integer id: @@ -111,7 +113,8 @@ file.data(&db) ### Writing input fields Finally, you can also modify the value of an input field by using the setter method. -Since this is modifying the input, the setter takes an `&mut`-reference to the database: +Since this is modifying the input, and potentially invalidating data derived from it, +the setter takes an `&mut`-reference to the database: ```rust file.set_contents(&mut db).to(String::from("fn foo() { /* add a comment */ }")); @@ -140,7 +143,7 @@ The algorithm Salsa uses to decide when a tracked function needs to be re-execut Tracked functions have to follow a particular structure: - They must take a `&`-reference to the database as their first argument. - - Note that because this is an `&`-reference, it is not possible to create or modify inputs during a tracked function! + - Note that because this is an `&`-reference, it is not possible to modify inputs during a tracked function! - They must take a "Salsa struct" as the second argument -- in our example, this is an input struct, but there are other kinds of Salsa structs we'll describe shortly. - They _can_ take additional arguments, but it's faster and better if they don't. diff --git a/book/src/plumbing/db_lifetime.md b/book/src/plumbing/db_lifetime.md index da2327bd..541f3d3a 100644 --- a/book/src/plumbing/db_lifetime.md +++ b/book/src/plumbing/db_lifetime.md @@ -169,7 +169,7 @@ The reason we use a raw pointer in the struct is because instances of this struc ```rust let mut db = MyDatabase::default(); -let input = MyInput::new(&mut db, ...); +let input = MyInput::new(&db, ...); // Revision 1: let result1 = tracked_fn(&db, input); @@ -235,4 +235,4 @@ However in some later revision R2, how ### Freeing the memory while a tracked struct remains live -### Aliases of a tracked struct \ No newline at end of file +### Aliases of a tracked struct diff --git a/book/src/tutorial/ir.md b/book/src/tutorial/ir.md index 0105535a..9e327f53 100644 --- a/book/src/tutorial/ir.md +++ b/book/src/tutorial/ir.md @@ -52,10 +52,10 @@ pub struct SourceProgram(salsa::Id); ``` It will also generate a method `new` that lets you create a `SourceProgram` in the database. -For an input, a `&mut db` reference is required, along with the values for each field: +For an input, a `&db` reference is required, along with the values for each field: ```rust -let source = SourceProgram::new(&mut db, "print 11 + 11".to_string()); +let source = SourceProgram::new(&db, "print 11 + 11".to_string()); ``` You can read the value of the field with `source.text(&db)`, @@ -90,7 +90,7 @@ then subsequent parts of the computation won't need to re-execute. Apart from the fields being immutable, the API for working with a tracked struct is quite similar to an input: -* You can create a new value by using `new`, but with a tracked struct, you only need an `&dyn` database, not `&mut` (e.g., `Program::new(&db, some_staements)`) +* You can create a new value by using `new`: e.g., `Program::new(&db, some_statements)` * You use a getter to read the value of a field, just like with an input (e.g., `my_func.statements(db)` to read the `statements` field). * In this case, the field is tagged as `#[return_ref]`, which means that the getter will return a `&Vec`, instead of cloning the vector. @@ -123,7 +123,7 @@ This would mean that we have to re-execute those parts of the code that depended Apart from the fields being immutable, the API for working with a tracked struct is quite similar to an input: -* You can create a new value by using `new`, but with a tracked struct, you only need an `&dyn` database, not `&mut` (e.g., `Function::new(&db, some_name, some_args, some_body)`) +* You can create a new value by using `new`: e.g., `Function::new(&db, some_name, some_args, some_body)` * You use a getter to read the value of a field, just like with an input (e.g., `my_func.args(db)` to read the `args` field). ### id fields