aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_expand
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_expand')
-rw-r--r--crates/hir_expand/src/hygiene.rs38
1 files changed, 16 insertions, 22 deletions
diff --git a/crates/hir_expand/src/hygiene.rs b/crates/hir_expand/src/hygiene.rs
index d49a67195..6042e15b2 100644
--- a/crates/hir_expand/src/hygiene.rs
+++ b/crates/hir_expand/src/hygiene.rs
@@ -4,6 +4,7 @@
4//! this moment, this is horribly incomplete and handles only `$crate`. 4//! this moment, this is horribly incomplete and handles only `$crate`.
5use std::sync::Arc; 5use std::sync::Arc;
6 6
7use arena::{Arena, Idx};
7use base_db::CrateId; 8use base_db::CrateId;
8use either::Either; 9use either::Either;
9use mbe::Origin; 10use mbe::Origin;
@@ -46,7 +47,7 @@ impl Hygiene {
46 let frames = self.frames.as_ref()?; 47 let frames = self.frames.as_ref()?;
47 48
48 let mut token = path.syntax().first_token()?; 49 let mut token = path.syntax().first_token()?;
49 let mut current = frames.0.first(); 50 let mut current = frames.first();
50 51
51 while let Some((frame, data)) = 52 while let Some((frame, data)) =
52 current.and_then(|it| Some((it, it.expansion.as_ref()?.map_token_up(&token)?))) 53 current.and_then(|it| Some((it, it.expansion.as_ref()?.map_token_up(&token)?)))
@@ -55,18 +56,15 @@ impl Hygiene {
55 if origin == Origin::Def { 56 if origin == Origin::Def {
56 return if frame.local_inner { frame.krate } else { None }; 57 return if frame.local_inner { frame.krate } else { None };
57 } 58 }
58 current = frames.get(frame.call_site?); 59 current = Some(&frames.0[frame.call_site?]);
59 token = mapped.value; 60 token = mapped.value;
60 } 61 }
61 None 62 None
62 } 63 }
63} 64}
64 65
65#[derive(Clone, Debug, Copy)] 66#[derive(Default, Debug)]
66struct HygieneFrameId(usize); 67struct HygieneFrames(Arena<HygieneFrame>);
67
68#[derive(Clone, Debug, Default)]
69struct HygieneFrames(Vec<HygieneFrame>);
70 68
71#[derive(Clone, Debug)] 69#[derive(Clone, Debug)]
72struct HygieneFrame { 70struct HygieneFrame {
@@ -76,8 +74,8 @@ struct HygieneFrame {
76 local_inner: bool, 74 local_inner: bool,
77 krate: Option<CrateId>, 75 krate: Option<CrateId>,
78 76
79 call_site: Option<HygieneFrameId>, 77 call_site: Option<Idx<HygieneFrame>>,
80 def_site: Option<HygieneFrameId>, 78 def_site: Option<Idx<HygieneFrame>>,
81} 79}
82 80
83impl HygieneFrames { 81impl HygieneFrames {
@@ -87,7 +85,7 @@ impl HygieneFrames {
87 frames 85 frames
88 } 86 }
89 87
90 fn add(&mut self, db: &dyn AstDatabase, file_id: HirFileId) -> Option<HygieneFrameId> { 88 fn add(&mut self, db: &dyn AstDatabase, file_id: HirFileId) -> Option<Idx<HygieneFrame>> {
91 let (krate, local_inner) = match file_id.0 { 89 let (krate, local_inner) = match file_id.0 {
92 HirFileIdRepr::FileId(_) => (None, false), 90 HirFileIdRepr::FileId(_) => (None, false),
93 HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id { 91 HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id {
@@ -108,24 +106,20 @@ impl HygieneFrames {
108 let expansion = file_id.expansion_info(db); 106 let expansion = file_id.expansion_info(db);
109 let expansion = match expansion { 107 let expansion = match expansion {
110 None => { 108 None => {
111 let idx = self.0.len(); 109 return Some(self.0.alloc(HygieneFrame {
112 self.0.push(HygieneFrame {
113 expansion: None, 110 expansion: None,
114 local_inner, 111 local_inner,
115 krate, 112 krate,
116 call_site: None, 113 call_site: None,
117 def_site: None, 114 def_site: None,
118 }); 115 }));
119 return Some(HygieneFrameId(idx));
120 } 116 }
121 Some(it) => it, 117 Some(it) => it,
122 }; 118 };
123 119
124 let def_site = expansion.def.clone(); 120 let def_site = expansion.def.clone();
125 let call_site = expansion.arg.file_id; 121 let call_site = expansion.arg.file_id;
126 122 let idx = self.0.alloc(HygieneFrame {
127 let idx = self.0.len();
128 self.0.push(HygieneFrame {
129 expansion: Some(expansion), 123 expansion: Some(expansion),
130 local_inner, 124 local_inner,
131 krate, 125 krate,
@@ -136,16 +130,16 @@ impl HygieneFrames {
136 self.0[idx].call_site = self.add(db, call_site); 130 self.0[idx].call_site = self.add(db, call_site);
137 self.0[idx].def_site = def_site.and_then(|it| self.add(db, it.file_id)); 131 self.0[idx].def_site = def_site.and_then(|it| self.add(db, it.file_id));
138 132
139 Some(HygieneFrameId(idx)) 133 Some(idx)
140 } 134 }
141 135
142 fn get(&self, id: HygieneFrameId) -> Option<&HygieneFrame> { 136 fn first(&self) -> Option<&HygieneFrame> {
143 self.0.get(id.0) 137 self.0.iter().next().map(|it| it.1)
144 } 138 }
145 139
146 fn root_crate(&self, name_ref: &ast::NameRef) -> Option<CrateId> { 140 fn root_crate(&self, name_ref: &ast::NameRef) -> Option<CrateId> {
147 let mut token = name_ref.syntax().first_token()?; 141 let mut token = name_ref.syntax().first_token()?;
148 let first = self.0.first()?; 142 let first = self.first()?;
149 let mut result = first.krate; 143 let mut result = first.krate;
150 let mut current = Some(first); 144 let mut current = Some(first);
151 145
@@ -164,7 +158,7 @@ impl HygieneFrames {
164 Some(it) => it, 158 Some(it) => it,
165 }; 159 };
166 160
167 current = self.get(site); 161 current = Some(&self.0[site]);
168 token = mapped.value; 162 token = mapped.value;
169 } 163 }
170 164