aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2021-03-18 15:11:18 +0000
committerJonas Schievink <[email protected]>2021-03-18 15:11:18 +0000
commitc05a1a6e37156b956380d57049a72cfe6f21095d (patch)
treececbf9cb7ee8b6706d2d70aeb04bbf67a6c43ac0
parent3ab9b39dd47d99ffd97f485c27f38b8944e12a3e (diff)
Store an `AstId` for procedural macros
-rw-r--r--crates/hir/src/has_source.rs15
-rw-r--r--crates/hir/src/lib.rs7
-rw-r--r--crates/hir_def/src/item_scope.rs2
-rw-r--r--crates/hir_def/src/nameres/collector.rs13
-rw-r--r--crates/hir_expand/src/db.rs4
-rw-r--r--crates/hir_expand/src/eager.rs2
-rw-r--r--crates/hir_expand/src/hygiene.rs2
-rw-r--r--crates/hir_expand/src/lib.rs4
-rw-r--r--crates/ide/src/display/navigation_target.rs8
-rw-r--r--crates/ide/src/hover.rs14
-rw-r--r--crates/ide_completion/src/render/macro_.rs2
11 files changed, 47 insertions, 26 deletions
diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs
index 5b22ab58b..d57fad9ed 100644
--- a/crates/hir/src/has_source.rs
+++ b/crates/hir/src/has_source.rs
@@ -6,7 +6,7 @@ use hir_def::{
6 src::{HasChildSource, HasSource as _}, 6 src::{HasChildSource, HasSource as _},
7 Lookup, VariantId, 7 Lookup, VariantId,
8}; 8};
9use hir_expand::InFile; 9use hir_expand::{InFile, MacroDefKind};
10use syntax::ast; 10use syntax::ast;
11 11
12use crate::{ 12use crate::{
@@ -111,10 +111,17 @@ impl HasSource for TypeAlias {
111 } 111 }
112} 112}
113impl HasSource for MacroDef { 113impl HasSource for MacroDef {
114 type Ast = ast::Macro; 114 type Ast = Either<ast::Macro, ast::Fn>;
115 fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> { 115 fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
116 let ast_id = self.id.ast_id()?; 116 Some(match &self.id.kind {
117 Some(InFile { file_id: ast_id.file_id, value: ast_id.to_node(db.upcast()) }) 117 MacroDefKind::Declarative(id)
118 | MacroDefKind::BuiltIn(_, id)
119 | MacroDefKind::BuiltInDerive(_, id)
120 | MacroDefKind::BuiltInEager(_, id) => {
121 id.with_value(Either::Left(id.to_node(db.upcast())))
122 }
123 MacroDefKind::ProcMacro(_, id) => id.map(|_| Either::Right(id.to_node(db.upcast()))),
124 })
118 } 125 }
119} 126}
120impl HasSource for Impl { 127impl HasSource for Impl {
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index b860cbf3c..95cfde61c 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -1144,12 +1144,15 @@ impl MacroDef {
1144 1144
1145 /// XXX: this parses the file 1145 /// XXX: this parses the file
1146 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { 1146 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
1147 self.source(db)?.value.name().map(|it| it.as_name()) 1147 match self.source(db)?.value {
1148 Either::Left(it) => it.name().map(|it| it.as_name()),
1149 Either::Right(it) => it.name().map(|it| it.as_name()),
1150 }
1148 } 1151 }
1149 1152
1150 /// Indicate it is a proc-macro 1153 /// Indicate it is a proc-macro
1151 pub fn is_proc_macro(&self) -> bool { 1154 pub fn is_proc_macro(&self) -> bool {
1152 matches!(self.id.kind, MacroDefKind::ProcMacro(_)) 1155 matches!(self.id.kind, MacroDefKind::ProcMacro(..))
1153 } 1156 }
1154 1157
1155 /// Indicate it is a derive macro 1158 /// Indicate it is a derive macro
diff --git a/crates/hir_def/src/item_scope.rs b/crates/hir_def/src/item_scope.rs
index aafd73b60..f3ebe7c72 100644
--- a/crates/hir_def/src/item_scope.rs
+++ b/crates/hir_def/src/item_scope.rs
@@ -252,7 +252,7 @@ impl ItemScope {
252 .for_each(|vis| *vis = Visibility::Module(this_module)); 252 .for_each(|vis| *vis = Visibility::Module(this_module));
253 253
254 for (mac, vis) in self.macros.values_mut() { 254 for (mac, vis) in self.macros.values_mut() {
255 if let MacroDefKind::ProcMacro(_) = mac.kind { 255 if let MacroDefKind::ProcMacro(..) = mac.kind {
256 // FIXME: Technically this is insufficient since reexports of proc macros are also 256 // FIXME: Technically this is insufficient since reexports of proc macros are also
257 // forbidden. Practically nobody does that. 257 // forbidden. Practically nobody does that.
258 continue; 258 continue;
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 45a79e896..696370ada 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -353,17 +353,17 @@ impl DefCollector<'_> {
353 /// use a dummy expander that always errors. This comes with the drawback of macros potentially 353 /// use a dummy expander that always errors. This comes with the drawback of macros potentially
354 /// going out of sync with what the build system sees (since we resolve using VFS state, but 354 /// going out of sync with what the build system sees (since we resolve using VFS state, but
355 /// Cargo builds only on-disk files). We could and probably should add diagnostics for that. 355 /// Cargo builds only on-disk files). We could and probably should add diagnostics for that.
356 fn resolve_proc_macro(&mut self, name: &Name) { 356 fn resolve_proc_macro(&mut self, name: &Name, ast_id: AstId<ast::Fn>) {
357 self.exports_proc_macros = true; 357 self.exports_proc_macros = true;
358 let macro_def = match self.proc_macros.iter().find(|(n, _)| n == name) { 358 let macro_def = match self.proc_macros.iter().find(|(n, _)| n == name) {
359 Some((_, expander)) => MacroDefId { 359 Some((_, expander)) => MacroDefId {
360 krate: self.def_map.krate, 360 krate: self.def_map.krate,
361 kind: MacroDefKind::ProcMacro(*expander), 361 kind: MacroDefKind::ProcMacro(*expander, ast_id),
362 local_inner: false, 362 local_inner: false,
363 }, 363 },
364 None => MacroDefId { 364 None => MacroDefId {
365 krate: self.def_map.krate, 365 krate: self.def_map.krate,
366 kind: MacroDefKind::ProcMacro(ProcMacroExpander::dummy(self.def_map.krate)), 366 kind: MacroDefKind::ProcMacro(ProcMacroExpander::dummy(self.def_map.krate), ast_id),
367 local_inner: false, 367 local_inner: false,
368 }, 368 },
369 }; 369 };
@@ -1116,7 +1116,8 @@ impl ModCollector<'_, '_> {
1116 ModItem::Function(id) => { 1116 ModItem::Function(id) => {
1117 let func = &self.item_tree[id]; 1117 let func = &self.item_tree[id];
1118 1118
1119 self.collect_proc_macro_def(&func.name, &attrs); 1119 let ast_id = InFile::new(self.file_id, func.ast_id);
1120 self.collect_proc_macro_def(&func.name, ast_id, &attrs);
1120 1121
1121 def = Some(DefData { 1122 def = Some(DefData {
1122 id: FunctionLoc { 1123 id: FunctionLoc {
@@ -1383,7 +1384,7 @@ impl ModCollector<'_, '_> {
1383 } 1384 }
1384 1385
1385 /// If `attrs` registers a procedural macro, collects its definition. 1386 /// If `attrs` registers a procedural macro, collects its definition.
1386 fn collect_proc_macro_def(&mut self, func_name: &Name, attrs: &Attrs) { 1387 fn collect_proc_macro_def(&mut self, func_name: &Name, ast_id: AstId<ast::Fn>, attrs: &Attrs) {
1387 // FIXME: this should only be done in the root module of `proc-macro` crates, not everywhere 1388 // FIXME: this should only be done in the root module of `proc-macro` crates, not everywhere
1388 // FIXME: distinguish the type of macro 1389 // FIXME: distinguish the type of macro
1389 let macro_name = if attrs.by_key("proc_macro").exists() 1390 let macro_name = if attrs.by_key("proc_macro").exists()
@@ -1404,7 +1405,7 @@ impl ModCollector<'_, '_> {
1404 } 1405 }
1405 }; 1406 };
1406 1407
1407 self.def_collector.resolve_proc_macro(&macro_name); 1408 self.def_collector.resolve_proc_macro(&macro_name, ast_id);
1408 } 1409 }
1409 1410
1410 fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) { 1411 fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) {
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs
index 4107d7781..2748e25cf 100644
--- a/crates/hir_expand/src/db.rs
+++ b/crates/hir_expand/src/db.rs
@@ -157,7 +157,7 @@ fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander,
157 Some(Arc::new((TokenExpander::BuiltinDerive(expander), mbe::TokenMap::default()))) 157 Some(Arc::new((TokenExpander::BuiltinDerive(expander), mbe::TokenMap::default())))
158 } 158 }
159 MacroDefKind::BuiltInEager(..) => None, 159 MacroDefKind::BuiltInEager(..) => None,
160 MacroDefKind::ProcMacro(expander) => { 160 MacroDefKind::ProcMacro(expander, ..) => {
161 Some(Arc::new((TokenExpander::ProcMacro(expander), mbe::TokenMap::default()))) 161 Some(Arc::new((TokenExpander::ProcMacro(expander), mbe::TokenMap::default())))
162 } 162 }
163 } 163 }
@@ -269,7 +269,7 @@ fn expand_proc_macro(
269 }; 269 };
270 270
271 let expander = match loc.def.kind { 271 let expander = match loc.def.kind {
272 MacroDefKind::ProcMacro(expander) => expander, 272 MacroDefKind::ProcMacro(expander, ..) => expander,
273 _ => unreachable!(), 273 _ => unreachable!(),
274 }; 274 };
275 275
diff --git a/crates/hir_expand/src/eager.rs b/crates/hir_expand/src/eager.rs
index ddadaffd3..04f374a29 100644
--- a/crates/hir_expand/src/eager.rs
+++ b/crates/hir_expand/src/eager.rs
@@ -209,7 +209,7 @@ fn eager_macro_recur(
209 MacroDefKind::Declarative(_) 209 MacroDefKind::Declarative(_)
210 | MacroDefKind::BuiltIn(..) 210 | MacroDefKind::BuiltIn(..)
211 | MacroDefKind::BuiltInDerive(..) 211 | MacroDefKind::BuiltInDerive(..)
212 | MacroDefKind::ProcMacro(_) => { 212 | MacroDefKind::ProcMacro(..) => {
213 let res = lazy_expand(db, &def, curr.with_value(child.clone()), krate); 213 let res = lazy_expand(db, &def, curr.with_value(child.clone()), krate);
214 let val = diagnostic_sink.expand_result_option(res)?; 214 let val = diagnostic_sink.expand_result_option(res)?;
215 215
diff --git a/crates/hir_expand/src/hygiene.rs b/crates/hir_expand/src/hygiene.rs
index e758b3c0a..20cda1683 100644
--- a/crates/hir_expand/src/hygiene.rs
+++ b/crates/hir_expand/src/hygiene.rs
@@ -182,7 +182,7 @@ impl HygieneFrame {
182 MacroDefKind::BuiltIn(..) => (info, Some(loc.def.krate), false), 182 MacroDefKind::BuiltIn(..) => (info, Some(loc.def.krate), false),
183 MacroDefKind::BuiltInDerive(..) => (info, None, false), 183 MacroDefKind::BuiltInDerive(..) => (info, None, false),
184 MacroDefKind::BuiltInEager(..) => (info, None, false), 184 MacroDefKind::BuiltInEager(..) => (info, None, false),
185 MacroDefKind::ProcMacro(_) => (info, None, false), 185 MacroDefKind::ProcMacro(..) => (info, None, false),
186 } 186 }
187 } 187 }
188 }, 188 },
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs
index 83e11019f..0a379651f 100644
--- a/crates/hir_expand/src/lib.rs
+++ b/crates/hir_expand/src/lib.rs
@@ -245,7 +245,7 @@ impl MacroDefId {
245 MacroDefKind::BuiltIn(_, id) => id, 245 MacroDefKind::BuiltIn(_, id) => id,
246 MacroDefKind::BuiltInDerive(_, id) => id, 246 MacroDefKind::BuiltInDerive(_, id) => id,
247 MacroDefKind::BuiltInEager(_, id) => id, 247 MacroDefKind::BuiltInEager(_, id) => id,
248 MacroDefKind::ProcMacro(_) => return None, 248 MacroDefKind::ProcMacro(..) => return None,
249 }; 249 };
250 Some(*id) 250 Some(*id)
251 } 251 }
@@ -258,7 +258,7 @@ pub enum MacroDefKind {
258 // FIXME: maybe just Builtin and rename BuiltinFnLikeExpander to BuiltinExpander 258 // FIXME: maybe just Builtin and rename BuiltinFnLikeExpander to BuiltinExpander
259 BuiltInDerive(BuiltinDeriveExpander, AstId<ast::Macro>), 259 BuiltInDerive(BuiltinDeriveExpander, AstId<ast::Macro>),
260 BuiltInEager(EagerExpander, AstId<ast::Macro>), 260 BuiltInEager(EagerExpander, AstId<ast::Macro>),
261 ProcMacro(ProcMacroExpander), 261 ProcMacro(ProcMacroExpander, AstId<ast::Fn>),
262} 262}
263 263
264#[derive(Debug, Clone, PartialEq, Eq, Hash)] 264#[derive(Debug, Clone, PartialEq, Eq, Hash)]
diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs
index c086de163..364be260c 100644
--- a/crates/ide/src/display/navigation_target.rs
+++ b/crates/ide/src/display/navigation_target.rs
@@ -339,10 +339,14 @@ impl TryToNav for hir::Field {
339impl TryToNav for hir::MacroDef { 339impl TryToNav for hir::MacroDef {
340 fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> { 340 fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
341 let src = self.source(db)?; 341 let src = self.source(db)?;
342 log::debug!("nav target {:#?}", src.value.syntax()); 342 let name_owner: &dyn ast::NameOwner = match &src.value {
343 Either::Left(it) => it,
344 Either::Right(it) => it,
345 };
346 log::debug!("nav target {:#?}", name_owner.syntax());
343 let mut res = NavigationTarget::from_named( 347 let mut res = NavigationTarget::from_named(
344 db, 348 db,
345 src.as_ref().map(|it| it as &dyn ast::NameOwner), 349 src.as_ref().with_value(name_owner),
346 SymbolKind::Macro, 350 SymbolKind::Macro,
347 ); 351 );
348 res.docs = self.docs(db); 352 res.docs = self.docs(db);
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 15d309d7d..a3fb17c0a 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -331,10 +331,16 @@ fn hover_for_definition(
331) -> Option<Markup> { 331) -> Option<Markup> {
332 let mod_path = definition_mod_path(db, &def); 332 let mod_path = definition_mod_path(db, &def);
333 return match def { 333 return match def {
334 Definition::Macro(it) => { 334 Definition::Macro(it) => match &it.source(db)?.value {
335 let label = macro_label(&it.source(db)?.value); 335 Either::Left(mac) => {
336 from_def_source_labeled(db, it, Some(label), mod_path) 336 let label = macro_label(&mac);
337 } 337 from_def_source_labeled(db, it, Some(label), mod_path)
338 }
339 Either::Right(_) => {
340 // FIXME
341 None
342 }
343 },
338 Definition::Field(def) => from_hir_fmt(db, def, mod_path), 344 Definition::Field(def) => from_hir_fmt(db, def, mod_path),
339 Definition::ModuleDef(it) => match it { 345 Definition::ModuleDef(it) => match it {
340 ModuleDef::Module(it) => from_hir_fmt(db, it, mod_path), 346 ModuleDef::Module(it) => from_hir_fmt(db, it, mod_path),
diff --git a/crates/ide_completion/src/render/macro_.rs b/crates/ide_completion/src/render/macro_.rs
index 3fa21ba7c..7578ad50b 100644
--- a/crates/ide_completion/src/render/macro_.rs
+++ b/crates/ide_completion/src/render/macro_.rs
@@ -91,7 +91,7 @@ impl<'a> MacroRender<'a> {
91 } 91 }
92 92
93 fn detail(&self) -> Option<String> { 93 fn detail(&self) -> Option<String> {
94 let ast_node = self.macro_.source(self.ctx.db())?.value; 94 let ast_node = self.macro_.source(self.ctx.db())?.value.left()?;
95 Some(macro_label(&ast_node)) 95 Some(macro_label(&ast_node))
96 } 96 }
97} 97}