diff options
Diffstat (limited to 'crates/ra_hir_def/src/item_scope.rs')
-rw-r--r-- | crates/ra_hir_def/src/item_scope.rs | 51 |
1 files changed, 40 insertions, 11 deletions
diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 0184b6af9..511c08a8d 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs | |||
@@ -12,6 +12,28 @@ use crate::{ | |||
12 | Lookup, MacroDefId, ModuleDefId, TraitId, | 12 | Lookup, MacroDefId, ModuleDefId, TraitId, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | #[derive(Copy, Clone)] | ||
16 | pub(crate) enum ImportType { | ||
17 | Glob, | ||
18 | Named, | ||
19 | } | ||
20 | |||
21 | impl ImportType { | ||
22 | fn is_glob(&self) -> bool { | ||
23 | match self { | ||
24 | ImportType::Glob => true, | ||
25 | ImportType::Named => false, | ||
26 | } | ||
27 | } | ||
28 | |||
29 | fn is_named(&self) -> bool { | ||
30 | match self { | ||
31 | ImportType::Glob => false, | ||
32 | ImportType::Named => true, | ||
33 | } | ||
34 | } | ||
35 | } | ||
36 | |||
15 | #[derive(Debug, Default, PartialEq, Eq)] | 37 | #[derive(Debug, Default, PartialEq, Eq)] |
16 | pub struct ItemScope { | 38 | pub struct ItemScope { |
17 | visible: FxHashMap<Name, PerNs>, | 39 | visible: FxHashMap<Name, PerNs>, |
@@ -123,23 +145,30 @@ impl ItemScope { | |||
123 | self.legacy_macros.insert(name, mac); | 145 | self.legacy_macros.insert(name, mac); |
124 | } | 146 | } |
125 | 147 | ||
126 | pub(crate) fn push_res(&mut self, name: Name, def: PerNs) -> bool { | 148 | pub(crate) fn push_res( |
149 | &mut self, | ||
150 | existing_import_map: &mut FxHashMap<Name, ImportType>, | ||
151 | name: Name, | ||
152 | def: PerNs, | ||
153 | def_import_type: ImportType, | ||
154 | ) -> bool { | ||
127 | let mut changed = false; | 155 | let mut changed = false; |
128 | let existing = self.visible.entry(name).or_default(); | 156 | let existing = self.visible.entry(name.clone()).or_default(); |
157 | let existing_import_type = existing_import_map.entry(name).or_insert(def_import_type); | ||
129 | 158 | ||
130 | macro_rules! check_changed { | 159 | macro_rules! check_changed { |
131 | ($changed:ident, ($existing:ident/$def:ident).$field:ident) => { | 160 | ($changed:ident, ($existing:ident/$def:ident).$field:ident, $existing_import_type:ident, $def_import_type:ident) => { |
132 | match ($existing.$field, $def.$field) { | 161 | match ($existing.$field, $def.$field) { |
133 | (None, Some(_)) => { | 162 | (None, Some(_)) => { |
134 | $existing.from_glob = $def.from_glob; | 163 | *existing_import_type = $def_import_type; |
135 | $existing.$field = $def.$field; | 164 | $existing.$field = $def.$field; |
136 | $changed = true; | 165 | $changed = true; |
137 | } | 166 | } |
138 | // Only update if the new def came from a specific import and the existing | 167 | (Some(_), Some(_)) |
139 | // import came from a glob import. | 168 | if $existing_import_type.is_glob() && $def_import_type.is_named() => |
140 | (Some(_), Some(_)) if $existing.from_glob && !$def.from_glob => { | 169 | { |
141 | mark::hit!(import_shadowed); | 170 | mark::hit!(import_shadowed); |
142 | $existing.from_glob = $def.from_glob; | 171 | *$existing_import_type = $def_import_type; |
143 | $existing.$field = $def.$field; | 172 | $existing.$field = $def.$field; |
144 | $changed = true; | 173 | $changed = true; |
145 | } | 174 | } |
@@ -148,9 +177,9 @@ impl ItemScope { | |||
148 | }; | 177 | }; |
149 | } | 178 | } |
150 | 179 | ||
151 | check_changed!(changed, (existing / def).types); | 180 | check_changed!(changed, (existing / def).types, existing_import_type, def_import_type); |
152 | check_changed!(changed, (existing / def).values); | 181 | check_changed!(changed, (existing / def).values, existing_import_type, def_import_type); |
153 | check_changed!(changed, (existing / def).macros); | 182 | check_changed!(changed, (existing / def).macros, existing_import_type, def_import_type); |
154 | 183 | ||
155 | changed | 184 | changed |
156 | } | 185 | } |