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.rs59
1 files changed, 40 insertions, 19 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index b114a6fe4..a636ec77d 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -136,23 +136,35 @@ struct Import {
136} 136}
137 137
138impl Import { 138impl Import {
139 fn from_use(tree: &ItemTree, id: ItemTreeId<item_tree::Import>) -> Self { 139 fn from_use(
140 db: &dyn DefDatabase,
141 krate: CrateId,
142 tree: &ItemTree,
143 id: ItemTreeId<item_tree::Import>,
144 ) -> Self {
140 let it = &tree[id.value]; 145 let it = &tree[id.value];
146 let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into());
141 let visibility = &tree[it.visibility]; 147 let visibility = &tree[it.visibility];
142 Self { 148 Self {
143 path: it.path.clone(), 149 path: it.path.clone(),
144 alias: it.alias.clone(), 150 alias: it.alias.clone(),
145 visibility: visibility.clone(), 151 visibility: visibility.clone(),
146 is_glob: it.is_glob, 152 is_glob: it.is_glob,
147 is_prelude: it.is_prelude, 153 is_prelude: attrs.by_key("prelude_import").exists(),
148 is_extern_crate: false, 154 is_extern_crate: false,
149 is_macro_use: false, 155 is_macro_use: false,
150 source: ImportSource::Import(id), 156 source: ImportSource::Import(id),
151 } 157 }
152 } 158 }
153 159
154 fn from_extern_crate(tree: &ItemTree, id: ItemTreeId<item_tree::ExternCrate>) -> Self { 160 fn from_extern_crate(
161 db: &dyn DefDatabase,
162 krate: CrateId,
163 tree: &ItemTree,
164 id: ItemTreeId<item_tree::ExternCrate>,
165 ) -> Self {
155 let it = &tree[id.value]; 166 let it = &tree[id.value];
167 let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into());
156 let visibility = &tree[it.visibility]; 168 let visibility = &tree[it.visibility];
157 Self { 169 Self {
158 path: ModPath::from_segments(PathKind::Plain, iter::once(it.name.clone())), 170 path: ModPath::from_segments(PathKind::Plain, iter::once(it.name.clone())),
@@ -161,7 +173,7 @@ impl Import {
161 is_glob: false, 173 is_glob: false,
162 is_prelude: false, 174 is_prelude: false,
163 is_extern_crate: true, 175 is_extern_crate: true,
164 is_macro_use: it.is_macro_use, 176 is_macro_use: attrs.by_key("macro_use").exists(),
165 source: ImportSource::ExternCrate(id), 177 source: ImportSource::ExternCrate(id),
166 } 178 }
167 } 179 }
@@ -930,7 +942,12 @@ impl ModCollector<'_, '_> {
930 if attrs.cfg().map_or(true, |cfg| self.is_cfg_enabled(&cfg)) { 942 if attrs.cfg().map_or(true, |cfg| self.is_cfg_enabled(&cfg)) {
931 if let ModItem::ExternCrate(id) = item { 943 if let ModItem::ExternCrate(id) = item {
932 let import = self.item_tree[*id].clone(); 944 let import = self.item_tree[*id].clone();
933 if import.is_macro_use { 945 let attrs = self.item_tree.attrs(
946 self.def_collector.db,
947 krate,
948 ModItem::from(*id).into(),
949 );
950 if attrs.by_key("macro_use").exists() {
934 self.def_collector.import_macros_from_extern_crate(self.module_id, &import); 951 self.def_collector.import_macros_from_extern_crate(self.module_id, &import);
935 } 952 }
936 } 953 }
@@ -956,6 +973,8 @@ impl ModCollector<'_, '_> {
956 self.def_collector.unresolved_imports.push(ImportDirective { 973 self.def_collector.unresolved_imports.push(ImportDirective {
957 module_id: self.module_id, 974 module_id: self.module_id,
958 import: Import::from_use( 975 import: Import::from_use(
976 self.def_collector.db,
977 krate,
959 &self.item_tree, 978 &self.item_tree,
960 InFile::new(self.file_id, import_id), 979 InFile::new(self.file_id, import_id),
961 ), 980 ),
@@ -966,6 +985,8 @@ impl ModCollector<'_, '_> {
966 self.def_collector.unresolved_imports.push(ImportDirective { 985 self.def_collector.unresolved_imports.push(ImportDirective {
967 module_id: self.module_id, 986 module_id: self.module_id,
968 import: Import::from_extern_crate( 987 import: Import::from_extern_crate(
988 self.def_collector.db,
989 krate,
969 &self.item_tree, 990 &self.item_tree,
970 InFile::new(self.file_id, import_id), 991 InFile::new(self.file_id, import_id),
971 ), 992 ),
@@ -1268,20 +1289,20 @@ impl ModCollector<'_, '_> {
1268 } 1289 }
1269 1290
1270 fn collect_derives(&mut self, attrs: &Attrs, ast_id: FileAstId<ast::Item>) { 1291 fn collect_derives(&mut self, attrs: &Attrs, ast_id: FileAstId<ast::Item>) {
1271 for derive_subtree in attrs.by_key("derive").tt_values() { 1292 for derive in attrs.by_key("derive").attrs() {
1272 // for #[derive(Copy, Clone)], `derive_subtree` is the `(Copy, Clone)` subtree 1293 match derive.parse_derive() {
1273 for tt in &derive_subtree.token_trees { 1294 Some(derive_macros) => {
1274 let ident = match &tt { 1295 for path in derive_macros {
1275 tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => ident, 1296 let ast_id = AstIdWithPath::new(self.file_id, ast_id, path);
1276 tt::TokenTree::Leaf(tt::Leaf::Punct(_)) => continue, // , is ok 1297 self.def_collector
1277 _ => continue, // anything else would be an error (which we currently ignore) 1298 .unexpanded_attribute_macros
1278 }; 1299 .push(DeriveDirective { module_id: self.module_id, ast_id });
1279 let path = ModPath::from_tt_ident(ident); 1300 }
1280 1301 }
1281 let ast_id = AstIdWithPath::new(self.file_id, ast_id, path); 1302 None => {
1282 self.def_collector 1303 // FIXME: diagnose
1283 .unexpanded_attribute_macros 1304 log::debug!("malformed derive: {:?}", derive);
1284 .push(DeriveDirective { module_id: self.module_id, ast_id }); 1305 }
1285 } 1306 }
1286 } 1307 }
1287 } 1308 }