aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-04-21 11:34:07 +0100
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-04-21 11:34:07 +0100
commitfa15c4d75e87bd3bf761c91f030c76aec59308ae (patch)
treeba7a3495b13e41231076d5a0e491132bbdb0670e /crates/ra_hir/src
parent493bf20b3d1a0a890514d5252901f13d2878ff34 (diff)
parent9e35bf91b827900b089a7ea937cb73707bebc420 (diff)
Merge #1175
1175: Fix bugs and add error log about macro expansion r=matklad a=edwin0cheng This PR fixed / add following things: * Add a fused count which stop recursion of macro expansion in name resolution. * Add some logs when macro expansion fails * Add `$crate` meta variable support in mbe, which create a `$crate` ident token in token tree. * Fixed matching a `$REPEAT` pattern inside a subtree, e.g. `(fn $name:ident {$($i:ident)*} ) => {...}` * Remove composite-able punct token in syntax node to token conversion. Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/ids.rs24
-rw-r--r--crates/ra_hir/src/nameres/collector.rs21
2 files changed, 39 insertions, 6 deletions
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index 141c9072f..2a1ed9b81 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -63,8 +63,15 @@ impl HirFileId {
63 match file_id.0 { 63 match file_id.0 {
64 HirFileIdRepr::File(file_id) => db.parse(file_id), 64 HirFileIdRepr::File(file_id) => db.parse(file_id),
65 HirFileIdRepr::Macro(macro_call_id) => { 65 HirFileIdRepr::Macro(macro_call_id) => {
66 // returning an empty string looks fishy... 66 parse_macro(db, macro_call_id).unwrap_or_else(|| {
67 parse_macro(db, macro_call_id).unwrap_or_else(|| SourceFile::parse("")) 67 // Note:
68 // The final goal we would like to make all parse_macro success,
69 // such that the following log will not call anyway.
70 log::warn!("fail on macro_parse: {}", macro_call_id.debug_dump(db));
71
72 // returning an empty string looks fishy...
73 SourceFile::parse("")
74 })
68 } 75 }
69 } 76 }
70 } 77 }
@@ -299,3 +306,16 @@ impl AstItemDef<ast::TypeAliasDef> for TypeAliasId {
299 db.lookup_intern_type_alias(self) 306 db.lookup_intern_type_alias(self)
300 } 307 }
301} 308}
309
310impl MacroCallId {
311 pub fn debug_dump(&self, db: &impl DefDatabase) -> String {
312 let loc = self.clone().loc(db);
313 let node = loc.ast_id.to_node(db);
314 let syntax_str = node.syntax().to_string();
315
316 // dump the file name
317 let file_id: HirFileId = self.clone().into();
318 let original = file_id.original_file(db);
319 format!("macro call [file: {:#?}] : {}", db.file_relative_path(original), syntax_str)
320 }
321}
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index 39cadc94a..6147b3219 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -42,6 +42,7 @@ pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> C
42 unresolved_imports: Vec::new(), 42 unresolved_imports: Vec::new(),
43 unexpanded_macros: Vec::new(), 43 unexpanded_macros: Vec::new(),
44 global_macro_scope: FxHashMap::default(), 44 global_macro_scope: FxHashMap::default(),
45 marco_stack_count: 0,
45 }; 46 };
46 collector.collect(); 47 collector.collect();
47 collector.finish() 48 collector.finish()
@@ -55,6 +56,10 @@ struct DefCollector<DB> {
55 unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>, 56 unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>,
56 unexpanded_macros: Vec<(CrateModuleId, AstId<ast::MacroCall>, Path)>, 57 unexpanded_macros: Vec<(CrateModuleId, AstId<ast::MacroCall>, Path)>,
57 global_macro_scope: FxHashMap<Name, MacroDefId>, 58 global_macro_scope: FxHashMap<Name, MacroDefId>,
59
60 /// Some macro use `$tt:tt which mean we have to handle the macro perfectly
61 /// To prevent stackoverflow, we add a deep counter here for prevent that.
62 marco_stack_count: u32,
58} 63}
59 64
60impl<'a, DB> DefCollector<&'a DB> 65impl<'a, DB> DefCollector<&'a DB>
@@ -324,10 +329,18 @@ where
324 } 329 }
325 330
326 fn collect_macro_expansion(&mut self, module_id: CrateModuleId, macro_call_id: MacroCallId) { 331 fn collect_macro_expansion(&mut self, module_id: CrateModuleId, macro_call_id: MacroCallId) {
327 let file_id: HirFileId = macro_call_id.into(); 332 self.marco_stack_count += 1;
328 let raw_items = self.db.raw_items(file_id); 333
329 ModCollector { def_collector: &mut *self, file_id, module_id, raw_items: &raw_items } 334 if self.marco_stack_count < 300 {
330 .collect(raw_items.items()) 335 let file_id: HirFileId = macro_call_id.into();
336 let raw_items = self.db.raw_items(file_id);
337 ModCollector { def_collector: &mut *self, file_id, module_id, raw_items: &raw_items }
338 .collect(raw_items.items())
339 } else {
340 log::error!("Too deep macro expansion: {}", macro_call_id.debug_dump(self.db));
341 }
342
343 self.marco_stack_count -= 1;
331 } 344 }
332 345
333 fn finish(self) -> CrateDefMap { 346 fn finish(self) -> CrateDefMap {