aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/nameres/collector.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/nameres/collector.rs')
-rw-r--r--crates/hir_def/src/nameres/collector.rs84
1 files changed, 49 insertions, 35 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 014ea4de4..d9d6c91a8 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -17,6 +17,7 @@ use hir_expand::{
17}; 17};
18use hir_expand::{InFile, MacroCallLoc}; 18use hir_expand::{InFile, MacroCallLoc};
19use itertools::Itertools; 19use itertools::Itertools;
20use la_arena::Idx;
20use rustc_hash::{FxHashMap, FxHashSet}; 21use rustc_hash::{FxHashMap, FxHashSet};
21use syntax::ast; 22use syntax::ast;
22 23
@@ -33,7 +34,10 @@ use crate::{
33 }, 34 },
34 macro_call_as_call_id, 35 macro_call_as_call_id,
35 nameres::{ 36 nameres::{
36 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, 37 diagnostics::DefDiagnostic,
38 mod_resolution::ModDir,
39 path_resolution::ReachedFixedPoint,
40 proc_macro::{ProcMacroDef, ProcMacroKind},
37 BuiltinShadowMode, DefMap, ModuleData, ModuleOrigin, ResolveMode, 41 BuiltinShadowMode, DefMap, ModuleData, ModuleOrigin, ResolveMode,
38 }, 42 },
39 path::{ImportAlias, ModPath, PathKind}, 43 path::{ImportAlias, ModPath, PathKind},
@@ -44,8 +48,6 @@ use crate::{
44 UnresolvedMacro, 48 UnresolvedMacro,
45}; 49};
46 50
47use super::proc_macro::{ProcMacroDef, ProcMacroKind};
48
49const GLOB_RECURSION_LIMIT: usize = 100; 51const GLOB_RECURSION_LIMIT: usize = 100;
50const EXPANSION_DEPTH_LIMIT: usize = 128; 52const EXPANSION_DEPTH_LIMIT: usize = 128;
51const FIXED_POINT_LIMIT: usize = 8192; 53const FIXED_POINT_LIMIT: usize = 8192;
@@ -142,7 +144,7 @@ impl PartialResolvedImport {
142 144
143#[derive(Clone, Debug, Eq, PartialEq)] 145#[derive(Clone, Debug, Eq, PartialEq)]
144enum ImportSource { 146enum ImportSource {
145 Import(ItemTreeId<item_tree::Import>), 147 Import { id: ItemTreeId<item_tree::Import>, use_tree: Idx<ast::UseTree> },
146 ExternCrate(ItemTreeId<item_tree::ExternCrate>), 148 ExternCrate(ItemTreeId<item_tree::ExternCrate>),
147} 149}
148 150
@@ -164,20 +166,26 @@ impl Import {
164 krate: CrateId, 166 krate: CrateId,
165 tree: &ItemTree, 167 tree: &ItemTree,
166 id: ItemTreeId<item_tree::Import>, 168 id: ItemTreeId<item_tree::Import>,
167 ) -> Self { 169 ) -> Vec<Self> {
168 let it = &tree[id.value]; 170 let it = &tree[id.value];
169 let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into()); 171 let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into());
170 let visibility = &tree[it.visibility]; 172 let visibility = &tree[it.visibility];
171 Self { 173 let is_prelude = attrs.by_key("prelude_import").exists();
172 path: it.path.clone(), 174
173 alias: it.alias.clone(), 175 let mut res = Vec::new();
174 visibility: visibility.clone(), 176 it.use_tree.expand(|idx, path, is_glob, alias| {
175 is_glob: it.is_glob, 177 res.push(Self {
176 is_prelude: attrs.by_key("prelude_import").exists(), 178 path: Interned::new(path), // FIXME this makes little sense
177 is_extern_crate: false, 179 alias,
178 is_macro_use: false, 180 visibility: visibility.clone(),
179 source: ImportSource::Import(id), 181 is_glob,
180 } 182 is_prelude,
183 is_extern_crate: false,
184 is_macro_use: false,
185 source: ImportSource::Import { id, use_tree: idx },
186 });
187 });
188 res
181 } 189 }
182 190
183 fn from_extern_crate( 191 fn from_extern_crate(
@@ -285,7 +293,7 @@ impl DefCollector<'_> {
285 let registered_name = if *attr_name == hir_expand::name![register_attr] 293 let registered_name = if *attr_name == hir_expand::name![register_attr]
286 || *attr_name == hir_expand::name![register_tool] 294 || *attr_name == hir_expand::name![register_tool]
287 { 295 {
288 match &attr.input { 296 match attr.input.as_deref() {
289 Some(AttrInput::TokenTree(subtree)) => match &*subtree.token_trees { 297 Some(AttrInput::TokenTree(subtree)) => match &*subtree.token_trees {
290 [tt::TokenTree::Leaf(tt::Leaf::Ident(name))] => name.as_name(), 298 [tt::TokenTree::Leaf(tt::Leaf::Ident(name))] => name.as_name(),
291 _ => continue, 299 _ => continue,
@@ -469,16 +477,21 @@ impl DefCollector<'_> {
469 /// going out of sync with what the build system sees (since we resolve using VFS state, but 477 /// going out of sync with what the build system sees (since we resolve using VFS state, but
470 /// Cargo builds only on-disk files). We could and probably should add diagnostics for that. 478 /// Cargo builds only on-disk files). We could and probably should add diagnostics for that.
471 fn export_proc_macro(&mut self, def: ProcMacroDef, ast_id: AstId<ast::Fn>) { 479 fn export_proc_macro(&mut self, def: ProcMacroDef, ast_id: AstId<ast::Fn>) {
480 let kind = def.kind.to_basedb_kind();
472 self.exports_proc_macros = true; 481 self.exports_proc_macros = true;
473 let macro_def = match self.proc_macros.iter().find(|(n, _)| n == &def.name) { 482 let macro_def = match self.proc_macros.iter().find(|(n, _)| n == &def.name) {
474 Some((_, expander)) => MacroDefId { 483 Some((_, expander)) => MacroDefId {
475 krate: self.def_map.krate, 484 krate: self.def_map.krate,
476 kind: MacroDefKind::ProcMacro(*expander, ast_id), 485 kind: MacroDefKind::ProcMacro(*expander, kind, ast_id),
477 local_inner: false, 486 local_inner: false,
478 }, 487 },
479 None => MacroDefId { 488 None => MacroDefId {
480 krate: self.def_map.krate, 489 krate: self.def_map.krate,
481 kind: MacroDefKind::ProcMacro(ProcMacroExpander::dummy(self.def_map.krate), ast_id), 490 kind: MacroDefKind::ProcMacro(
491 ProcMacroExpander::dummy(self.def_map.krate),
492 kind,
493 ast_id,
494 ),
482 local_inner: false, 495 local_inner: false,
483 }, 496 },
484 }; 497 };
@@ -1129,11 +1142,8 @@ impl DefCollector<'_> {
1129 } 1142 }
1130 1143
1131 for directive in &self.unresolved_imports { 1144 for directive in &self.unresolved_imports {
1132 if let ImportSource::Import(import) = &directive.import.source { 1145 if let ImportSource::Import { id: import, use_tree } = &directive.import.source {
1133 let item_tree = import.item_tree(self.db); 1146 match (directive.import.path.segments().first(), &directive.import.path.kind) {
1134 let import_data = &item_tree[import.value];
1135
1136 match (import_data.path.segments().first(), &import_data.path.kind) {
1137 (Some(krate), PathKind::Plain) | (Some(krate), PathKind::Abs) => { 1147 (Some(krate), PathKind::Plain) | (Some(krate), PathKind::Abs) => {
1138 if diagnosed_extern_crates.contains(krate) { 1148 if diagnosed_extern_crates.contains(krate) {
1139 continue; 1149 continue;
@@ -1144,8 +1154,8 @@ impl DefCollector<'_> {
1144 1154
1145 self.def_map.diagnostics.push(DefDiagnostic::unresolved_import( 1155 self.def_map.diagnostics.push(DefDiagnostic::unresolved_import(
1146 directive.module_id, 1156 directive.module_id,
1147 InFile::new(import.file_id(), import_data.ast_id), 1157 *import,
1148 import_data.index, 1158 *use_tree,
1149 )); 1159 ));
1150 } 1160 }
1151 } 1161 }
@@ -1221,16 +1231,20 @@ impl ModCollector<'_, '_> {
1221 match item { 1231 match item {
1222 ModItem::Mod(m) => self.collect_module(&self.item_tree[m], &attrs), 1232 ModItem::Mod(m) => self.collect_module(&self.item_tree[m], &attrs),
1223 ModItem::Import(import_id) => { 1233 ModItem::Import(import_id) => {
1224 self.def_collector.unresolved_imports.push(ImportDirective { 1234 let module_id = self.module_id;
1225 module_id: self.module_id, 1235 let imports = Import::from_use(
1226 import: Import::from_use( 1236 self.def_collector.db,
1227 self.def_collector.db, 1237 krate,
1228 krate, 1238 &self.item_tree,
1229 &self.item_tree, 1239 ItemTreeId::new(self.file_id, import_id),
1230 ItemTreeId::new(self.file_id, import_id), 1240 );
1231 ), 1241 self.def_collector.unresolved_imports.extend(imports.into_iter().map(
1232 status: PartialResolvedImport::Unresolved, 1242 |import| ImportDirective {
1233 }) 1243 module_id,
1244 import,
1245 status: PartialResolvedImport::Unresolved,
1246 },
1247 ));
1234 } 1248 }
1235 ModItem::ExternCrate(import_id) => { 1249 ModItem::ExternCrate(import_id) => {
1236 self.def_collector.unresolved_imports.push(ImportDirective { 1250 self.def_collector.unresolved_imports.push(ImportDirective {