aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-01-19 17:20:45 +0000
committerAleksey Kladov <[email protected]>2019-01-21 08:27:01 +0000
commitd832149a1f16fe83163455da560bb665a672d4d7 (patch)
treea69f5818b2829e96c5f0e3585bbe8290f82cd585
parentcb8dfab21c85f79b97cfd8e5cf3cff88c2e6d269 (diff)
start chapter about interners
-rw-r--r--guide.md30
1 files changed, 28 insertions, 2 deletions
diff --git a/guide.md b/guide.md
index 5196f83df..de51f7216 100644
--- a/guide.md
+++ b/guide.md
@@ -351,11 +351,37 @@ declarations.
351[`submodules_query`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/module_tree.rs#L41) 351[`submodules_query`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/module_tree.rs#L41)
352 352
353We store the resulting modules in a `Vec`-based indexed arena. The indices in 353We store the resulting modules in a `Vec`-based indexed arena. The indices in
354the arena becomes module identifiers. 354the arena becomes module ids. And this brings us to the next topic:
355 355assigning ids in the general case.
356 356
357## Location Interner pattern 357## Location Interner pattern
358 358
359One way to assign ids is how we've dealt with modules: collect all items into a
360single array in some specific order and use index in the array as an id. The
361main drawback of this approach is that ids are not stable: adding a new item can
362shift ids of all other items. This works for modules, because adding a module is
363a comparatively rare operation, but would be less convenient for, for example
364functions.
365
366Another solution here is positional ids: we can identify a function as "the
367function with name `foo` in a ModuleId(92) module". Such locations are stable:
368adding a new function to the module (unless it is also named `foo`) does not
369change the location. However, such "id" ceases to be a `Copy` integer and in
370general can become pretty large if we account for nesting (third parameter of
371the foo function of the bar impl in the baz module).
372
373[`LocationInterner`] allows us to combine benefits of positional and numeric
374ids. It is a bidirectional append only map between locations and consecutive
375integers which can "intern" a location and return an integer id back. Salsa
376database we use includes a couple of [interners]. How to "garbage collect"
377unused locations is an open question.
378
379[`LocationInterner`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_db/src/loc2id.rs#L65-L71
380[interners]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/db.rs#L22-L23
381
382For example, we use `LocationInterner` to assign ids to defs: functions,
383structs, enums, etc.
384
359## Macros and recursive locations 385## Macros and recursive locations
360 386
361## Name resolution 387## Name resolution