diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/ids.rs | 24 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 21 |
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 | |||
310 | impl 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 | ||
60 | impl<'a, DB> DefCollector<&'a DB> | 65 | impl<'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 { |