diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-08-13 15:31:49 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-08-13 15:31:49 +0100 |
commit | e9926948ca267932ccc1341388bfd1b3fa88a001 (patch) | |
tree | cc4b797cb39a40b59e9e3d37178e8a1907f12358 /crates/hir_def/src/trace.rs | |
parent | 902f74c2697cc2a50de9067845814a2a852fccfd (diff) | |
parent | 50f8c1ebf23f634b68529603a917e3feeda457fa (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.rs | 51 |
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. | ||
12 | use arena::{map::ArenaMap, Arena, Idx, RawId}; | ||
13 | |||
14 | pub(crate) struct Trace<T, V> { | ||
15 | arena: Option<Arena<T>>, | ||
16 | map: Option<ArenaMap<Idx<T>, V>>, | ||
17 | len: u32, | ||
18 | } | ||
19 | |||
20 | impl<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 | } | ||