diff options
Diffstat (limited to 'crates/hir_def/src/nameres')
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 31 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/tests/diagnostics.rs | 18 |
2 files changed, 44 insertions, 5 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index b114a6fe4..55228e480 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 | ||
138 | impl Import { | 138 | impl 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 | ), |
diff --git a/crates/hir_def/src/nameres/tests/diagnostics.rs b/crates/hir_def/src/nameres/tests/diagnostics.rs index 1a7b98831..58d69d3c6 100644 --- a/crates/hir_def/src/nameres/tests/diagnostics.rs +++ b/crates/hir_def/src/nameres/tests/diagnostics.rs | |||
@@ -1,4 +1,5 @@ | |||
1 | use base_db::fixture::WithFixture; | 1 | use base_db::fixture::WithFixture; |
2 | use test_utils::mark; | ||
2 | 3 | ||
3 | use crate::test_db::TestDB; | 4 | use crate::test_db::TestDB; |
4 | 5 | ||
@@ -119,3 +120,20 @@ fn inactive_item() { | |||
119 | "#, | 120 | "#, |
120 | ); | 121 | ); |
121 | } | 122 | } |
123 | |||
124 | /// Tests that `cfg` attributes behind `cfg_attr` is handled properly. | ||
125 | #[test] | ||
126 | fn inactive_via_cfg_attr() { | ||
127 | mark::check!(cfg_attr_active); | ||
128 | check_diagnostics( | ||
129 | r#" | ||
130 | //- /lib.rs | ||
131 | #[cfg_attr(not(never), cfg(no))] fn f() {} | ||
132 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ code is inactive due to #[cfg] directives: no is disabled | ||
133 | |||
134 | #[cfg_attr(not(never), cfg(not(no)))] fn f() {} | ||
135 | |||
136 | #[cfg_attr(never, cfg(no))] fn g() {} | ||
137 | "#, | ||
138 | ); | ||
139 | } | ||