diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-05-27 12:56:26 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-05-27 12:56:26 +0100 |
commit | d0a4ba294ccf0c925a5ff1115c19a60c6a24b734 (patch) | |
tree | 5caf7619e3486f68516d81971abc3018ddee5323 /crates/hir_def/src/nameres | |
parent | bfb06e17acd4bcb623ad5656490a7a1971980441 (diff) | |
parent | 196cb65ead398f81340de431400103224d7de660 (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.rs | 66 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/diagnostics.rs | 16 |
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 | }; |
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 | ||
@@ -143,7 +144,7 @@ impl PartialResolvedImport { | |||
143 | 144 | ||
144 | #[derive(Clone, Debug, Eq, PartialEq)] | 145 | #[derive(Clone, Debug, Eq, PartialEq)] |
145 | enum ImportSource { | 146 | enum 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 | ||
3 | use cfg::{CfgExpr, CfgOptions}; | 3 | use cfg::{CfgExpr, CfgOptions}; |
4 | use hir_expand::MacroCallKind; | 4 | use hir_expand::MacroCallKind; |
5 | use la_arena::Idx; | ||
5 | use syntax::ast; | 6 | use syntax::ast; |
6 | 7 | ||
7 | use crate::{nameres::LocalModuleId, path::ModPath, AstId}; | 8 | use 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)] |
10 | pub enum DefDiagnosticKind { | 16 | pub 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( |