From 9e35bf91b827900b089a7ea937cb73707bebc420 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sat, 20 Apr 2019 23:05:25 +0800 Subject: Fix bugs --- crates/ra_hir/src/ids.rs | 24 ++++++++++++++++++++++-- crates/ra_hir/src/nameres/collector.rs | 21 +++++++++++++++++---- 2 files changed, 39 insertions(+), 6 deletions(-) (limited to 'crates/ra_hir/src') 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 { match file_id.0 { HirFileIdRepr::File(file_id) => db.parse(file_id), HirFileIdRepr::Macro(macro_call_id) => { - // returning an empty string looks fishy... - parse_macro(db, macro_call_id).unwrap_or_else(|| SourceFile::parse("")) + parse_macro(db, macro_call_id).unwrap_or_else(|| { + // Note: + // The final goal we would like to make all parse_macro success, + // such that the following log will not call anyway. + log::warn!("fail on macro_parse: {}", macro_call_id.debug_dump(db)); + + // returning an empty string looks fishy... + SourceFile::parse("") + }) } } } @@ -299,3 +306,16 @@ impl AstItemDef for TypeAliasId { db.lookup_intern_type_alias(self) } } + +impl MacroCallId { + pub fn debug_dump(&self, db: &impl DefDatabase) -> String { + let loc = self.clone().loc(db); + let node = loc.ast_id.to_node(db); + let syntax_str = node.syntax().to_string(); + + // dump the file name + let file_id: HirFileId = self.clone().into(); + let original = file_id.original_file(db); + format!("macro call [file: {:#?}] : {}", db.file_relative_path(original), syntax_str) + } +} 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 unresolved_imports: Vec::new(), unexpanded_macros: Vec::new(), global_macro_scope: FxHashMap::default(), + marco_stack_count: 0, }; collector.collect(); collector.finish() @@ -55,6 +56,10 @@ struct DefCollector { unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>, unexpanded_macros: Vec<(CrateModuleId, AstId, Path)>, global_macro_scope: FxHashMap, + + /// Some macro use `$tt:tt which mean we have to handle the macro perfectly + /// To prevent stackoverflow, we add a deep counter here for prevent that. + marco_stack_count: u32, } impl<'a, DB> DefCollector<&'a DB> @@ -324,10 +329,18 @@ where } fn collect_macro_expansion(&mut self, module_id: CrateModuleId, macro_call_id: MacroCallId) { - let file_id: HirFileId = macro_call_id.into(); - let raw_items = self.db.raw_items(file_id); - ModCollector { def_collector: &mut *self, file_id, module_id, raw_items: &raw_items } - .collect(raw_items.items()) + self.marco_stack_count += 1; + + if self.marco_stack_count < 300 { + let file_id: HirFileId = macro_call_id.into(); + let raw_items = self.db.raw_items(file_id); + ModCollector { def_collector: &mut *self, file_id, module_id, raw_items: &raw_items } + .collect(raw_items.items()) + } else { + log::error!("Too deep macro expansion: {}", macro_call_id.debug_dump(self.db)); + } + + self.marco_stack_count -= 1; } fn finish(self) -> CrateDefMap { -- cgit v1.2.3