aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/nameres
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-05-27 12:56:26 +0100
committerGitHub <[email protected]>2021-05-27 12:56:26 +0100
commitd0a4ba294ccf0c925a5ff1115c19a60c6a24b734 (patch)
tree5caf7619e3486f68516d81971abc3018ddee5323 /crates/hir_def/src/nameres
parentbfb06e17acd4bcb623ad5656490a7a1971980441 (diff)
parent196cb65ead398f81340de431400103224d7de660 (diff)
Merge #8997
8997: internal: stop expanding UseTrees during ItemTree lowering r=jonas-schievink a=jonas-schievink Closes https://github.com/rust-analyzer/rust-analyzer/issues/8908 Messy diff, but `ItemTree` lowering got simpler, since we now have a strict 1-to-1 mapping between `ast::Item` and `ModItem`. The most messy part is mapping a single `UseTree` back to its `ast::UseTree` counterpart for diagnostics, but I think the ad-hoc source map built during lowering does the job. Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/hir_def/src/nameres')
-rw-r--r--crates/hir_def/src/nameres/collector.rs66
-rw-r--r--crates/hir_def/src/nameres/diagnostics.rs16
2 files changed, 48 insertions, 34 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 3ea472908..4296c6304 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
@@ -143,7 +144,7 @@ impl PartialResolvedImport {
143 144
144#[derive(Clone, Debug, Eq, PartialEq)] 145#[derive(Clone, Debug, Eq, PartialEq)]
145enum ImportSource { 146enum ImportSource {
146 Import(ItemTreeId<item_tree::Import>), 147 Import { id: ItemTreeId<item_tree::Import>, use_tree: Idx<ast::UseTree> },
147 ExternCrate(ItemTreeId<item_tree::ExternCrate>), 148 ExternCrate(ItemTreeId<item_tree::ExternCrate>),
148} 149}
149 150
@@ -165,20 +166,26 @@ impl Import {
165 krate: CrateId, 166 krate: CrateId,
166 tree: &ItemTree, 167 tree: &ItemTree,
167 id: ItemTreeId<item_tree::Import>, 168 id: ItemTreeId<item_tree::Import>,
168 ) -> Self { 169 ) -> Vec<Self> {
169 let it = &tree[id.value]; 170 let it = &tree[id.value];
170 let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into()); 171 let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into());
171 let visibility = &tree[it.visibility]; 172 let visibility = &tree[it.visibility];
172 Self { 173 let is_prelude = attrs.by_key("prelude_import").exists();
173 path: it.path.clone(), 174
174 alias: it.alias.clone(), 175 let mut res = Vec::new();
175 visibility: visibility.clone(), 176 it.use_tree.expand(|idx, path, is_glob, alias| {
176 is_glob: it.is_glob, 177 res.push(Self {
177 is_prelude: attrs.by_key("prelude_import").exists(), 178 path: Interned::new(path), // FIXME this makes little sense
178 is_extern_crate: false, 179 alias,
179 is_macro_use: false, 180 visibility: visibility.clone(),
180 source: ImportSource::Import(id), 181 is_glob,
181 } 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
182 } 189 }
183 190
184 fn from_extern_crate( 191 fn from_extern_crate(
@@ -1130,11 +1137,8 @@ impl DefCollector<'_> {
1130 } 1137 }
1131 1138
1132 for directive in &self.unresolved_imports { 1139 for directive in &self.unresolved_imports {
1133 if let ImportSource::Import(import) = &directive.import.source { 1140 if let ImportSource::Import { id: import, use_tree } = &directive.import.source {
1134 let item_tree = import.item_tree(self.db); 1141 match (directive.import.path.segments().first(), &directive.import.path.kind) {
1135 let import_data = &item_tree[import.value];
1136
1137 match (import_data.path.segments().first(), &import_data.path.kind) {
1138 (Some(krate), PathKind::Plain) | (Some(krate), PathKind::Abs) => { 1142 (Some(krate), PathKind::Plain) | (Some(krate), PathKind::Abs) => {
1139 if diagnosed_extern_crates.contains(krate) { 1143 if diagnosed_extern_crates.contains(krate) {
1140 continue; 1144 continue;
@@ -1145,8 +1149,8 @@ impl DefCollector<'_> {
1145 1149
1146 self.def_map.diagnostics.push(DefDiagnostic::unresolved_import( 1150 self.def_map.diagnostics.push(DefDiagnostic::unresolved_import(
1147 directive.module_id, 1151 directive.module_id,
1148 InFile::new(import.file_id(), import_data.ast_id), 1152 *import,
1149 import_data.index, 1153 *use_tree,
1150 )); 1154 ));
1151 } 1155 }
1152 } 1156 }
@@ -1222,16 +1226,20 @@ impl ModCollector<'_, '_> {
1222 match item { 1226 match item {
1223 ModItem::Mod(m) => self.collect_module(&self.item_tree[m], &attrs), 1227 ModItem::Mod(m) => self.collect_module(&self.item_tree[m], &attrs),
1224 ModItem::Import(import_id) => { 1228 ModItem::Import(import_id) => {
1225 self.def_collector.unresolved_imports.push(ImportDirective { 1229 let module_id = self.module_id;
1226 module_id: self.module_id, 1230 let imports = Import::from_use(
1227 import: Import::from_use( 1231 self.def_collector.db,
1228 self.def_collector.db, 1232 krate,
1229 krate, 1233 &self.item_tree,
1230 &self.item_tree, 1234 ItemTreeId::new(self.file_id, import_id),
1231 ItemTreeId::new(self.file_id, import_id), 1235 );
1232 ), 1236 self.def_collector.unresolved_imports.extend(imports.into_iter().map(
1233 status: PartialResolvedImport::Unresolved, 1237 |import| ImportDirective {
1234 }) 1238 module_id,
1239 import,
1240 status: PartialResolvedImport::Unresolved,
1241 },
1242 ));
1235 } 1243 }
1236 ModItem::ExternCrate(import_id) => { 1244 ModItem::ExternCrate(import_id) => {
1237 self.def_collector.unresolved_imports.push(ImportDirective { 1245 self.def_collector.unresolved_imports.push(ImportDirective {
diff --git a/crates/hir_def/src/nameres/diagnostics.rs b/crates/hir_def/src/nameres/diagnostics.rs
index 8f2f0ff9f..57c36c3c6 100644
--- a/crates/hir_def/src/nameres/diagnostics.rs
+++ b/crates/hir_def/src/nameres/diagnostics.rs
@@ -2,9 +2,15 @@
2 2
3use cfg::{CfgExpr, CfgOptions}; 3use cfg::{CfgExpr, CfgOptions};
4use hir_expand::MacroCallKind; 4use hir_expand::MacroCallKind;
5use la_arena::Idx;
5use syntax::ast; 6use syntax::ast;
6 7
7use crate::{nameres::LocalModuleId, path::ModPath, AstId}; 8use crate::{
9 item_tree::{self, ItemTreeId},
10 nameres::LocalModuleId,
11 path::ModPath,
12 AstId,
13};
8 14
9#[derive(Debug, PartialEq, Eq)] 15#[derive(Debug, PartialEq, Eq)]
10pub enum DefDiagnosticKind { 16pub enum DefDiagnosticKind {
@@ -12,7 +18,7 @@ pub enum DefDiagnosticKind {
12 18
13 UnresolvedExternCrate { ast: AstId<ast::ExternCrate> }, 19 UnresolvedExternCrate { ast: AstId<ast::ExternCrate> },
14 20
15 UnresolvedImport { ast: AstId<ast::Use>, index: usize }, 21 UnresolvedImport { id: ItemTreeId<item_tree::Import>, index: Idx<ast::UseTree> },
16 22
17 UnconfiguredCode { ast: AstId<ast::Item>, cfg: CfgExpr, opts: CfgOptions }, 23 UnconfiguredCode { ast: AstId<ast::Item>, cfg: CfgExpr, opts: CfgOptions },
18 24
@@ -53,10 +59,10 @@ impl DefDiagnostic {
53 59
54 pub(super) fn unresolved_import( 60 pub(super) fn unresolved_import(
55 container: LocalModuleId, 61 container: LocalModuleId,
56 ast: AstId<ast::Use>, 62 id: ItemTreeId<item_tree::Import>,
57 index: usize, 63 index: Idx<ast::UseTree>,
58 ) -> Self { 64 ) -> Self {
59 Self { in_module: container, kind: DefDiagnosticKind::UnresolvedImport { ast, index } } 65 Self { in_module: container, kind: DefDiagnosticKind::UnresolvedImport { id, index } }
60 } 66 }
61 67
62 pub(super) fn unconfigured_code( 68 pub(super) fn unconfigured_code(