• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 la_arena::{Arena, ArenaMap, Idx, RawIdx};
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> {
new_for_arena() -> 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 
new_for_map() -> Trace<T, V>25     pub(crate) fn new_for_map() -> Trace<T, V> {
26         Trace { arena: None, map: Some(ArenaMap::default()), len: 0 }
27     }
28 
alloc(&mut self, value: impl FnOnce() -> V, data: impl FnOnce() -> T) -> Idx<T>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(RawIdx::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 
into_arena(mut self) -> Arena<T>44     pub(crate) fn into_arena(mut self) -> Arena<T> {
45         self.arena.take().unwrap()
46     }
47 
into_map(mut self) -> ArenaMap<Idx<T>, V>48     pub(crate) fn into_map(mut self) -> ArenaMap<Idx<T>, V> {
49         self.map.take().unwrap()
50     }
51 }
52