sway_core/decl_engine/
id.rs1use crate::{
2 decl_engine::*,
3 engine_threading::*,
4 language::ty::{
5 TyDeclParsedType, TyEnumDecl, TyFunctionDecl, TyImplSelfOrTrait, TyStructDecl, TyTraitDecl,
6 TyTraitFn, TyTraitType, TyTypeAliasDecl,
7 },
8 type_system::*,
9};
10use serde::{Deserialize, Serialize};
11use std::{
12 collections::hash_map::DefaultHasher,
13 fmt,
14 hash::{Hash, Hasher},
15 marker::PhantomData,
16};
17use sway_types::{Named, Spanned};
18
19pub type DeclIdIndexType = usize;
20
21pub struct DeclId<T>(DeclIdIndexType, PhantomData<T>);
23
24impl<T> fmt::Debug for DeclId<T> {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 f.debug_tuple("DeclId").field(&self.0).finish()
27 }
28}
29
30#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug, Serialize, Deserialize)]
31pub struct DeclUniqueId(pub(crate) u64);
32
33impl<T> DeclId<T> {
34 pub(crate) fn inner(&self) -> DeclIdIndexType {
35 self.0
36 }
37
38 pub fn unique_id(&self) -> DeclUniqueId
39 where
40 T: 'static,
41 {
42 let mut hasher = DefaultHasher::default();
43 std::any::TypeId::of::<T>().hash(&mut hasher);
44 self.0.hash(&mut hasher);
45
46 DeclUniqueId(hasher.finish())
47 }
48}
49
50impl<T> Copy for DeclId<T> {}
51impl<T> Clone for DeclId<T> {
52 fn clone(&self) -> Self {
53 *self
54 }
55}
56
57impl<T> Eq for DeclId<T> {}
58impl<T> Hash for DeclId<T> {
59 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
60 self.0.hash(state)
61 }
62}
63impl<T> PartialEq for DeclId<T> {
64 fn eq(&self, other: &Self) -> bool {
65 self.0.eq(&other.0)
66 }
67}
68impl<T> PartialOrd for DeclId<T> {
69 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
70 Some(self.cmp(other))
71 }
72}
73impl<T> Ord for DeclId<T> {
74 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
75 self.0.cmp(&other.0)
76 }
77}
78
79impl<T> DeclId<T> {
80 pub(crate) fn new(id: usize) -> Self {
81 DeclId(id, PhantomData)
82 }
83
84 pub(crate) fn replace_id(&mut self, index: Self) {
85 self.0 = index.0;
86 }
87
88 pub(crate) fn dummy() -> Self {
89 Self(usize::MAX, PhantomData)
91 }
92}
93
94#[allow(clippy::from_over_into)]
95impl<T> Into<usize> for DeclId<T> {
96 fn into(self) -> usize {
97 self.0
98 }
99}
100
101impl<T> DebugWithEngines for DeclId<T>
102where
103 DeclEngine: DeclEngineIndex<T>,
104 T: Named + Spanned + DebugWithEngines,
105{
106 fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> fmt::Result {
107 let decl = engines.de().get(self);
108 DebugWithEngines::fmt(&decl, f, engines)
109 }
110}
111
112impl<T> EqWithEngines for DeclId<T>
113where
114 DeclEngine: DeclEngineIndex<T>,
115 T: Named + Spanned + PartialEqWithEngines + EqWithEngines,
116{
117}
118
119impl<T> PartialEqWithEngines for DeclId<T>
120where
121 DeclEngine: DeclEngineIndex<T>,
122 T: Named + Spanned + PartialEqWithEngines,
123{
124 fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
125 let decl_engine = ctx.engines().de();
126 let l_decl = decl_engine.get(self);
127 let r_decl = decl_engine.get(other);
128 l_decl.name() == r_decl.name() && l_decl.eq(&r_decl, ctx)
129 }
130}
131
132impl<T> HashWithEngines for DeclId<T>
133where
134 DeclEngine: DeclEngineIndex<T>,
135 T: Named + Spanned + HashWithEngines,
136{
137 fn hash<H: Hasher>(&self, state: &mut H, engines: &Engines) {
138 let decl_engine = engines.de();
139 let decl = decl_engine.get(self);
140 decl.name().hash(state);
141 decl.hash(state, engines);
142 }
143}
144
145impl SubstTypes for DeclId<TyFunctionDecl> {
146 fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges {
147 let decl_engine = ctx.engines.de();
148 let mut decl = (*decl_engine.get(self)).clone();
149 if decl.subst(ctx).has_changes() {
150 decl_engine.replace(*self, decl);
151 HasChanges::Yes
152 } else {
153 HasChanges::No
154 }
155 }
156}
157impl SubstTypes for DeclId<TyTraitDecl> {
158 fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges {
159 let decl_engine = ctx.engines.de();
160 let mut decl = (*decl_engine.get(self)).clone();
161 if decl.subst(ctx).has_changes() {
162 decl_engine.replace(*self, decl);
163 HasChanges::Yes
164 } else {
165 HasChanges::No
166 }
167 }
168}
169impl SubstTypes for DeclId<TyTraitFn> {
170 fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges {
171 let decl_engine = ctx.engines.de();
172 let mut decl = (*decl_engine.get(self)).clone();
173 if decl.subst(ctx).has_changes() {
174 decl_engine.replace(*self, decl);
175 HasChanges::Yes
176 } else {
177 HasChanges::No
178 }
179 }
180}
181impl SubstTypes for DeclId<TyImplSelfOrTrait> {
182 fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges {
183 let decl_engine = ctx.engines.de();
184 let mut decl = (*decl_engine.get(self)).clone();
185 if decl.subst(ctx).has_changes() {
186 decl_engine.replace(*self, decl);
187 HasChanges::Yes
188 } else {
189 HasChanges::No
190 }
191 }
192}
193impl SubstTypes for DeclId<TyStructDecl> {
194 fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges {
195 let decl_engine = ctx.engines.de();
196 let mut decl = (*decl_engine.get(self)).clone();
197 if decl.subst(ctx).has_changes() {
198 decl_engine.replace(*self, decl);
199 HasChanges::Yes
200 } else {
201 HasChanges::No
202 }
203 }
204}
205impl SubstTypes for DeclId<TyEnumDecl> {
206 fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges {
207 let decl_engine = ctx.engines.de();
208 let mut decl = (*decl_engine.get(self)).clone();
209 if decl.subst(ctx).has_changes() {
210 decl_engine.replace(*self, decl);
211 HasChanges::Yes
212 } else {
213 HasChanges::No
214 }
215 }
216}
217impl SubstTypes for DeclId<TyTypeAliasDecl> {
218 fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges {
219 let decl_engine = ctx.engines.de();
220 let mut decl = (*decl_engine.get(self)).clone();
221 if decl.subst(ctx).has_changes() {
222 decl_engine.replace(*self, decl);
223 HasChanges::Yes
224 } else {
225 HasChanges::No
226 }
227 }
228}
229
230impl SubstTypes for DeclId<TyTraitType> {
231 fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges {
232 let decl_engine = ctx.engines.de();
233 let mut decl = (*decl_engine.get(self)).clone();
234 if decl.subst(ctx).has_changes() {
235 decl_engine.replace(*self, decl);
236 HasChanges::Yes
237 } else {
238 HasChanges::No
239 }
240 }
241}
242
243impl<T> DeclId<T>
244where
245 DeclEngine: DeclEngineIndex<T> + DeclEngineInsert<T> + DeclEngineGetParsedDeclId<T>,
246 T: Named + Spanned + SubstTypes + Clone + TyDeclParsedType,
247{
248 pub(crate) fn subst_types_and_insert_new(
249 &self,
250 ctx: &SubstTypesContext,
251 ) -> Option<DeclRef<Self>> {
252 let decl_engine = ctx.engines.de();
253 let mut decl = (*decl_engine.get(self)).clone();
254 if decl.subst(ctx).has_changes() {
255 Some(decl_engine.insert(decl, decl_engine.get_parsed_decl_id(self).as_ref()))
256 } else {
257 None
258 }
259 }
260}
261
262impl<T> Serialize for DeclId<T> {
263 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
264 where
265 S: serde::Serializer,
266 {
267 self.0.serialize(serializer)
268 }
269}
270
271impl<'de, T> Deserialize<'de> for DeclId<T> {
272 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
273 where
274 D: serde::Deserializer<'de>,
275 {
276 let id = DeclIdIndexType::deserialize(deserializer)?;
277 Ok(DeclId::new(id))
278 }
279}