1 //! In rust, it is possible to have a value, a type and a macro with the same
2 //! name without conflicts.
4 //! `PerNs` (per namespace) captures this.
6 use hir_expand::MacroDefId;
8 use crate::{item_scope::ItemInNs, visibility::Visibility, ModuleDefId};
10 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
12 pub types: Option<(ModuleDefId, Visibility)>,
13 pub values: Option<(ModuleDefId, Visibility)>,
14 pub macros: Option<(MacroDefId, Visibility)>,
17 impl Default for PerNs {
18 fn default() -> Self {
19 PerNs { types: None, values: None, macros: None }
24 pub fn none() -> PerNs {
25 PerNs { types: None, values: None, macros: None }
28 pub fn values(t: ModuleDefId, v: Visibility) -> PerNs {
29 PerNs { types: None, values: Some((t, v)), macros: None }
32 pub fn types(t: ModuleDefId, v: Visibility) -> PerNs {
33 PerNs { types: Some((t, v)), values: None, macros: None }
36 pub fn both(types: ModuleDefId, values: ModuleDefId, v: Visibility) -> PerNs {
37 PerNs { types: Some((types, v)), values: Some((values, v)), macros: None }
40 pub fn macros(macro_: MacroDefId, v: Visibility) -> PerNs {
41 PerNs { types: None, values: None, macros: Some((macro_, v)) }
44 pub fn is_none(&self) -> bool {
45 self.types.is_none() && self.values.is_none() && self.macros.is_none()
48 pub fn take_types(self) -> Option<ModuleDefId> {
49 self.types.map(|it| it.0)
52 pub fn take_types_vis(self) -> Option<(ModuleDefId, Visibility)> {
56 pub fn take_values(self) -> Option<ModuleDefId> {
57 self.values.map(|it| it.0)
60 pub fn take_macros(self) -> Option<MacroDefId> {
61 self.macros.map(|it| it.0)
64 pub fn filter_visibility(self, mut f: impl FnMut(Visibility) -> bool) -> PerNs {
65 let _p = profile::span("PerNs::filter_visibility");
67 types: self.types.filter(|(_, v)| f(*v)),
68 values: self.values.filter(|(_, v)| f(*v)),
69 macros: self.macros.filter(|(_, v)| f(*v)),
73 pub fn with_visibility(self, vis: Visibility) -> 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)),
81 pub fn or(self, other: PerNs) -> PerNs {
83 types: self.types.or(other.types),
84 values: self.values.or(other.values),
85 macros: self.macros.or(other.macros),
89 pub fn iter_items(self) -> impl Iterator<Item = ItemInNs> {
90 let _p = profile::span("PerNs::iter_items");
92 .map(|it| ItemInNs::Types(it.0))
94 .chain(self.values.map(|it| ItemInNs::Values(it.0)).into_iter())
95 .chain(self.macros.map(|it| ItemInNs::Macros(it.0)).into_iter())