sway_core/decl_engine/
id.rs

1use 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
21/// An ID used to refer to an item in the [DeclEngine](super::decl_engine::DeclEngine)
22pub 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        // we assume that `usize::MAX` id is not possible in practice
90        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}