4
4
5
5
This chapter is based on the explanation given by Niko Matsakis in this
6
6
[ video] ( https://www.youtube.com/watch?v=_muY4HjSqVw ) about
7
- [ Salsa] ( https://github.com/salsa-rs/salsa ) . To find out more you may
8
- want to watch [ Salsa In More
7
+ [ ` Salsa ` ] ( https://github.com/salsa-rs/salsa ) . To find out more you may
8
+ want to watch [ ` Salsa ` In More
9
9
Depth] ( https://www.youtube.com/watch?v=i_IhACacPRY ) , also by Niko
10
10
Matsakis.
11
11
12
- > As of <!-- date-check --> November 2022, although Salsa is inspired by
13
- > (among other things) rustc's query system, it is not used directly in rustc.
14
- > It _ is_ used in [ chalk] , an implementation of Rust's trait system, and extensively in
15
- > [ ` rust-analyzer ` ] , the official implementation of the language server protocol for Rust, but
16
- > there are no medium or long-term concrete plans to integrate it into the
17
- > compiler.
12
+ > As of <!-- date-check --> November 2022, although ` Salsa ` is inspired by (among
13
+ > other things) ` rustc ` 's query system, it is not used directly in ` rustc ` . It
14
+ > _ is_ used in [ chalk] , an implementation of Rust's trait system, and
15
+ > extensively in [ ` rust-analyzer ` ] , the official implementation of the language
16
+ > server protocol for Rust, but there are no medium or long-term concrete
17
+ > plans to integrate it into the compiler.
18
18
19
19
20
20
[ `rust-analyzer` ] : https://rust-analyzer.github.io/
21
21
[ chalk ] : https://rust-lang.github.io/chalk/book/what_is_chalk.html
22
22
23
23
## What is Salsa?
24
24
25
- Salsa is a library for incremental recomputation. This means it allows reusing
25
+ ` Salsa ` is a library for incremental recomputation. This means it allows reusing
26
26
computations that were already done in the past to increase the efficiency
27
27
of future computations.
28
28
29
- The objectives of Salsa are:
29
+ The objectives of ` Salsa ` are:
30
30
* Provide that functionality in an automatic way, so reusing old computations
31
- is done automatically by the library
31
+ is done automatically by the library.
32
32
* Doing so in a "sound", or "correct", way, therefore leading to the same
33
- results as if it had been done from scratch
33
+ results as if it had been done from scratch.
34
34
35
- Salsa's actual model is much richer, allowing many kinds of inputs and many
35
+ ` Salsa ` 's actual model is much richer, allowing many kinds of inputs and many
36
36
different outputs.
37
- For example, integrating Salsa with an IDE could mean that the inputs could be
37
+ For example, integrating ` Salsa ` with an IDE could mean that the inputs could be
38
38
the manifest (` Cargo.toml ` ), entire source files (` foo.rs ` ), snippets and so
39
39
on; the outputs of such an integration could range from a binary executable, to
40
40
lints, types (for example, if a user selects a certain variable and wishes to
41
41
see its type), completions, etc.
42
42
43
43
## How does it work?
44
44
45
- The first thing that Salsa has to do is identify the "base inputs" that
45
+ The first thing that ` Salsa ` has to do is identify the "base inputs" that
46
46
are not something computed but given as input.
47
47
48
- Then Salsa has to also identify intermediate, "derived" values, which are
48
+ Then ` Salsa ` has to also identify intermediate, "derived" values, which are
49
49
something that the library produces, but, for each derived value there's a
50
50
"pure" function that computes the derived value.
51
51
52
52
For example, there might be a function ` ast(x: Path) -> AST ` . The produced
53
53
` AST ` isn't a final value, it's an intermediate value that the library would
54
54
use for the computation.
55
55
56
- This means that when you try to compute with the library, Salsa is going to
56
+ This means that when you try to compute with the library, ` Salsa ` is going to
57
57
compute various derived values, and eventually read the input and produce the
58
58
result for the asked computation.
59
59
60
- In the course of computing, Salsa tracks which inputs were accessed and which
60
+ In the course of computing, ` Salsa ` tracks which inputs were accessed and which
61
61
values are derived. This information is used to determine what's going to
62
62
happen when the inputs change: are the derived values still valid?
63
63
64
64
This doesn't necessarily mean that each computation downstream from the input
65
- is going to be checked, which could be costly. Salsa only needs to check each
65
+ is going to be checked, which could be costly. ` Salsa ` only needs to check each
66
66
downstream computation until it finds one that isn't changed. At that point, it
67
67
won't check other derived computations since they wouldn't need to change.
68
68
@@ -78,7 +78,7 @@ J <- B <--+
78
78
79
79
When an input ` I ` changes, the derived value ` A ` could change. The derived
80
80
value ` B ` , which does not depend on ` I ` , ` A ` , or any value derived from ` A ` or
81
- ` I ` , is not subject to change. Therefore, Salsa can reuse the computation done
81
+ ` I ` , is not subject to change. Therefore, ` Salsa ` can reuse the computation done
82
82
for ` B ` in the past, without having to compute it again.
83
83
84
84
The computation could also terminate early. Keeping the same graph as before,
@@ -88,37 +88,37 @@ computation. This leads to an "early termination", because there's no need to
88
88
check if ` C ` needs to change, since both ` C ` direct inputs, ` A ` and ` B ` ,
89
89
haven't changed.
90
90
91
- ## Key Salsa concepts
91
+ ## Key ` Salsa ` concepts
92
92
93
93
### Query
94
94
95
- A query is some value that Salsa can access in the course of computation. Each
95
+ A query is some value that ` Salsa ` can access in the course of computation. Each
96
96
query can have a number of keys (from 0 to many), and all queries have a
97
- result, akin to functions. 0-key queries are called "input" queries.
97
+ result, akin to functions. ` 0-key ` queries are called "input" queries.
98
98
99
99
### Database
100
100
101
101
The database is basically the context for the entire computation, it's meant to
102
- store Salsa's internal state, all intermediate values for each query, and
103
- anything else that the computation might need. The database must know all the
104
- queries that the library is going to do before it can be built, but they don't
105
- need to be specified in the same place.
102
+ store ` Salsa ` 's internal state, all intermediate values for each query, and
103
+ anything else that the computation might need. The database must know all the
104
+ queries the library is going to do before it can be built, but they don't need
105
+ to be specified in the same place.
106
106
107
107
After the database is formed, it can be accessed with queries that are very
108
- similar to functions. Since each query's result is stored in the database,
109
- when a query is invoked N times, it will return N ** cloned** results, without
110
- having to recompute the query (unless the input has changed in such a way that
111
- it warrants recomputation).
108
+ similar to functions. Since each query's result is stored in the database, when
109
+ a query is invoked ` N ` - times, it will return ` N ` - ** cloned** results, without having
110
+ to recompute the query (unless the input has changed in such a way that it
111
+ warrants recomputation).
112
112
113
- For each input query (0-key), a "set" method is generated, allowing the user to
113
+ For each input query (` 0-key ` ), a "set" method is generated, allowing the user to
114
114
change the output of such query, and trigger previous memoized values to be
115
115
potentially invalidated.
116
116
117
117
### Query Groups
118
118
119
119
A query group is a set of queries which have been defined together as a unit.
120
120
The database is formed by combining query groups. Query groups are akin to
121
- "Salsa modules".
121
+ "` Salsa ` modules".
122
122
123
123
A set of queries in a query group are just a set of methods in a trait.
124
124
@@ -132,7 +132,7 @@ Example input query group:
132
132
133
133
``` rust,ignore
134
134
/// This attribute will process this tree, produce this tree as output, and produce
135
- /// a bunch of intermediate stuff that Salsa also uses. One of these things is a
135
+ /// a bunch of intermediate stuff that Salsa also uses. One of these things is a
136
136
/// "StorageStruct", whose name we have specified in the attribute.
137
137
///
138
138
/// This query group is a bunch of **input** queries, that do not rely on any
@@ -154,9 +154,9 @@ this one depends on by specifying them as supertraits, as seen in the following
154
154
example:
155
155
156
156
``` rust,ignore
157
- /// This query group is going to contain queries that depend on derived values. A
158
- /// query group can access another query group's queries by specifying the
159
- /// dependency as a super trait . Query groups can be stacked as much as needed using
157
+ /// This query group is going to contain queries that depend on derived values.
158
+ /// A query group can access another query group's queries by specifying the
159
+ /// dependency as a supertrait . Query groups can be stacked as much as needed using
160
160
/// that pattern.
161
161
#[salsa::query_group(ParserStorage)]
162
162
pub trait Parser: Inputs {
@@ -172,10 +172,11 @@ Trait` (or `dyn Trait`), where `Trait` is the query group that the definition
172
172
belongs to, in addition to the other keys.
173
173
174
174
``` rust,ignore
175
- ///This is going to be the definition of the `ast` query in the `Parser` trait.
176
- ///So, when the query `ast` is invoked, and it needs to be recomputed, Salsa is going to call this function
177
- ///and it's going to give it the database as `impl Parser`.
178
- ///The function doesn't need to be aware of all the queries of all the query groups
175
+ /// This is going to be the definition of the `ast` query in the `Parser` trait.
176
+ /// So, when the query `ast` is invoked, and it needs to be recomputed, Salsa is
177
+ /// going to call this function and it's going to give it the database as `impl
178
+ /// Parser`. The function doesn't need to be aware of all the queries of all the
179
+ /// query groups
179
180
fn ast(db: &impl Parser, name: String) -> String {
180
181
//! Note, `impl Parser` is used here but `dyn Parser` works just as well
181
182
/* code */
0 commit comments