aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/per_ns.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/per_ns.rs')
-rw-r--r--crates/hir_def/src/per_ns.rs95
1 files changed, 95 insertions, 0 deletions
diff --git a/crates/hir_def/src/per_ns.rs b/crates/hir_def/src/per_ns.rs
new file mode 100644
index 000000000..74665c588
--- /dev/null
+++ b/crates/hir_def/src/per_ns.rs
@@ -0,0 +1,95 @@
1//! In rust, it is possible to have a value, a type and a macro with the same
2//! name without conflicts.
3//!
4//! `PerNs` (per namespace) captures this.
5
6use hir_expand::MacroDefId;
7
8use crate::{item_scope::ItemInNs, visibility::Visibility, ModuleDefId};
9
10#[derive(Debug, Copy, Clone, PartialEq, Eq)]
11pub struct PerNs {
12 pub types: Option<(ModuleDefId, Visibility)>,
13 pub values: Option<(ModuleDefId, Visibility)>,
14 pub macros: Option<(MacroDefId, Visibility)>,
15}
16
17impl Default for PerNs {
18 fn default() -> Self {
19 PerNs { types: None, values: None, macros: None }
20 }
21}
22
23impl PerNs {
24 pub fn none() -> PerNs {
25 PerNs { types: None, values: None, macros: None }
26 }
27
28 pub fn values(t: ModuleDefId, v: Visibility) -> PerNs {
29 PerNs { types: None, values: Some((t, v)), macros: None }
30 }
31
32 pub fn types(t: ModuleDefId, v: Visibility) -> PerNs {
33 PerNs { types: Some((t, v)), values: None, macros: None }
34 }
35
36 pub fn both(types: ModuleDefId, values: ModuleDefId, v: Visibility) -> PerNs {
37 PerNs { types: Some((types, v)), values: Some((values, v)), macros: None }
38 }
39
40 pub fn macros(macro_: MacroDefId, v: Visibility) -> PerNs {
41 PerNs { types: None, values: None, macros: Some((macro_, v)) }
42 }
43
44 pub fn is_none(&self) -> bool {
45 self.types.is_none() && self.values.is_none() && self.macros.is_none()
46 }
47
48 pub fn take_types(self) -> Option<ModuleDefId> {
49 self.types.map(|it| it.0)
50 }
51
52 pub fn take_types_vis(self) -> Option<(ModuleDefId, Visibility)> {
53 self.types
54 }
55
56 pub fn take_values(self) -> Option<ModuleDefId> {
57 self.values.map(|it| it.0)
58 }
59
60 pub fn take_macros(self) -> Option<MacroDefId> {
61 self.macros.map(|it| it.0)
62 }
63
64 pub fn filter_visibility(self, mut f: impl FnMut(Visibility) -> bool) -> PerNs {
65 PerNs {
66 types: self.types.filter(|(_, v)| f(*v)),
67 values: self.values.filter(|(_, v)| f(*v)),
68 macros: self.macros.filter(|(_, v)| f(*v)),
69 }
70 }
71
72 pub fn with_visibility(self, vis: Visibility) -> PerNs {
73 PerNs {
74 types: self.types.map(|(it, _)| (it, vis)),
75 values: self.values.map(|(it, _)| (it, vis)),
76 macros: self.macros.map(|(it, _)| (it, vis)),
77 }
78 }
79
80 pub fn or(self, other: PerNs) -> PerNs {
81 PerNs {
82 types: self.types.or(other.types),
83 values: self.values.or(other.values),
84 macros: self.macros.or(other.macros),
85 }
86 }
87
88 pub fn iter_items(self) -> impl Iterator<Item = ItemInNs> {
89 self.types
90 .map(|it| ItemInNs::Types(it.0))
91 .into_iter()
92 .chain(self.values.map(|it| ItemInNs::Values(it.0)).into_iter())
93 .chain(self.macros.map(|it| ItemInNs::Macros(it.0)).into_iter())
94 }
95}