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.rs107
1 files changed, 69 insertions, 38 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 1936348fb..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 }
@@ -221,17 +233,20 @@ impl DefCollector<'_> {
221 let item_tree = self.db.item_tree(file_id.into()); 233 let item_tree = self.db.item_tree(file_id.into());
222 let module_id = self.def_map.root; 234 let module_id = self.def_map.root;
223 self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id }; 235 self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id };
224 let mut root_collector = ModCollector { 236 if item_tree
225 def_collector: &mut *self, 237 .top_level_attrs(self.db, self.def_map.krate)
226 macro_depth: 0, 238 .cfg()
227 module_id, 239 .map_or(true, |cfg| self.cfg_options.check(&cfg) != Some(false))
228 file_id: file_id.into(),
229 item_tree: &item_tree,
230 mod_dir: ModDir::root(),
231 };
232 if item_tree.top_level_attrs().cfg().map_or(true, |cfg| root_collector.is_cfg_enabled(&cfg))
233 { 240 {
234 root_collector.collect(item_tree.top_level_items()); 241 ModCollector {
242 def_collector: &mut *self,
243 macro_depth: 0,
244 module_id,
245 file_id: file_id.into(),
246 item_tree: &item_tree,
247 mod_dir: ModDir::root(),
248 }
249 .collect(item_tree.top_level_items());
235 } 250 }
236 251
237 // main name resolution fixed-point loop. 252 // main name resolution fixed-point loop.
@@ -905,6 +920,8 @@ struct ModCollector<'a, 'b> {
905 920
906impl ModCollector<'_, '_> { 921impl ModCollector<'_, '_> {
907 fn collect(&mut self, items: &[ModItem]) { 922 fn collect(&mut self, items: &[ModItem]) {
923 let krate = self.def_collector.def_map.krate;
924
908 // Note: don't assert that inserted value is fresh: it's simply not true 925 // Note: don't assert that inserted value is fresh: it's simply not true
909 // for macros. 926 // for macros.
910 self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone()); 927 self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone());
@@ -921,11 +938,16 @@ impl ModCollector<'_, '_> {
921 // `#[macro_use] extern crate` is hoisted to imports macros before collecting 938 // `#[macro_use] extern crate` is hoisted to imports macros before collecting
922 // any other items. 939 // any other items.
923 for item in items { 940 for item in items {
924 let attrs = self.item_tree.attrs((*item).into()); 941 let attrs = self.item_tree.attrs(self.def_collector.db, krate, (*item).into());
925 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)) {
926 if let ModItem::ExternCrate(id) = item { 943 if let ModItem::ExternCrate(id) = item {
927 let import = self.item_tree[*id].clone(); 944 let import = self.item_tree[*id].clone();
928 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() {
929 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);
930 } 952 }
931 } 953 }
@@ -933,7 +955,7 @@ impl ModCollector<'_, '_> {
933 } 955 }
934 956
935 for &item in items { 957 for &item in items {
936 let attrs = self.item_tree.attrs(item.into()); 958 let attrs = self.item_tree.attrs(self.def_collector.db, krate, item.into());
937 if let Some(cfg) = attrs.cfg() { 959 if let Some(cfg) = attrs.cfg() {
938 if !self.is_cfg_enabled(&cfg) { 960 if !self.is_cfg_enabled(&cfg) {
939 self.emit_unconfigured_diagnostic(item, &cfg); 961 self.emit_unconfigured_diagnostic(item, &cfg);
@@ -946,11 +968,13 @@ impl ModCollector<'_, '_> {
946 968
947 let mut def = None; 969 let mut def = None;
948 match item { 970 match item {
949 ModItem::Mod(m) => self.collect_module(&self.item_tree[m], attrs), 971 ModItem::Mod(m) => self.collect_module(&self.item_tree[m], &attrs),
950 ModItem::Import(import_id) => { 972 ModItem::Import(import_id) => {
951 self.def_collector.unresolved_imports.push(ImportDirective { 973 self.def_collector.unresolved_imports.push(ImportDirective {
952 module_id: self.module_id, 974 module_id: self.module_id,
953 import: Import::from_use( 975 import: Import::from_use(
976 self.def_collector.db,
977 krate,
954 &self.item_tree, 978 &self.item_tree,
955 InFile::new(self.file_id, import_id), 979 InFile::new(self.file_id, import_id),
956 ), 980 ),
@@ -961,6 +985,8 @@ impl ModCollector<'_, '_> {
961 self.def_collector.unresolved_imports.push(ImportDirective { 985 self.def_collector.unresolved_imports.push(ImportDirective {
962 module_id: self.module_id, 986 module_id: self.module_id,
963 import: Import::from_extern_crate( 987 import: Import::from_extern_crate(
988 self.def_collector.db,
989 krate,
964 &self.item_tree, 990 &self.item_tree,
965 InFile::new(self.file_id, import_id), 991 InFile::new(self.file_id, import_id),
966 ), 992 ),
@@ -975,7 +1001,11 @@ impl ModCollector<'_, '_> {
975 1001
976 // "Macro 2.0" is not currently supported by rust-analyzer, but libcore uses it 1002 // "Macro 2.0" is not currently supported by rust-analyzer, but libcore uses it
977 // to define builtin macros, so we support at least that part. 1003 // to define builtin macros, so we support at least that part.
978 let attrs = self.item_tree.attrs(ModItem::from(id).into()); 1004 let attrs = self.item_tree.attrs(
1005 self.def_collector.db,
1006 krate,
1007 ModItem::from(id).into(),
1008 );
979 if attrs.by_key("rustc_builtin_macro").exists() { 1009 if attrs.by_key("rustc_builtin_macro").exists() {
980 let krate = self.def_collector.def_map.krate; 1010 let krate = self.def_collector.def_map.krate;
981 let macro_id = find_builtin_macro(&mac.name, krate, ast_id) 1011 let macro_id = find_builtin_macro(&mac.name, krate, ast_id)
@@ -1012,7 +1042,7 @@ impl ModCollector<'_, '_> {
1012 ModItem::Function(id) => { 1042 ModItem::Function(id) => {
1013 let func = &self.item_tree[id]; 1043 let func = &self.item_tree[id];
1014 1044
1015 self.collect_proc_macro_def(&func.name, attrs); 1045 self.collect_proc_macro_def(&func.name, &attrs);
1016 1046
1017 def = Some(DefData { 1047 def = Some(DefData {
1018 id: FunctionLoc { 1048 id: FunctionLoc {
@@ -1032,7 +1062,7 @@ impl ModCollector<'_, '_> {
1032 // FIXME: check attrs to see if this is an attribute macro invocation; 1062 // FIXME: check attrs to see if this is an attribute macro invocation;
1033 // in which case we don't add the invocation, just a single attribute 1063 // in which case we don't add the invocation, just a single attribute
1034 // macro invocation 1064 // macro invocation
1035 self.collect_derives(attrs, it.ast_id.upcast()); 1065 self.collect_derives(&attrs, it.ast_id.upcast());
1036 1066
1037 def = Some(DefData { 1067 def = Some(DefData {
1038 id: StructLoc { container, id: ItemTreeId::new(self.file_id, id) } 1068 id: StructLoc { container, id: ItemTreeId::new(self.file_id, id) }
@@ -1049,7 +1079,7 @@ impl ModCollector<'_, '_> {
1049 // FIXME: check attrs to see if this is an attribute macro invocation; 1079 // FIXME: check attrs to see if this is an attribute macro invocation;
1050 // in which case we don't add the invocation, just a single attribute 1080 // in which case we don't add the invocation, just a single attribute
1051 // macro invocation 1081 // macro invocation
1052 self.collect_derives(attrs, it.ast_id.upcast()); 1082 self.collect_derives(&attrs, it.ast_id.upcast());
1053 1083
1054 def = Some(DefData { 1084 def = Some(DefData {
1055 id: UnionLoc { container, id: ItemTreeId::new(self.file_id, id) } 1085 id: UnionLoc { container, id: ItemTreeId::new(self.file_id, id) }
@@ -1066,7 +1096,7 @@ impl ModCollector<'_, '_> {
1066 // FIXME: check attrs to see if this is an attribute macro invocation; 1096 // FIXME: check attrs to see if this is an attribute macro invocation;
1067 // in which case we don't add the invocation, just a single attribute 1097 // in which case we don't add the invocation, just a single attribute
1068 // macro invocation 1098 // macro invocation
1069 self.collect_derives(attrs, it.ast_id.upcast()); 1099 self.collect_derives(&attrs, it.ast_id.upcast());
1070 1100
1071 def = Some(DefData { 1101 def = Some(DefData {
1072 id: EnumLoc { container, id: ItemTreeId::new(self.file_id, id) } 1102 id: EnumLoc { container, id: ItemTreeId::new(self.file_id, id) }
@@ -1259,20 +1289,20 @@ impl ModCollector<'_, '_> {
1259 } 1289 }
1260 1290
1261 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>) {
1262 for derive_subtree in attrs.by_key("derive").tt_values() { 1292 for derive in attrs.by_key("derive").attrs() {
1263 // for #[derive(Copy, Clone)], `derive_subtree` is the `(Copy, Clone)` subtree 1293 match derive.parse_derive() {
1264 for tt in &derive_subtree.token_trees { 1294 Some(derive_macros) => {
1265 let ident = match &tt { 1295 for path in derive_macros {
1266 tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => ident, 1296 let ast_id = AstIdWithPath::new(self.file_id, ast_id, path);
1267 tt::TokenTree::Leaf(tt::Leaf::Punct(_)) => continue, // , is ok 1297 self.def_collector
1268 _ => continue, // anything else would be an error (which we currently ignore) 1298 .unexpanded_attribute_macros
1269 }; 1299 .push(DeriveDirective { module_id: self.module_id, ast_id });
1270 let path = ModPath::from_tt_ident(ident); 1300 }
1271 1301 }
1272 let ast_id = AstIdWithPath::new(self.file_id, ast_id, path); 1302 None => {
1273 self.def_collector 1303 // FIXME: diagnose
1274 .unexpanded_attribute_macros 1304 log::debug!("malformed derive: {:?}", derive);
1275 .push(DeriveDirective { module_id: self.module_id, ast_id }); 1305 }
1276 } 1306 }
1277 } 1307 }
1278 } 1308 }
@@ -1303,8 +1333,9 @@ impl ModCollector<'_, '_> {
1303 } 1333 }
1304 1334
1305 fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) { 1335 fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) {
1336 let krate = self.def_collector.def_map.krate;
1306 let mac = &self.item_tree[id]; 1337 let mac = &self.item_tree[id];
1307 let attrs = self.item_tree.attrs(ModItem::from(id).into()); 1338 let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
1308 let ast_id = InFile::new(self.file_id, mac.ast_id.upcast()); 1339 let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
1309 1340
1310 let export_attr = attrs.by_key("macro_export"); 1341 let export_attr = attrs.by_key("macro_export");