This commit is contained in:
github-merge-queue[bot] 2024-06-18 10:53:01 +00:00
parent 28f91f75fd
commit d570c71faa
6 changed files with 24 additions and 20 deletions

View file

@ -198,17 +198,18 @@ pub struct ProgramFile {
<span class="boring">}
</span></code></pre></pre>
<p>You create an input by using the <code>new</code> method.
Because the values of input fields are stored in the database, you also give an <code>&amp;mut</code>-reference to the database:</p>
Because the values of input fields are stored in the database, you also give an <code>&amp;</code>-reference to the database:</p>
<pre><pre class="playground"><code class="language-rust">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let file: ProgramFile = ProgramFile::new(
&amp;mut db,
&amp;db,
PathBuf::from(&quot;some_path.txt&quot;),
String::from(&quot;fn foo() { }&quot;),
);
<span class="boring">}
</span></code></pre></pre>
<p>Mutable access is not needed since creating a new input cannot affect existing tracked data in the database.</p>
<h3 id="salsa-structs-are-just-integers"><a class="header" href="#salsa-structs-are-just-integers">Salsa structs are just integers</a></h3>
<p>The <code>ProgramFile</code> struct generated by the <code>salsa::input</code> macro doesn't actually store any data. It's just a newtyped integer id:</p>
<pre><pre class="playground"><code class="language-rust">
@ -253,7 +254,8 @@ pub struct ProgramFile {
</span></code></pre></pre>
<h3 id="writing-input-fields"><a class="header" href="#writing-input-fields">Writing input fields</a></h3>
<p>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 <code>&amp;mut</code>-reference to the database:</p>
Since this is modifying the input, and potentially invalidating data derived from it,
the setter takes an <code>&amp;mut</code>-reference to the database:</p>
<pre><pre class="playground"><code class="language-rust">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
@ -282,7 +284,7 @@ The algorithm Salsa uses to decide when a tracked function needs to be re-execut
<ul>
<li>They must take a <code>&amp;</code>-reference to the database as their first argument.
<ul>
<li>Note that because this is an <code>&amp;</code>-reference, it is not possible to create or modify inputs during a tracked function!</li>
<li>Note that because this is an <code>&amp;</code>-reference, it is not possible to modify inputs during a tracked function!</li>
</ul>
</li>
<li>They must take a &quot;Salsa struct&quot; as the second argument -- in our example, this is an input struct, but there are other kinds of Salsa structs we'll describe shortly.</li>

View file

@ -304,7 +304,7 @@ struct MyTrackedStruct&lt;'db&gt; {
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let mut db = MyDatabase::default();
let input = MyInput::new(&amp;mut db, ...);
let input = MyInput::new(&amp;db, ...);
// Revision 1:
let result1 = tracked_fn(&amp;db, input);

View file

@ -215,17 +215,18 @@ pub struct ProgramFile {
<span class="boring">}
</span></code></pre></pre>
<p>You create an input by using the <code>new</code> method.
Because the values of input fields are stored in the database, you also give an <code>&amp;mut</code>-reference to the database:</p>
Because the values of input fields are stored in the database, you also give an <code>&amp;</code>-reference to the database:</p>
<pre><pre class="playground"><code class="language-rust">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let file: ProgramFile = ProgramFile::new(
&amp;mut db,
&amp;db,
PathBuf::from(&quot;some_path.txt&quot;),
String::from(&quot;fn foo() { }&quot;),
);
<span class="boring">}
</span></code></pre></pre>
<p>Mutable access is not needed since creating a new input cannot affect existing tracked data in the database.</p>
<h3 id="salsa-structs-are-just-integers"><a class="header" href="#salsa-structs-are-just-integers">Salsa structs are just integers</a></h3>
<p>The <code>ProgramFile</code> struct generated by the <code>salsa::input</code> macro doesn't actually store any data. It's just a newtyped integer id:</p>
<pre><pre class="playground"><code class="language-rust">
@ -270,7 +271,8 @@ pub struct ProgramFile {
</span></code></pre></pre>
<h3 id="writing-input-fields"><a class="header" href="#writing-input-fields">Writing input fields</a></h3>
<p>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 <code>&amp;mut</code>-reference to the database:</p>
Since this is modifying the input, and potentially invalidating data derived from it,
the setter takes an <code>&amp;mut</code>-reference to the database:</p>
<pre><pre class="playground"><code class="language-rust">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
@ -299,7 +301,7 @@ The algorithm Salsa uses to decide when a tracked function needs to be re-execut
<ul>
<li>They must take a <code>&amp;</code>-reference to the database as their first argument.
<ul>
<li>Note that because this is an <code>&amp;</code>-reference, it is not possible to create or modify inputs during a tracked function!</li>
<li>Note that because this is an <code>&amp;</code>-reference, it is not possible to modify inputs during a tracked function!</li>
</ul>
</li>
<li>They must take a &quot;Salsa struct&quot; as the second argument -- in our example, this is an input struct, but there are other kinds of Salsa structs we'll describe shortly.</li>
@ -761,11 +763,11 @@ pub struct SourceProgram(salsa::Id);
<span class="boring">}
</span></code></pre></pre>
<p>It will also generate a method <code>new</code> that lets you create a <code>SourceProgram</code> in the database.
For an input, a <code>&amp;mut db</code> reference is required, along with the values for each field:</p>
For an input, a <code>&amp;db</code> reference is required, along with the values for each field:</p>
<pre><pre class="playground"><code class="language-rust">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let source = SourceProgram::new(&amp;mut db, &quot;print 11 + 11&quot;.to_string());
</span>let source = SourceProgram::new(&amp;db, &quot;print 11 + 11&quot;.to_string());
<span class="boring">}
</span></code></pre></pre>
<p>You can read the value of the field with <code>source.text(&amp;db)</code>,
@ -799,7 +801,7 @@ then subsequent parts of the computation won't need to re-execute.
(We'll revisit the role of tracked structs in reuse more in future parts of the IR.)</p>
<p>Apart from the fields being immutable, the API for working with a tracked struct is quite similar to an input:</p>
<ul>
<li>You can create a new value by using <code>new</code>, but with a tracked struct, you only need an <code>&amp;dyn</code> database, not <code>&amp;mut</code> (e.g., <code>Program::new(&amp;db, some_staements)</code>)</li>
<li>You can create a new value by using <code>new</code>: e.g., <code>Program::new(&amp;db, some_statements)</code></li>
<li>You use a getter to read the value of a field, just like with an input (e.g., <code>my_func.statements(db)</code> to read the <code>statements</code> field).
<ul>
<li>In this case, the field is tagged as <code>#[return_ref]</code>, which means that the getter will return a <code>&amp;Vec&lt;Statement&gt;</code>, instead of cloning the vector.</li>
@ -843,7 +845,7 @@ This would mean that we have to re-execute those parts of the code that depended
(but not those parts of the code that depended on the body of <em>other</em> functions).</p>
<p>Apart from the fields being immutable, the API for working with a tracked struct is quite similar to an input:</p>
<ul>
<li>You can create a new value by using <code>new</code>, but with a tracked struct, you only need an <code>&amp;dyn</code> database, not <code>&amp;mut</code> (e.g., <code>Function::new(&amp;db, some_name, some_args, some_body)</code>)</li>
<li>You can create a new value by using <code>new</code>: e.g., <code>Function::new(&amp;db, some_name, some_args, some_body)</code></li>
<li>You use a getter to read the value of a field, just like with an input (e.g., <code>my_func.args(db)</code> to read the <code>args</code> field).</li>
</ul>
<h3 id="id-fields-1"><a class="header" href="#id-fields-1">id fields</a></h3>
@ -2192,7 +2194,7 @@ struct MyTrackedStruct&lt;'db&gt; {
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let mut db = MyDatabase::default();
let input = MyInput::new(&amp;mut db, ...);
let input = MyInput::new(&amp;db, ...);
// Revision 1:
let result1 = tracked_fn(&amp;db, input);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -194,11 +194,11 @@ pub struct SourceProgram(salsa::Id);
<span class="boring">}
</span></code></pre></pre>
<p>It will also generate a method <code>new</code> that lets you create a <code>SourceProgram</code> in the database.
For an input, a <code>&amp;mut db</code> reference is required, along with the values for each field:</p>
For an input, a <code>&amp;db</code> reference is required, along with the values for each field:</p>
<pre><pre class="playground"><code class="language-rust">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let source = SourceProgram::new(&amp;mut db, &quot;print 11 + 11&quot;.to_string());
</span>let source = SourceProgram::new(&amp;db, &quot;print 11 + 11&quot;.to_string());
<span class="boring">}
</span></code></pre></pre>
<p>You can read the value of the field with <code>source.text(&amp;db)</code>,
@ -232,7 +232,7 @@ then subsequent parts of the computation won't need to re-execute.
(We'll revisit the role of tracked structs in reuse more in future parts of the IR.)</p>
<p>Apart from the fields being immutable, the API for working with a tracked struct is quite similar to an input:</p>
<ul>
<li>You can create a new value by using <code>new</code>, but with a tracked struct, you only need an <code>&amp;dyn</code> database, not <code>&amp;mut</code> (e.g., <code>Program::new(&amp;db, some_staements)</code>)</li>
<li>You can create a new value by using <code>new</code>: e.g., <code>Program::new(&amp;db, some_statements)</code></li>
<li>You use a getter to read the value of a field, just like with an input (e.g., <code>my_func.statements(db)</code> to read the <code>statements</code> field).
<ul>
<li>In this case, the field is tagged as <code>#[return_ref]</code>, which means that the getter will return a <code>&amp;Vec&lt;Statement&gt;</code>, instead of cloning the vector.</li>
@ -276,7 +276,7 @@ This would mean that we have to re-execute those parts of the code that depended
(but not those parts of the code that depended on the body of <em>other</em> functions).</p>
<p>Apart from the fields being immutable, the API for working with a tracked struct is quite similar to an input:</p>
<ul>
<li>You can create a new value by using <code>new</code>, but with a tracked struct, you only need an <code>&amp;dyn</code> database, not <code>&amp;mut</code> (e.g., <code>Function::new(&amp;db, some_name, some_args, some_body)</code>)</li>
<li>You can create a new value by using <code>new</code>: e.g., <code>Function::new(&amp;db, some_name, some_args, some_body)</code></li>
<li>You use a getter to read the value of a field, just like with an input (e.g., <code>my_func.args(db)</code> to read the <code>args</code> field).</li>
</ul>
<h3 id="id-fields"><a class="header" href="#id-fields">id fields</a></h3>