mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
start chapter about interners
This commit is contained in:
parent
cb8dfab21c
commit
d832149a1f
1 changed files with 28 additions and 2 deletions
30
guide.md
30
guide.md
|
@ -351,11 +351,37 @@ declarations.
|
||||||
[`submodules_query`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/module_tree.rs#L41)
|
[`submodules_query`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/module_tree.rs#L41)
|
||||||
|
|
||||||
We store the resulting modules in a `Vec`-based indexed arena. The indices in
|
We store the resulting modules in a `Vec`-based indexed arena. The indices in
|
||||||
the arena becomes module identifiers.
|
the arena becomes module ids. And this brings us to the next topic:
|
||||||
|
assigning ids in the general case.
|
||||||
|
|
||||||
## Location Interner pattern
|
## Location Interner pattern
|
||||||
|
|
||||||
|
One way to assign ids is how we've dealt with modules: collect all items into a
|
||||||
|
single array in some specific order and use index in the array as an id. The
|
||||||
|
main drawback of this approach is that ids are not stable: adding a new item can
|
||||||
|
shift ids of all other items. This works for modules, because adding a module is
|
||||||
|
a comparatively rare operation, but would be less convenient for, for example
|
||||||
|
functions.
|
||||||
|
|
||||||
|
Another solution here is positional ids: we can identify a function as "the
|
||||||
|
function with name `foo` in a ModuleId(92) module". Such locations are stable:
|
||||||
|
adding a new function to the module (unless it is also named `foo`) does not
|
||||||
|
change the location. However, such "id" ceases to be a `Copy` integer and in
|
||||||
|
general can become pretty large if we account for nesting (third parameter of
|
||||||
|
the foo function of the bar impl in the baz module).
|
||||||
|
|
||||||
|
[`LocationInterner`] allows us to combine benefits of positional and numeric
|
||||||
|
ids. It is a bidirectional append only map between locations and consecutive
|
||||||
|
integers which can "intern" a location and return an integer id back. Salsa
|
||||||
|
database we use includes a couple of [interners]. How to "garbage collect"
|
||||||
|
unused locations is an open question.
|
||||||
|
|
||||||
|
[`LocationInterner`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_db/src/loc2id.rs#L65-L71
|
||||||
|
[interners]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/db.rs#L22-L23
|
||||||
|
|
||||||
|
For example, we use `LocationInterner` to assign ids to defs: functions,
|
||||||
|
structs, enums, etc.
|
||||||
|
|
||||||
## Macros and recursive locations
|
## Macros and recursive locations
|
||||||
|
|
||||||
## Name resolution
|
## Name resolution
|
||||||
|
|
Loading…
Reference in a new issue