aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r--crates/ra_hir_def/src/lib.rs15
-rw-r--r--crates/ra_hir_def/src/nameres.rs35
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs38
3 files changed, 39 insertions, 49 deletions
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index 1d195d65d..b063530c2 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -35,7 +35,7 @@ use std::hash::{Hash, Hasher};
35 35
36use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, MacroDefId, Source}; 36use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, MacroDefId, Source};
37use ra_arena::{impl_arena_id, map::ArenaMap, RawId}; 37use ra_arena::{impl_arena_id, map::ArenaMap, RawId};
38use ra_db::{salsa, CrateId}; 38use ra_db::{impl_intern_key, salsa, CrateId};
39use ra_syntax::{ast, AstNode}; 39use ra_syntax::{ast, AstNode};
40 40
41use crate::{builtin_type::BuiltinType, db::InternDatabase}; 41use crate::{builtin_type::BuiltinType, db::InternDatabase};
@@ -56,19 +56,6 @@ pub struct ModuleId {
56pub struct LocalModuleId(RawId); 56pub struct LocalModuleId(RawId);
57impl_arena_id!(LocalModuleId); 57impl_arena_id!(LocalModuleId);
58 58
59macro_rules! impl_intern_key {
60 ($name:ident) => {
61 impl salsa::InternKey for $name {
62 fn from_intern_id(v: salsa::InternId) -> Self {
63 $name(v)
64 }
65 fn as_intern_id(&self) -> salsa::InternId {
66 self.0
67 }
68 }
69 };
70}
71
72#[derive(Debug)] 59#[derive(Debug)]
73pub struct ItemLoc<N: AstNode> { 60pub struct ItemLoc<N: AstNode> {
74 pub(crate) module: ModuleId, 61 pub(crate) module: ModuleId,
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs
index 3b2e99647..f6cf59c5f 100644
--- a/crates/ra_hir_def/src/nameres.rs
+++ b/crates/ra_hir_def/src/nameres.rs
@@ -66,7 +66,7 @@ use ra_arena::Arena;
66use ra_db::{CrateId, Edition, FileId}; 66use ra_db::{CrateId, Edition, FileId};
67use ra_prof::profile; 67use ra_prof::profile;
68use ra_syntax::ast; 68use ra_syntax::ast;
69use rustc_hash::{FxHashMap, FxHashSet}; 69use rustc_hash::FxHashMap;
70 70
71use crate::{ 71use crate::{
72 builtin_type::BuiltinType, 72 builtin_type::BuiltinType,
@@ -90,18 +90,6 @@ pub struct CrateDefMap {
90 root: LocalModuleId, 90 root: LocalModuleId,
91 modules: Arena<LocalModuleId, ModuleData>, 91 modules: Arena<LocalModuleId, ModuleData>,
92 92
93 /// Some macros are not well-behavior, which leads to infinite loop
94 /// e.g. macro_rules! foo { ($ty:ty) => { foo!($ty); } }
95 /// We mark it down and skip it in collector
96 ///
97 /// FIXME:
98 /// Right now it only handle a poison macro in a single crate,
99 /// such that if other crate try to call that macro,
100 /// the whole process will do again until it became poisoned in that crate.
101 /// We should handle this macro set globally
102 /// However, do we want to put it as a global variable?
103 poison_macros: FxHashSet<MacroDefId>,
104
105 diagnostics: Vec<DefDiagnostic>, 93 diagnostics: Vec<DefDiagnostic>,
106} 94}
107 95
@@ -234,7 +222,6 @@ impl CrateDefMap {
234 prelude: None, 222 prelude: None,
235 root, 223 root,
236 modules, 224 modules,
237 poison_macros: FxHashSet::default(),
238 diagnostics: Vec::new(), 225 diagnostics: Vec::new(),
239 } 226 }
240 }; 227 };
@@ -267,16 +254,6 @@ impl CrateDefMap {
267 self.diagnostics.iter().for_each(|it| it.add_to(db, module, sink)) 254 self.diagnostics.iter().for_each(|it| it.add_to(db, module, sink))
268 } 255 }
269 256
270 pub fn resolve_path(
271 &self,
272 db: &impl DefDatabase,
273 original_module: LocalModuleId,
274 path: &Path,
275 ) -> (PerNs, Option<usize>) {
276 let res = self.resolve_path_fp_with_macro(db, ResolveMode::Other, original_module, path);
277 (res.resolved_def, res.segment_index)
278 }
279
280 pub fn modules(&self) -> impl Iterator<Item = LocalModuleId> + '_ { 257 pub fn modules(&self) -> impl Iterator<Item = LocalModuleId> + '_ {
281 self.modules.iter().map(|(id, _data)| id) 258 self.modules.iter().map(|(id, _data)| id)
282 } 259 }
@@ -287,6 +264,16 @@ impl CrateDefMap {
287 .filter(move |(_id, data)| data.definition == Some(file_id)) 264 .filter(move |(_id, data)| data.definition == Some(file_id))
288 .map(|(id, _data)| id) 265 .map(|(id, _data)| id)
289 } 266 }
267
268 pub(crate) fn resolve_path(
269 &self,
270 db: &impl DefDatabase,
271 original_module: LocalModuleId,
272 path: &Path,
273 ) -> (PerNs, Option<usize>) {
274 let res = self.resolve_path_fp_with_macro(db, ResolveMode::Other, original_module, path);
275 (res.resolved_def, res.segment_index)
276 }
290} 277}
291 278
292impl ModuleData { 279impl ModuleData {
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index b02364e86..1d004b6a6 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -8,7 +8,7 @@ use hir_expand::{
8use ra_cfg::CfgOptions; 8use ra_cfg::CfgOptions;
9use ra_db::{CrateId, FileId}; 9use ra_db::{CrateId, FileId};
10use ra_syntax::{ast, SmolStr}; 10use ra_syntax::{ast, SmolStr};
11use rustc_hash::FxHashMap; 11use rustc_hash::{FxHashMap, FxHashSet};
12use test_utils::tested_by; 12use test_utils::tested_by;
13 13
14use crate::{ 14use crate::{
@@ -57,6 +57,7 @@ pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> C
57 unexpanded_macros: Vec::new(), 57 unexpanded_macros: Vec::new(),
58 mod_dirs: FxHashMap::default(), 58 mod_dirs: FxHashMap::default(),
59 macro_stack_monitor: MacroStackMonitor::default(), 59 macro_stack_monitor: MacroStackMonitor::default(),
60 poison_macros: FxHashSet::default(),
60 cfg_options, 61 cfg_options,
61 }; 62 };
62 collector.collect(); 63 collector.collect();
@@ -103,6 +104,17 @@ struct DefCollector<'a, DB> {
103 /// Some macro use `$tt:tt which mean we have to handle the macro perfectly 104 /// Some macro use `$tt:tt which mean we have to handle the macro perfectly
104 /// To prevent stack overflow, we add a deep counter here for prevent that. 105 /// To prevent stack overflow, we add a deep counter here for prevent that.
105 macro_stack_monitor: MacroStackMonitor, 106 macro_stack_monitor: MacroStackMonitor,
107 /// Some macros are not well-behavior, which leads to infinite loop
108 /// e.g. macro_rules! foo { ($ty:ty) => { foo!($ty); } }
109 /// We mark it down and skip it in collector
110 ///
111 /// FIXME:
112 /// Right now it only handle a poison macro in a single crate,
113 /// such that if other crate try to call that macro,
114 /// the whole process will do again until it became poisoned in that crate.
115 /// We should handle this macro set globally
116 /// However, do we want to put it as a global variable?
117 poison_macros: FxHashSet<MacroDefId>,
106 118
107 cfg_options: &'a CfgOptions, 119 cfg_options: &'a CfgOptions,
108} 120}
@@ -489,7 +501,7 @@ where
489 macro_call_id: MacroCallId, 501 macro_call_id: MacroCallId,
490 macro_def_id: MacroDefId, 502 macro_def_id: MacroDefId,
491 ) { 503 ) {
492 if self.def_map.poison_macros.contains(&macro_def_id) { 504 if self.poison_macros.contains(&macro_def_id) {
493 return; 505 return;
494 } 506 }
495 507
@@ -509,7 +521,7 @@ where
509 .collect(raw_items.items()); 521 .collect(raw_items.items());
510 } else { 522 } else {
511 log::error!("Too deep macro expansion: {:?}", macro_call_id); 523 log::error!("Too deep macro expansion: {:?}", macro_call_id);
512 self.def_map.poison_macros.insert(macro_def_id); 524 self.poison_macros.insert(macro_def_id);
513 } 525 }
514 526
515 self.macro_stack_monitor.decrease(macro_def_id); 527 self.macro_stack_monitor.decrease(macro_def_id);
@@ -807,7 +819,7 @@ mod tests {
807 db: &impl DefDatabase, 819 db: &impl DefDatabase,
808 def_map: CrateDefMap, 820 def_map: CrateDefMap,
809 monitor: MacroStackMonitor, 821 monitor: MacroStackMonitor,
810 ) -> CrateDefMap { 822 ) -> (CrateDefMap, FxHashSet<MacroDefId>) {
811 let mut collector = DefCollector { 823 let mut collector = DefCollector {
812 db, 824 db,
813 def_map, 825 def_map,
@@ -816,13 +828,18 @@ mod tests {
816 unexpanded_macros: Vec::new(), 828 unexpanded_macros: Vec::new(),
817 mod_dirs: FxHashMap::default(), 829 mod_dirs: FxHashMap::default(),
818 macro_stack_monitor: monitor, 830 macro_stack_monitor: monitor,
831 poison_macros: FxHashSet::default(),
819 cfg_options: &CfgOptions::default(), 832 cfg_options: &CfgOptions::default(),
820 }; 833 };
821 collector.collect(); 834 collector.collect();
822 collector.finish() 835 (collector.def_map, collector.poison_macros)
823 } 836 }
824 837
825 fn do_limited_resolve(code: &str, limit: u32, poison_limit: u32) -> CrateDefMap { 838 fn do_limited_resolve(
839 code: &str,
840 limit: u32,
841 poison_limit: u32,
842 ) -> (CrateDefMap, FxHashSet<MacroDefId>) {
826 let (db, _file_id) = TestDB::with_single_file(&code); 843 let (db, _file_id) = TestDB::with_single_file(&code);
827 let krate = db.test_crate(); 844 let krate = db.test_crate();
828 845
@@ -837,7 +854,6 @@ mod tests {
837 prelude: None, 854 prelude: None,
838 root, 855 root,
839 modules, 856 modules,
840 poison_macros: FxHashSet::default(),
841 diagnostics: Vec::new(), 857 diagnostics: Vec::new(),
842 } 858 }
843 }; 859 };
@@ -867,7 +883,7 @@ foo!(KABOOM);
867 883
868 #[test] 884 #[test]
869 fn test_macro_expand_poisoned() { 885 fn test_macro_expand_poisoned() {
870 let def = do_limited_resolve( 886 let (_, poison_macros) = do_limited_resolve(
871 r#" 887 r#"
872 macro_rules! foo { 888 macro_rules! foo {
873 ($ty:ty) => { foo!($ty); } 889 ($ty:ty) => { foo!($ty); }
@@ -878,12 +894,12 @@ foo!(KABOOM);
878 16, 894 16,
879 ); 895 );
880 896
881 assert_eq!(def.poison_macros.len(), 1); 897 assert_eq!(poison_macros.len(), 1);
882 } 898 }
883 899
884 #[test] 900 #[test]
885 fn test_macro_expand_normal() { 901 fn test_macro_expand_normal() {
886 let def = do_limited_resolve( 902 let (_, poison_macros) = do_limited_resolve(
887 r#" 903 r#"
888 macro_rules! foo { 904 macro_rules! foo {
889 ($ident:ident) => { struct $ident {} } 905 ($ident:ident) => { struct $ident {} }
@@ -894,6 +910,6 @@ foo!(Bar);
894 16, 910 16,
895 ); 911 );
896 912
897 assert_eq!(def.poison_macros.len(), 0); 913 assert_eq!(poison_macros.len(), 0);
898 } 914 }
899} 915}