aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r--crates/ra_hir_def/src/body/lower.rs6
-rw-r--r--crates/ra_hir_def/src/item_scope.rs51
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs36
-rw-r--r--crates/ra_hir_def/src/per_ns.rs20
4 files changed, 73 insertions, 40 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index 3ced648e5..d749c828d 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -26,7 +26,7 @@ use crate::{
26 dummy_expr_id, ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, 26 dummy_expr_id, ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal,
27 LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, 27 LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
28 }, 28 },
29 item_scope::BuiltinShadowMode, 29 item_scope::{BuiltinShadowMode, ImportType},
30 item_tree::{FileItemTreeId, ItemTree, ItemTreeNode}, 30 item_tree::{FileItemTreeId, ItemTree, ItemTreeNode},
31 path::{GenericArgs, Path}, 31 path::{GenericArgs, Path},
32 type_ref::{Mutability, Rawness, TypeRef}, 32 type_ref::{Mutability, Rawness, TypeRef},
@@ -81,6 +81,7 @@ pub(super) fn lower(
81 map 81 map
82 }, 82 },
83 expander, 83 expander,
84 import_types: FxHashMap::default(),
84 } 85 }
85 .collect(params, body) 86 .collect(params, body)
86} 87}
@@ -93,6 +94,7 @@ struct ExprCollector<'a> {
93 source_map: BodySourceMap, 94 source_map: BodySourceMap,
94 95
95 item_trees: FxHashMap<HirFileId, Arc<ItemTree>>, 96 item_trees: FxHashMap<HirFileId, Arc<ItemTree>>,
97 import_types: FxHashMap<Name, ImportType>,
96} 98}
97 99
98impl ExprCollector<'_> { 100impl ExprCollector<'_> {
@@ -711,8 +713,10 @@ impl ExprCollector<'_> {
711 _ => true, 713 _ => true,
712 }; 714 };
713 self.body.item_scope.push_res( 715 self.body.item_scope.push_res(
716 &mut self.import_types,
714 name.as_name(), 717 name.as_name(),
715 crate::per_ns::PerNs::from_def(def, vis, has_constructor), 718 crate::per_ns::PerNs::from_def(def, vis, has_constructor),
719 ImportType::Named,
716 ); 720 );
717 } 721 }
718 } 722 }
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)]
16pub(crate) enum ImportType {
17 Glob,
18 Named,
19}
20
21impl 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)]
16pub struct ItemScope { 38pub 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 }
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 93f58e2c7..f7b99e0be 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -20,6 +20,7 @@ use test_utils::mark;
20use crate::{ 20use crate::{
21 attr::Attrs, 21 attr::Attrs,
22 db::DefDatabase, 22 db::DefDatabase,
23 item_scope::ImportType,
23 item_tree::{ 24 item_tree::{
24 self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, Mod, ModItem, ModKind, StructDefKind, 25 self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, Mod, ModItem, ModKind, StructDefKind,
25 }, 26 },
@@ -80,6 +81,7 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: CrateDefMap) -> Cr
80 mod_dirs: FxHashMap::default(), 81 mod_dirs: FxHashMap::default(),
81 cfg_options, 82 cfg_options,
82 proc_macros, 83 proc_macros,
84 import_types: FxHashMap::default(),
83 }; 85 };
84 collector.collect(); 86 collector.collect();
85 collector.finish() 87 collector.finish()
@@ -186,6 +188,7 @@ struct DefCollector<'a> {
186 mod_dirs: FxHashMap<LocalModuleId, ModDir>, 188 mod_dirs: FxHashMap<LocalModuleId, ModDir>,
187 cfg_options: &'a CfgOptions, 189 cfg_options: &'a CfgOptions,
188 proc_macros: Vec<(Name, ProcMacroExpander)>, 190 proc_macros: Vec<(Name, ProcMacroExpander)>,
191 import_types: FxHashMap<Name, ImportType>,
189} 192}
190 193
191impl DefCollector<'_> { 194impl DefCollector<'_> {
@@ -305,7 +308,7 @@ impl DefCollector<'_> {
305 self.def_map.root, 308 self.def_map.root,
306 &[(name, PerNs::macros(macro_, Visibility::Public))], 309 &[(name, PerNs::macros(macro_, Visibility::Public))],
307 Visibility::Public, 310 Visibility::Public,
308 false, 311 ImportType::Named,
309 ); 312 );
310 } 313 }
311 } 314 }
@@ -331,7 +334,7 @@ impl DefCollector<'_> {
331 self.def_map.root, 334 self.def_map.root,
332 &[(name, PerNs::macros(macro_, Visibility::Public))], 335 &[(name, PerNs::macros(macro_, Visibility::Public))],
333 Visibility::Public, 336 Visibility::Public,
334 false, 337 ImportType::Named,
335 ); 338 );
336 } 339 }
337 340
@@ -478,7 +481,7 @@ impl DefCollector<'_> {
478 .filter(|(_, res)| !res.is_none()) 481 .filter(|(_, res)| !res.is_none())
479 .collect::<Vec<_>>(); 482 .collect::<Vec<_>>();
480 483
481 self.update(module_id, &items, vis, true); 484 self.update(module_id, &items, vis, ImportType::Glob);
482 } else { 485 } else {
483 // glob import from same crate => we do an initial 486 // glob import from same crate => we do an initial
484 // import, and then need to propagate any further 487 // import, and then need to propagate any further
@@ -500,7 +503,7 @@ impl DefCollector<'_> {
500 .filter(|(_, res)| !res.is_none()) 503 .filter(|(_, res)| !res.is_none())
501 .collect::<Vec<_>>(); 504 .collect::<Vec<_>>();
502 505
503 self.update(module_id, &items, vis, true); 506 self.update(module_id, &items, vis, ImportType::Glob);
504 // record the glob import in case we add further items 507 // record the glob import in case we add further items
505 let glob = self.glob_imports.entry(m.local_id).or_default(); 508 let glob = self.glob_imports.entry(m.local_id).or_default();
506 if !glob.iter().any(|(mid, _)| *mid == module_id) { 509 if !glob.iter().any(|(mid, _)| *mid == module_id) {
@@ -530,7 +533,7 @@ impl DefCollector<'_> {
530 (name, res) 533 (name, res)
531 }) 534 })
532 .collect::<Vec<_>>(); 535 .collect::<Vec<_>>();
533 self.update(module_id, &resolutions, vis, true); 536 self.update(module_id, &resolutions, vis, ImportType::Glob);
534 } 537 }
535 Some(d) => { 538 Some(d) => {
536 log::debug!("glob import {:?} from non-module/enum {:?}", import, d); 539 log::debug!("glob import {:?} from non-module/enum {:?}", import, d);
@@ -556,7 +559,7 @@ impl DefCollector<'_> {
556 } 559 }
557 } 560 }
558 561
559 self.update(module_id, &[(name, def)], vis, false); 562 self.update(module_id, &[(name, def)], vis, ImportType::Named);
560 } 563 }
561 None => mark::hit!(bogus_paths), 564 None => mark::hit!(bogus_paths),
562 } 565 }
@@ -568,9 +571,9 @@ impl DefCollector<'_> {
568 module_id: LocalModuleId, 571 module_id: LocalModuleId,
569 resolutions: &[(Name, PerNs)], 572 resolutions: &[(Name, PerNs)],
570 vis: Visibility, 573 vis: Visibility,
571 is_from_glob: bool, 574 import_type: ImportType,
572 ) { 575 ) {
573 self.update_recursive(module_id, resolutions, vis, is_from_glob, 0) 576 self.update_recursive(module_id, resolutions, vis, import_type, 0)
574 } 577 }
575 578
576 fn update_recursive( 579 fn update_recursive(
@@ -582,7 +585,7 @@ impl DefCollector<'_> {
582 vis: Visibility, 585 vis: Visibility,
583 // All resolutions are imported with this glob status; the glob status 586 // All resolutions are imported with this glob status; the glob status
584 // in the `PerNs` values are ignored and overwritten 587 // in the `PerNs` values are ignored and overwritten
585 is_from_glob: bool, 588 import_type: ImportType,
586 depth: usize, 589 depth: usize,
587 ) { 590 ) {
588 if depth > 100 { 591 if depth > 100 {
@@ -592,8 +595,12 @@ impl DefCollector<'_> {
592 let scope = &mut self.def_map.modules[module_id].scope; 595 let scope = &mut self.def_map.modules[module_id].scope;
593 let mut changed = false; 596 let mut changed = false;
594 for (name, res) in resolutions { 597 for (name, res) in resolutions {
595 changed |= 598 changed |= scope.push_res(
596 scope.push_res(name.clone(), res.with_visibility(vis).from_glob(is_from_glob)); 599 &mut self.import_types,
600 name.clone(),
601 res.with_visibility(vis),
602 import_type,
603 );
597 } 604 }
598 605
599 if !changed { 606 if !changed {
@@ -616,7 +623,7 @@ impl DefCollector<'_> {
616 glob_importing_module, 623 glob_importing_module,
617 resolutions, 624 resolutions,
618 glob_import_vis, 625 glob_import_vis,
619 true, 626 ImportType::Glob,
620 depth + 1, 627 depth + 1,
621 ); 628 );
622 } 629 }
@@ -940,7 +947,7 @@ impl ModCollector<'_, '_> {
940 self.module_id, 947 self.module_id,
941 &[(name.clone(), PerNs::from_def(id, vis, has_constructor))], 948 &[(name.clone(), PerNs::from_def(id, vis, has_constructor))],
942 vis, 949 vis,
943 false, 950 ImportType::Named,
944 ) 951 )
945 } 952 }
946 } 953 }
@@ -1047,7 +1054,7 @@ impl ModCollector<'_, '_> {
1047 self.module_id, 1054 self.module_id,
1048 &[(name, PerNs::from_def(def, vis, false))], 1055 &[(name, PerNs::from_def(def, vis, false))],
1049 vis, 1056 vis,
1050 false, 1057 ImportType::Named,
1051 ); 1058 );
1052 res 1059 res
1053 } 1060 }
@@ -1177,6 +1184,7 @@ mod tests {
1177 mod_dirs: FxHashMap::default(), 1184 mod_dirs: FxHashMap::default(),
1178 cfg_options: &CfgOptions::default(), 1185 cfg_options: &CfgOptions::default(),
1179 proc_macros: Default::default(), 1186 proc_macros: Default::default(),
1187 import_types: FxHashMap::default(),
1180 }; 1188 };
1181 collector.collect(); 1189 collector.collect();
1182 collector.def_map 1190 collector.def_map
diff --git a/crates/ra_hir_def/src/per_ns.rs b/crates/ra_hir_def/src/per_ns.rs
index e5cbca71d..74665c588 100644
--- a/crates/ra_hir_def/src/per_ns.rs
+++ b/crates/ra_hir_def/src/per_ns.rs
@@ -9,7 +9,6 @@ use crate::{item_scope::ItemInNs, visibility::Visibility, ModuleDefId};
9 9
10#[derive(Debug, Copy, Clone, PartialEq, Eq)] 10#[derive(Debug, Copy, Clone, PartialEq, Eq)]
11pub struct PerNs { 11pub struct PerNs {
12 pub from_glob: bool,
13 pub types: Option<(ModuleDefId, Visibility)>, 12 pub types: Option<(ModuleDefId, Visibility)>,
14 pub values: Option<(ModuleDefId, Visibility)>, 13 pub values: Option<(ModuleDefId, Visibility)>,
15 pub macros: Option<(MacroDefId, Visibility)>, 14 pub macros: Option<(MacroDefId, Visibility)>,
@@ -17,29 +16,29 @@ pub struct PerNs {
17 16
18impl Default for PerNs { 17impl Default for PerNs {
19 fn default() -> Self { 18 fn default() -> Self {
20 PerNs { from_glob: false, types: None, values: None, macros: None } 19 PerNs { types: None, values: None, macros: None }
21 } 20 }
22} 21}
23 22
24impl PerNs { 23impl PerNs {
25 pub fn none() -> PerNs { 24 pub fn none() -> PerNs {
26 PerNs { from_glob: false, types: None, values: None, macros: None } 25 PerNs { types: None, values: None, macros: None }
27 } 26 }
28 27
29 pub fn values(t: ModuleDefId, v: Visibility) -> PerNs { 28 pub fn values(t: ModuleDefId, v: Visibility) -> PerNs {
30 PerNs { from_glob: false, types: None, values: Some((t, v)), macros: None } 29 PerNs { types: None, values: Some((t, v)), macros: None }
31 } 30 }
32 31
33 pub fn types(t: ModuleDefId, v: Visibility) -> PerNs { 32 pub fn types(t: ModuleDefId, v: Visibility) -> PerNs {
34 PerNs { from_glob: false, types: Some((t, v)), values: None, macros: None } 33 PerNs { types: Some((t, v)), values: None, macros: None }
35 } 34 }
36 35
37 pub fn both(types: ModuleDefId, values: ModuleDefId, v: Visibility) -> PerNs { 36 pub fn both(types: ModuleDefId, values: ModuleDefId, v: Visibility) -> PerNs {
38 PerNs { from_glob: false, types: Some((types, v)), values: Some((values, v)), macros: None } 37 PerNs { types: Some((types, v)), values: Some((values, v)), macros: None }
39 } 38 }
40 39
41 pub fn macros(macro_: MacroDefId, v: Visibility) -> PerNs { 40 pub fn macros(macro_: MacroDefId, v: Visibility) -> PerNs {
42 PerNs { from_glob: false, types: None, values: None, macros: Some((macro_, v)) } 41 PerNs { types: None, values: None, macros: Some((macro_, v)) }
43 } 42 }
44 43
45 pub fn is_none(&self) -> bool { 44 pub fn is_none(&self) -> bool {
@@ -64,7 +63,6 @@ impl PerNs {
64 63
65 pub fn filter_visibility(self, mut f: impl FnMut(Visibility) -> bool) -> PerNs { 64 pub fn filter_visibility(self, mut f: impl FnMut(Visibility) -> bool) -> PerNs {
66 PerNs { 65 PerNs {
67 from_glob: self.from_glob,
68 types: self.types.filter(|(_, v)| f(*v)), 66 types: self.types.filter(|(_, v)| f(*v)),
69 values: self.values.filter(|(_, v)| f(*v)), 67 values: self.values.filter(|(_, v)| f(*v)),
70 macros: self.macros.filter(|(_, v)| f(*v)), 68 macros: self.macros.filter(|(_, v)| f(*v)),
@@ -73,7 +71,6 @@ impl PerNs {
73 71
74 pub fn with_visibility(self, vis: Visibility) -> PerNs { 72 pub fn with_visibility(self, vis: Visibility) -> PerNs {
75 PerNs { 73 PerNs {
76 from_glob: self.from_glob,
77 types: self.types.map(|(it, _)| (it, vis)), 74 types: self.types.map(|(it, _)| (it, vis)),
78 values: self.values.map(|(it, _)| (it, vis)), 75 values: self.values.map(|(it, _)| (it, vis)),
79 macros: self.macros.map(|(it, _)| (it, vis)), 76 macros: self.macros.map(|(it, _)| (it, vis)),
@@ -82,7 +79,6 @@ impl PerNs {
82 79
83 pub fn or(self, other: PerNs) -> PerNs { 80 pub fn or(self, other: PerNs) -> PerNs {
84 PerNs { 81 PerNs {
85 from_glob: self.from_glob,
86 types: self.types.or(other.types), 82 types: self.types.or(other.types),
87 values: self.values.or(other.values), 83 values: self.values.or(other.values),
88 macros: self.macros.or(other.macros), 84 macros: self.macros.or(other.macros),
@@ -96,8 +92,4 @@ impl PerNs {
96 .chain(self.values.map(|it| ItemInNs::Values(it.0)).into_iter()) 92 .chain(self.values.map(|it| ItemInNs::Values(it.0)).into_iter())
97 .chain(self.macros.map(|it| ItemInNs::Macros(it.0)).into_iter()) 93 .chain(self.macros.map(|it| ItemInNs::Macros(it.0)).into_iter())
98 } 94 }
99
100 pub fn from_glob(self, from_glob: bool) -> PerNs {
101 PerNs { from_glob, ..self }
102 }
103} 95}