mun_hir/
ids.rs

1use crate::{
2    item_tree::{Function, ItemTreeId, ItemTreeNode, Struct, TypeAlias},
3    module_tree::LocalModuleId,
4    primitive_type::PrimitiveType,
5    DefDatabase, PackageId,
6};
7use std::hash::{Hash, Hasher};
8
9#[derive(Debug)]
10pub struct ItemLoc<N: ItemTreeNode> {
11    pub id: ItemTreeId<N>,
12}
13
14impl<N: ItemTreeNode> PartialEq for ItemLoc<N> {
15    fn eq(&self, other: &Self) -> bool {
16        self.id == other.id
17    }
18}
19impl<N: ItemTreeNode> Eq for ItemLoc<N> {}
20
21impl<N: ItemTreeNode> Hash for ItemLoc<N> {
22    fn hash<H: Hasher>(&self, hasher: &mut H) {
23        self.id.hash(hasher);
24    }
25}
26
27impl<N: ItemTreeNode> Clone for ItemLoc<N> {
28    fn clone(&self) -> ItemLoc<N> {
29        ItemLoc { id: self.id }
30    }
31}
32impl<N: ItemTreeNode> Copy for ItemLoc<N> {}
33
34#[derive(Debug)]
35pub struct AssocItemLoc<N: ItemTreeNode> {
36    pub module: ModuleId,
37    pub id: ItemTreeId<N>,
38}
39
40impl<N: ItemTreeNode> Clone for AssocItemLoc<N> {
41    fn clone(&self) -> Self {
42        Self {
43            module: self.module,
44            id: self.id,
45        }
46    }
47}
48
49impl<N: ItemTreeNode> Copy for AssocItemLoc<N> {}
50
51impl<N: ItemTreeNode> PartialEq for AssocItemLoc<N> {
52    fn eq(&self, other: &Self) -> bool {
53        self.module == other.module && self.id == other.id
54    }
55}
56
57impl<N: ItemTreeNode> Eq for AssocItemLoc<N> {}
58
59impl<N: ItemTreeNode> Hash for AssocItemLoc<N> {
60    fn hash<H: Hasher>(&self, state: &mut H) {
61        self.module.hash(state);
62        self.id.hash(state);
63    }
64}
65
66macro_rules! impl_intern_key {
67    ($name:ident) => {
68        impl salsa::InternKey for $name {
69            fn from_intern_id(v: salsa::InternId) -> Self {
70                $name(v)
71            }
72            fn as_intern_id(&self) -> salsa::InternId {
73                self.0
74            }
75        }
76    };
77}
78
79macro_rules! impl_intern {
80    ($id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
81        impl_intern_key!($id);
82
83        impl Intern for $loc {
84            type ID = $id;
85            fn intern(self, db: &dyn DefDatabase) -> $id {
86                db.$intern(self)
87            }
88        }
89
90        impl Lookup for $id {
91            type Data = $loc;
92            fn lookup(&self, db: &dyn DefDatabase) -> $loc {
93                db.$lookup(*self)
94            }
95        }
96    };
97}
98
99/// Represents an id of a module inside a package.
100#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
101pub struct ModuleId {
102    pub package: PackageId,
103    pub local_id: LocalModuleId,
104}
105
106#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
107pub struct FunctionId(salsa::InternId);
108pub(crate) type FunctionLoc = AssocItemLoc<Function>;
109impl_intern!(
110    FunctionId,
111    FunctionLoc,
112    intern_function,
113    lookup_intern_function
114);
115
116#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
117pub struct StructId(salsa::InternId);
118pub(crate) type StructLoc = AssocItemLoc<Struct>;
119impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct);
120
121#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
122pub struct TypeAliasId(salsa::InternId);
123pub(crate) type TypeAliasLoc = AssocItemLoc<TypeAlias>;
124impl_intern!(
125    TypeAliasId,
126    TypeAliasLoc,
127    intern_type_alias,
128    lookup_intern_type_alias
129);
130
131pub trait Intern {
132    type ID;
133    fn intern(self, db: &dyn DefDatabase) -> Self::ID;
134}
135
136pub trait Lookup {
137    type Data;
138    fn lookup(&self, db: &dyn DefDatabase) -> Self::Data;
139}
140
141#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
142pub enum ItemDefinitionId {
143    ModuleId(ModuleId),
144    FunctionId(FunctionId),
145    StructId(StructId),
146    TypeAliasId(TypeAliasId),
147    PrimitiveType(PrimitiveType),
148}
149
150impl From<ModuleId> for ItemDefinitionId {
151    fn from(id: ModuleId) -> Self {
152        ItemDefinitionId::ModuleId(id)
153    }
154}
155impl From<FunctionId> for ItemDefinitionId {
156    fn from(id: FunctionId) -> Self {
157        ItemDefinitionId::FunctionId(id)
158    }
159}
160impl From<StructId> for ItemDefinitionId {
161    fn from(id: StructId) -> Self {
162        ItemDefinitionId::StructId(id)
163    }
164}
165impl From<TypeAliasId> for ItemDefinitionId {
166    fn from(id: TypeAliasId) -> Self {
167        ItemDefinitionId::TypeAliasId(id)
168    }
169}
170impl From<PrimitiveType> for ItemDefinitionId {
171    fn from(id: PrimitiveType) -> Self {
172        ItemDefinitionId::PrimitiveType(id)
173    }
174}
175
176/// Definitions which have a body
177#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
178pub enum DefWithBodyId {
179    FunctionId(FunctionId),
180}
181
182impl From<FunctionId> for DefWithBodyId {
183    fn from(id: FunctionId) -> Self {
184        DefWithBodyId::FunctionId(id)
185    }
186}