diff options
Diffstat (limited to 'crates/hir_expand')
-rw-r--r-- | crates/hir_expand/src/hygiene.rs | 38 |
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`. |
5 | use std::sync::Arc; | 5 | use std::sync::Arc; |
6 | 6 | ||
7 | use arena::{Arena, Idx}; | ||
7 | use base_db::CrateId; | 8 | use base_db::CrateId; |
8 | use either::Either; | 9 | use either::Either; |
9 | use mbe::Origin; | 10 | use 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)] |
66 | struct HygieneFrameId(usize); | 67 | struct HygieneFrames(Arena<HygieneFrame>); |
67 | |||
68 | #[derive(Clone, Debug, Default)] | ||
69 | struct HygieneFrames(Vec<HygieneFrame>); | ||
70 | 68 | ||
71 | #[derive(Clone, Debug)] | 69 | #[derive(Clone, Debug)] |
72 | struct HygieneFrame { | 70 | struct 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 | ||
83 | impl HygieneFrames { | 81 | impl 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 | ||