]> git.lizzy.rs Git - rust.git/blob - crates/hir_def/src/per_ns.rs
Merge #10352
[rust.git] / crates / hir_def / src / per_ns.rs
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
6 use hir_expand::MacroDefId;
7
8 use crate::{item_scope::ItemInNs, visibility::Visibility, ModuleDefId};
9
10 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
11 pub struct PerNs {
12     pub types: Option<(ModuleDefId, Visibility)>,
13     pub values: Option<(ModuleDefId, Visibility)>,
14     pub macros: Option<(MacroDefId, Visibility)>,
15 }
16
17 impl Default for PerNs {
18     fn default() -> Self {
19         PerNs { types: None, values: None, macros: None }
20     }
21 }
22
23 impl 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         let _p = profile::span("PerNs::filter_visibility");
66         PerNs {
67             types: self.types.filter(|(_, v)| f(*v)),
68             values: self.values.filter(|(_, v)| f(*v)),
69             macros: self.macros.filter(|(_, v)| f(*v)),
70         }
71     }
72
73     pub fn with_visibility(self, vis: Visibility) -> PerNs {
74         PerNs {
75             types: self.types.map(|(it, _)| (it, vis)),
76             values: self.values.map(|(it, _)| (it, vis)),
77             macros: self.macros.map(|(it, _)| (it, vis)),
78         }
79     }
80
81     pub fn or(self, other: PerNs) -> PerNs {
82         PerNs {
83             types: self.types.or(other.types),
84             values: self.values.or(other.values),
85             macros: self.macros.or(other.macros),
86         }
87     }
88
89     pub fn iter_items(self) -> impl Iterator<Item = ItemInNs> {
90         let _p = profile::span("PerNs::iter_items");
91         self.types
92             .map(|it| ItemInNs::Types(it.0))
93             .into_iter()
94             .chain(self.values.map(|it| ItemInNs::Values(it.0)).into_iter())
95             .chain(self.macros.map(|it| ItemInNs::Macros(it.0)).into_iter())
96     }
97 }