aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/trace.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-08-13 15:31:49 +0100
committerGitHub <[email protected]>2020-08-13 15:31:49 +0100
commite9926948ca267932ccc1341388bfd1b3fa88a001 (patch)
treecc4b797cb39a40b59e9e3d37178e8a1907f12358 /crates/hir_def/src/trace.rs
parent902f74c2697cc2a50de9067845814a2a852fccfd (diff)
parent50f8c1ebf23f634b68529603a917e3feeda457fa (diff)
Merge #5747
5747: Rename crate r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/hir_def/src/trace.rs')
-rw-r--r--crates/hir_def/src/trace.rs51
1 files changed, 51 insertions, 0 deletions
diff --git a/crates/hir_def/src/trace.rs b/crates/hir_def/src/trace.rs
new file mode 100644
index 000000000..fd64e7018
--- /dev/null
+++ b/crates/hir_def/src/trace.rs
@@ -0,0 +1,51 @@
1//! Trace is a pretty niche data structure which is used when lowering a CST
2//! into HIR.
3//!
4//! Lowering process calculates two bits of information:
5//! * the lowered syntax itself
6//! * a mapping between lowered syntax and original syntax
7//!
8//! Due to the way salsa works, the mapping is usually hot lava, as it contains
9//! absolute offsets. The `Trace` structure (inspired, at least in name, by
10//! Kotlin's `BindingTrace`) allows use the same code to compute both
11//! projections.
12use arena::{map::ArenaMap, Arena, Idx, RawId};
13
14pub(crate) struct Trace<T, V> {
15 arena: Option<Arena<T>>,
16 map: Option<ArenaMap<Idx<T>, V>>,
17 len: u32,
18}
19
20impl<T, V> Trace<T, V> {
21 pub(crate) fn new_for_arena() -> Trace<T, V> {
22 Trace { arena: Some(Arena::default()), map: None, len: 0 }
23 }
24
25 pub(crate) fn new_for_map() -> Trace<T, V> {
26 Trace { arena: None, map: Some(ArenaMap::default()), len: 0 }
27 }
28
29 pub(crate) fn alloc(&mut self, value: impl FnOnce() -> V, data: impl FnOnce() -> T) -> Idx<T> {
30 let id = if let Some(arena) = &mut self.arena {
31 arena.alloc(data())
32 } else {
33 let id = Idx::<T>::from_raw(RawId::from(self.len));
34 self.len += 1;
35 id
36 };
37
38 if let Some(map) = &mut self.map {
39 map.insert(id, value());
40 }
41 id
42 }
43
44 pub(crate) fn into_arena(mut self) -> Arena<T> {
45 self.arena.take().unwrap()
46 }
47
48 pub(crate) fn into_map(mut self) -> ArenaMap<Idx<T>, V> {
49 self.map.take().unwrap()
50 }
51}