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#[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#[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}