aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_expand/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_expand/src/lib.rs')
-rw-r--r--crates/hir_expand/src/lib.rs124
1 files changed, 31 insertions, 93 deletions
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs
index 88cb16ca4..edd5f9db2 100644
--- a/crates/hir_expand/src/lib.rs
+++ b/crates/hir_expand/src/lib.rs
@@ -80,19 +80,10 @@ impl HirFileId {
80 match self.0 { 80 match self.0 {
81 HirFileIdRepr::FileId(file_id) => file_id, 81 HirFileIdRepr::FileId(file_id) => file_id,
82 HirFileIdRepr::MacroFile(macro_file) => { 82 HirFileIdRepr::MacroFile(macro_file) => {
83 let file_id = match macro_file.macro_call_id { 83 let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id);
84 MacroCallId::LazyMacro(id) => { 84 let file_id = match &loc.eager {
85 let loc = db.lookup_intern_macro(id); 85 Some(EagerCallInfo { included_file: Some(file), .. }) => (*file).into(),
86 loc.kind.file_id() 86 _ => loc.kind.file_id(),
87 }
88 MacroCallId::EagerMacro(id) => {
89 let loc = db.lookup_intern_eager_expansion(id);
90 if let Some(included_file) = loc.included_file {
91 return included_file;
92 } else {
93 loc.call.file_id
94 }
95 }
96 }; 87 };
97 file_id.original_file(db) 88 file_id.original_file(db)
98 } 89 }
@@ -103,17 +94,10 @@ impl HirFileId {
103 let mut level = 0; 94 let mut level = 0;
104 let mut curr = self; 95 let mut curr = self;
105 while let HirFileIdRepr::MacroFile(macro_file) = curr.0 { 96 while let HirFileIdRepr::MacroFile(macro_file) = curr.0 {
97 let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id);
98
106 level += 1; 99 level += 1;
107 curr = match macro_file.macro_call_id { 100 curr = loc.kind.file_id();
108 MacroCallId::LazyMacro(id) => {
109 let loc = db.lookup_intern_macro(id);
110 loc.kind.file_id()
111 }
112 MacroCallId::EagerMacro(id) => {
113 let loc = db.lookup_intern_eager_expansion(id);
114 loc.call.file_id
115 }
116 };
117 } 101 }
118 level 102 level
119 } 103 }
@@ -122,16 +106,10 @@ impl HirFileId {
122 pub fn call_node(self, db: &dyn db::AstDatabase) -> Option<InFile<SyntaxNode>> { 106 pub fn call_node(self, db: &dyn db::AstDatabase) -> Option<InFile<SyntaxNode>> {
123 match self.0 { 107 match self.0 {
124 HirFileIdRepr::FileId(_) => None, 108 HirFileIdRepr::FileId(_) => None,
125 HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id { 109 HirFileIdRepr::MacroFile(macro_file) => {
126 MacroCallId::LazyMacro(lazy_id) => { 110 let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id);
127 let loc: MacroCallLoc = db.lookup_intern_macro(lazy_id); 111 Some(loc.kind.node(db))
128 Some(loc.kind.node(db)) 112 }
129 }
130 MacroCallId::EagerMacro(id) => {
131 let loc: EagerCallLoc = db.lookup_intern_eager_expansion(id);
132 Some(loc.call.with_value(loc.call.to_node(db).syntax().clone()))
133 }
134 },
135 } 113 }
136 } 114 }
137 115
@@ -140,14 +118,7 @@ impl HirFileId {
140 match self.0 { 118 match self.0 {
141 HirFileIdRepr::FileId(_) => None, 119 HirFileIdRepr::FileId(_) => None,
142 HirFileIdRepr::MacroFile(macro_file) => { 120 HirFileIdRepr::MacroFile(macro_file) => {
143 let lazy_id = match macro_file.macro_call_id { 121 let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id);
144 MacroCallId::LazyMacro(id) => id,
145 MacroCallId::EagerMacro(_id) => {
146 // FIXME: handle expansion_info for eager macro
147 return None;
148 }
149 };
150 let loc: MacroCallLoc = db.lookup_intern_macro(lazy_id);
151 122
152 let arg_tt = loc.kind.arg(db)?; 123 let arg_tt = loc.kind.arg(db)?;
153 124
@@ -180,13 +151,7 @@ impl HirFileId {
180 match self.0 { 151 match self.0 {
181 HirFileIdRepr::FileId(_) => None, 152 HirFileIdRepr::FileId(_) => None,
182 HirFileIdRepr::MacroFile(macro_file) => { 153 HirFileIdRepr::MacroFile(macro_file) => {
183 let lazy_id = match macro_file.macro_call_id { 154 let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id);
184 MacroCallId::LazyMacro(id) => id,
185 MacroCallId::EagerMacro(_id) => {
186 return None;
187 }
188 };
189 let loc: MacroCallLoc = db.lookup_intern_macro(lazy_id);
190 let item = match loc.def.kind { 155 let item = match loc.def.kind {
191 MacroDefKind::BuiltInDerive(..) => loc.kind.node(db), 156 MacroDefKind::BuiltInDerive(..) => loc.kind.node(db),
192 _ => return None, 157 _ => return None,
@@ -199,16 +164,12 @@ impl HirFileId {
199 /// Return whether this file is an include macro 164 /// Return whether this file is an include macro
200 pub fn is_include_macro(&self, db: &dyn db::AstDatabase) -> bool { 165 pub fn is_include_macro(&self, db: &dyn db::AstDatabase) -> bool {
201 match self.0 { 166 match self.0 {
202 HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id { 167 HirFileIdRepr::MacroFile(macro_file) => {
203 MacroCallId::EagerMacro(id) => { 168 let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id);
204 let loc = db.lookup_intern_eager_expansion(id); 169 matches!(loc.eager, Some(EagerCallInfo { included_file: Some(_), .. }))
205 return loc.included_file.is_some(); 170 }
206 } 171 _ => false,
207 _ => {}
208 },
209 _ => {}
210 } 172 }
211 false
212 } 173 }
213} 174}
214 175
@@ -220,29 +181,8 @@ pub struct MacroFile {
220/// `MacroCallId` identifies a particular macro invocation, like 181/// `MacroCallId` identifies a particular macro invocation, like
221/// `println!("Hello, {}", world)`. 182/// `println!("Hello, {}", world)`.
222#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 183#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
223pub enum MacroCallId { 184pub struct MacroCallId(salsa::InternId);
224 LazyMacro(LazyMacroId), 185impl_intern_key!(MacroCallId);
225 EagerMacro(EagerMacroId),
226}
227
228#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
229pub struct LazyMacroId(salsa::InternId);
230impl_intern_key!(LazyMacroId);
231
232#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
233pub struct EagerMacroId(salsa::InternId);
234impl_intern_key!(EagerMacroId);
235
236impl From<LazyMacroId> for MacroCallId {
237 fn from(it: LazyMacroId) -> Self {
238 MacroCallId::LazyMacro(it)
239 }
240}
241impl From<EagerMacroId> for MacroCallId {
242 fn from(it: EagerMacroId) -> Self {
243 MacroCallId::EagerMacro(it)
244 }
245}
246 186
247#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 187#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
248pub struct MacroDefId { 188pub struct MacroDefId {
@@ -258,8 +198,8 @@ impl MacroDefId {
258 db: &dyn db::AstDatabase, 198 db: &dyn db::AstDatabase,
259 krate: CrateId, 199 krate: CrateId,
260 kind: MacroCallKind, 200 kind: MacroCallKind,
261 ) -> LazyMacroId { 201 ) -> MacroCallId {
262 db.intern_macro(MacroCallLoc { def: self, krate, kind }) 202 db.intern_macro(MacroCallLoc { def: self, krate, eager: None, kind })
263 } 203 }
264 204
265 pub fn ast_id(&self) -> Either<AstId<ast::Macro>, AstId<ast::Fn>> { 205 pub fn ast_id(&self) -> Either<AstId<ast::Macro>, AstId<ast::Fn>> {
@@ -289,9 +229,17 @@ pub enum MacroDefKind {
289} 229}
290 230
291#[derive(Debug, Clone, PartialEq, Eq, Hash)] 231#[derive(Debug, Clone, PartialEq, Eq, Hash)]
232struct EagerCallInfo {
233 /// NOTE: This can be *either* the expansion result, *or* the argument to the eager macro!
234 expansion: Arc<tt::Subtree>,
235 included_file: Option<FileId>,
236}
237
238#[derive(Debug, Clone, PartialEq, Eq, Hash)]
292pub struct MacroCallLoc { 239pub struct MacroCallLoc {
293 pub(crate) def: MacroDefId, 240 pub(crate) def: MacroDefId,
294 pub(crate) krate: CrateId, 241 pub(crate) krate: CrateId,
242 eager: Option<EagerCallInfo>,
295 pub kind: MacroCallKind, 243 pub kind: MacroCallKind,
296} 244}
297 245
@@ -313,6 +261,7 @@ pub enum MacroCallKind {
313} 261}
314 262
315impl MacroCallKind { 263impl MacroCallKind {
264 /// Returns the file containing the macro invocation.
316 fn file_id(&self) -> HirFileId { 265 fn file_id(&self) -> HirFileId {
317 match self { 266 match self {
318 MacroCallKind::FnLike { ast_id, .. } => ast_id.file_id, 267 MacroCallKind::FnLike { ast_id, .. } => ast_id.file_id,
@@ -354,17 +303,6 @@ impl MacroCallId {
354 } 303 }
355} 304}
356 305
357#[derive(Debug, Clone, PartialEq, Eq, Hash)]
358pub struct EagerCallLoc {
359 pub(crate) def: MacroDefId,
360 pub(crate) fragment: FragmentKind,
361 pub(crate) subtree: Arc<tt::Subtree>,
362 pub(crate) krate: CrateId,
363 pub(crate) call: AstId<ast::MacroCall>,
364 // The included file ID of the include macro.
365 pub(crate) included_file: Option<FileId>,
366}
367
368/// ExpansionInfo mainly describes how to map text range between src and expanded macro 306/// ExpansionInfo mainly describes how to map text range between src and expanded macro
369#[derive(Debug, Clone, PartialEq, Eq)] 307#[derive(Debug, Clone, PartialEq, Eq)]
370pub struct ExpansionInfo { 308pub struct ExpansionInfo {