diff options
Diffstat (limited to 'crates/hir_def/src/nameres/collector.rs')
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 84 |
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 | }; |
18 | use hir_expand::{InFile, MacroCallLoc}; | 18 | use hir_expand::{InFile, MacroCallLoc}; |
19 | use itertools::Itertools; | 19 | use itertools::Itertools; |
20 | use la_arena::Idx; | ||
20 | use rustc_hash::{FxHashMap, FxHashSet}; | 21 | use rustc_hash::{FxHashMap, FxHashSet}; |
21 | use syntax::ast; | 22 | use 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 | ||
47 | use super::proc_macro::{ProcMacroDef, ProcMacroKind}; | ||
48 | |||
49 | const GLOB_RECURSION_LIMIT: usize = 100; | 51 | const GLOB_RECURSION_LIMIT: usize = 100; |
50 | const EXPANSION_DEPTH_LIMIT: usize = 128; | 52 | const EXPANSION_DEPTH_LIMIT: usize = 128; |
51 | const FIXED_POINT_LIMIT: usize = 8192; | 53 | const 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)] |
144 | enum ImportSource { | 146 | enum 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 { |