1use parking_lot::RwLock;
2use std::{
3 collections::{HashMap, HashSet, VecDeque},
4 fmt::Write,
5 sync::Arc,
6};
7
8use sway_types::{Named, ProgramId, SourceId, Spanned};
9
10use crate::{
11 concurrent_slab::ConcurrentSlab,
12 decl_engine::{parsed_id::ParsedDeclId, *},
13 engine_threading::*,
14 language::{
15 parsed::{
16 AbiDeclaration, ConfigurableDeclaration, ConstGenericDeclaration, ConstantDeclaration,
17 Declaration, EnumDeclaration, FunctionDeclaration, ImplSelfOrTrait, StorageDeclaration,
18 StructDeclaration, TraitDeclaration, TraitFn, TraitTypeDeclaration,
19 TypeAliasDeclaration,
20 },
21 ty::{
22 self, TyAbiDecl, TyConfigurableDecl, TyConstGenericDecl, TyConstantDecl,
23 TyDeclParsedType, TyEnumDecl, TyFunctionDecl, TyImplSelfOrTrait, TyStorageDecl,
24 TyStructDecl, TyTraitDecl, TyTraitFn, TyTraitType, TyTypeAliasDecl,
25 },
26 },
27};
28
29#[derive(Debug, Default)]
31pub struct DeclEngine {
32 function_slab: ConcurrentSlab<TyFunctionDecl>,
33 trait_slab: ConcurrentSlab<TyTraitDecl>,
34 trait_fn_slab: ConcurrentSlab<TyTraitFn>,
35 trait_type_slab: ConcurrentSlab<TyTraitType>,
36 impl_self_or_trait_slab: ConcurrentSlab<TyImplSelfOrTrait>,
37 struct_slab: ConcurrentSlab<TyStructDecl>,
38 storage_slab: ConcurrentSlab<TyStorageDecl>,
39 abi_slab: ConcurrentSlab<TyAbiDecl>,
40 constant_slab: ConcurrentSlab<TyConstantDecl>,
41 configurable_slab: ConcurrentSlab<TyConfigurableDecl>,
42 const_generics_slab: ConcurrentSlab<TyConstGenericDecl>,
43 enum_slab: ConcurrentSlab<TyEnumDecl>,
44 type_alias_slab: ConcurrentSlab<TyTypeAliasDecl>,
45
46 function_parsed_decl_id_map:
47 RwLock<HashMap<DeclId<TyFunctionDecl>, ParsedDeclId<FunctionDeclaration>>>,
48 trait_parsed_decl_id_map: RwLock<HashMap<DeclId<TyTraitDecl>, ParsedDeclId<TraitDeclaration>>>,
49 trait_fn_parsed_decl_id_map: RwLock<HashMap<DeclId<TyTraitFn>, ParsedDeclId<TraitFn>>>,
50 trait_type_parsed_decl_id_map:
51 RwLock<HashMap<DeclId<TyTraitType>, ParsedDeclId<TraitTypeDeclaration>>>,
52 impl_self_or_trait_parsed_decl_id_map:
53 RwLock<HashMap<DeclId<TyImplSelfOrTrait>, ParsedDeclId<ImplSelfOrTrait>>>,
54 struct_parsed_decl_id_map:
55 RwLock<HashMap<DeclId<TyStructDecl>, ParsedDeclId<StructDeclaration>>>,
56 storage_parsed_decl_id_map:
57 RwLock<HashMap<DeclId<TyStorageDecl>, ParsedDeclId<StorageDeclaration>>>,
58 abi_parsed_decl_id_map: RwLock<HashMap<DeclId<TyAbiDecl>, ParsedDeclId<AbiDeclaration>>>,
59 constant_parsed_decl_id_map:
60 RwLock<HashMap<DeclId<TyConstantDecl>, ParsedDeclId<ConstantDeclaration>>>,
61 configurable_parsed_decl_id_map:
62 RwLock<HashMap<DeclId<TyConfigurableDecl>, ParsedDeclId<ConfigurableDeclaration>>>,
63 const_generics_parsed_decl_id_map:
64 RwLock<HashMap<DeclId<TyConstGenericDecl>, ParsedDeclId<ConstGenericDeclaration>>>,
65 enum_parsed_decl_id_map: RwLock<HashMap<DeclId<TyEnumDecl>, ParsedDeclId<EnumDeclaration>>>,
66 type_alias_parsed_decl_id_map:
67 RwLock<HashMap<DeclId<TyTypeAliasDecl>, ParsedDeclId<TypeAliasDeclaration>>>,
68
69 parents: RwLock<HashMap<AssociatedItemDeclId, Vec<AssociatedItemDeclId>>>,
70}
71
72impl Clone for DeclEngine {
73 fn clone(&self) -> Self {
74 DeclEngine {
75 function_slab: self.function_slab.clone(),
76 trait_slab: self.trait_slab.clone(),
77 trait_fn_slab: self.trait_fn_slab.clone(),
78 trait_type_slab: self.trait_type_slab.clone(),
79 impl_self_or_trait_slab: self.impl_self_or_trait_slab.clone(),
80 struct_slab: self.struct_slab.clone(),
81 storage_slab: self.storage_slab.clone(),
82 abi_slab: self.abi_slab.clone(),
83 constant_slab: self.constant_slab.clone(),
84 configurable_slab: self.configurable_slab.clone(),
85 const_generics_slab: self.const_generics_slab.clone(),
86 enum_slab: self.enum_slab.clone(),
87 type_alias_slab: self.type_alias_slab.clone(),
88 function_parsed_decl_id_map: RwLock::new(
89 self.function_parsed_decl_id_map.read().clone(),
90 ),
91 trait_parsed_decl_id_map: RwLock::new(self.trait_parsed_decl_id_map.read().clone()),
92 trait_fn_parsed_decl_id_map: RwLock::new(
93 self.trait_fn_parsed_decl_id_map.read().clone(),
94 ),
95 trait_type_parsed_decl_id_map: RwLock::new(
96 self.trait_type_parsed_decl_id_map.read().clone(),
97 ),
98 impl_self_or_trait_parsed_decl_id_map: RwLock::new(
99 self.impl_self_or_trait_parsed_decl_id_map.read().clone(),
100 ),
101 struct_parsed_decl_id_map: RwLock::new(self.struct_parsed_decl_id_map.read().clone()),
102 storage_parsed_decl_id_map: RwLock::new(self.storage_parsed_decl_id_map.read().clone()),
103 abi_parsed_decl_id_map: RwLock::new(self.abi_parsed_decl_id_map.read().clone()),
104 constant_parsed_decl_id_map: RwLock::new(
105 self.constant_parsed_decl_id_map.read().clone(),
106 ),
107 configurable_parsed_decl_id_map: RwLock::new(
108 self.configurable_parsed_decl_id_map.read().clone(),
109 ),
110 const_generics_parsed_decl_id_map: RwLock::new(
111 self.const_generics_parsed_decl_id_map.read().clone(),
112 ),
113 enum_parsed_decl_id_map: RwLock::new(self.enum_parsed_decl_id_map.read().clone()),
114 type_alias_parsed_decl_id_map: RwLock::new(
115 self.type_alias_parsed_decl_id_map.read().clone(),
116 ),
117 parents: RwLock::new(self.parents.read().clone()),
118 }
119 }
120}
121
122pub trait DeclEngineGet<I, U> {
123 fn get(&self, index: &I) -> Arc<U>;
124 fn map<R>(&self, index: &I, f: impl FnOnce(&U) -> R) -> R;
125}
126
127pub trait DeclEngineGetParsedDeclId<T>
128where
129 T: TyDeclParsedType,
130{
131 fn get_parsed_decl_id(&self, decl_id: &DeclId<T>) -> Option<ParsedDeclId<T::ParsedType>>;
132}
133
134pub trait DeclEngineGetParsedDecl<T>
135where
136 T: TyDeclParsedType,
137{
138 fn get_parsed_decl(&self, decl_id: &DeclId<T>) -> Option<Declaration>;
139}
140
141pub trait DeclEngineInsert<T>
142where
143 T: Named + Spanned + TyDeclParsedType,
144{
145 fn insert(
146 &self,
147 decl: T,
148 parsed_decl_id: Option<&ParsedDeclId<T::ParsedType>>,
149 ) -> DeclRef<DeclId<T>>;
150}
151
152pub trait DeclEngineInsertArc<T>
153where
154 T: Named + Spanned + TyDeclParsedType,
155{
156 fn insert_arc(
157 &self,
158 decl: Arc<T>,
159 parsed_decl_id: Option<&ParsedDeclId<T::ParsedType>>,
160 ) -> DeclRef<DeclId<T>>;
161}
162
163pub trait DeclEngineReplace<T> {
164 fn replace(&self, index: DeclId<T>, decl: T);
165}
166
167pub trait DeclEngineIndex<T>: DeclEngineGet<DeclId<T>, T> + DeclEngineReplace<T>
168where
169 T: Named + Spanned,
170{
171}
172
173macro_rules! decl_engine_get {
174 ($slab:ident, $decl:ty) => {
175 impl DeclEngineGet<DeclId<$decl>, $decl> for DeclEngine {
176 fn get(&self, index: &DeclId<$decl>) -> Arc<$decl> {
177 self.$slab.get(index.inner())
178 }
179
180 fn map<R>(&self, index: &DeclId<$decl>, f: impl FnOnce(&$decl) -> R) -> R {
181 self.$slab.map(index.inner(), f)
182 }
183 }
184
185 impl DeclEngineGet<DeclRef<DeclId<$decl>>, $decl> for DeclEngine {
186 fn get(&self, index: &DeclRef<DeclId<$decl>>) -> Arc<$decl> {
187 self.$slab.get(index.id().inner())
188 }
189
190 fn map<R>(&self, index: &DeclRef<DeclId<$decl>>, f: impl FnOnce(&$decl) -> R) -> R {
191 self.$slab.map(index.id().inner(), f)
192 }
193 }
194 };
195}
196decl_engine_get!(function_slab, ty::TyFunctionDecl);
197decl_engine_get!(trait_slab, ty::TyTraitDecl);
198decl_engine_get!(trait_fn_slab, ty::TyTraitFn);
199decl_engine_get!(trait_type_slab, ty::TyTraitType);
200decl_engine_get!(impl_self_or_trait_slab, ty::TyImplSelfOrTrait);
201decl_engine_get!(struct_slab, ty::TyStructDecl);
202decl_engine_get!(storage_slab, ty::TyStorageDecl);
203decl_engine_get!(abi_slab, ty::TyAbiDecl);
204decl_engine_get!(constant_slab, ty::TyConstantDecl);
205decl_engine_get!(configurable_slab, ty::TyConfigurableDecl);
206decl_engine_get!(const_generics_slab, ty::TyConstGenericDecl);
207decl_engine_get!(enum_slab, ty::TyEnumDecl);
208decl_engine_get!(type_alias_slab, ty::TyTypeAliasDecl);
209
210macro_rules! decl_engine_insert {
211 ($slab:ident, $parsed_slab:ident, $decl:ty) => {
212 impl DeclEngineInsert<$decl> for DeclEngine {
213 fn insert(
214 &self,
215 decl: $decl,
216 parsed_decl_id: Option<&ParsedDeclId<<$decl as TyDeclParsedType>::ParsedType>>,
217 ) -> DeclRef<DeclId<$decl>> {
218 let span = decl.span();
219 let decl_name = decl.name().clone();
220 let decl_id = DeclId::new(self.$slab.insert(decl));
221 if let Some(parsed_decl_id) = parsed_decl_id {
222 self.$parsed_slab
223 .write()
224 .insert(decl_id, parsed_decl_id.clone());
225 }
226 DeclRef::new(decl_name, decl_id, span)
227 }
228 }
229 impl DeclEngineInsertArc<$decl> for DeclEngine {
230 fn insert_arc(
231 &self,
232 decl: Arc<$decl>,
233 parsed_decl_id: Option<&ParsedDeclId<<$decl as TyDeclParsedType>::ParsedType>>,
234 ) -> DeclRef<DeclId<$decl>> {
235 let span = decl.span();
236 let decl_name = decl.name().clone();
237 let decl_id = DeclId::new(self.$slab.insert_arc(decl));
238 if let Some(parsed_decl_id) = parsed_decl_id {
239 self.$parsed_slab
240 .write()
241 .insert(decl_id, parsed_decl_id.clone());
242 }
243 DeclRef::new(decl_name, decl_id, span)
244 }
245 }
246 };
247}
248decl_engine_insert!(
249 function_slab,
250 function_parsed_decl_id_map,
251 ty::TyFunctionDecl
252);
253decl_engine_insert!(trait_slab, trait_parsed_decl_id_map, ty::TyTraitDecl);
254decl_engine_insert!(trait_fn_slab, trait_fn_parsed_decl_id_map, ty::TyTraitFn);
255decl_engine_insert!(
256 trait_type_slab,
257 trait_type_parsed_decl_id_map,
258 ty::TyTraitType
259);
260decl_engine_insert!(
261 impl_self_or_trait_slab,
262 impl_self_or_trait_parsed_decl_id_map,
263 ty::TyImplSelfOrTrait
264);
265decl_engine_insert!(struct_slab, struct_parsed_decl_id_map, ty::TyStructDecl);
266decl_engine_insert!(storage_slab, storage_parsed_decl_id_map, ty::TyStorageDecl);
267decl_engine_insert!(abi_slab, abi_parsed_decl_id_map, ty::TyAbiDecl);
268decl_engine_insert!(
269 constant_slab,
270 constant_parsed_decl_id_map,
271 ty::TyConstantDecl
272);
273decl_engine_insert!(
274 configurable_slab,
275 configurable_parsed_decl_id_map,
276 ty::TyConfigurableDecl
277);
278decl_engine_insert!(
279 const_generics_slab,
280 const_generics_parsed_decl_id_map,
281 ty::TyConstGenericDecl
282);
283decl_engine_insert!(enum_slab, enum_parsed_decl_id_map, ty::TyEnumDecl);
284decl_engine_insert!(
285 type_alias_slab,
286 type_alias_parsed_decl_id_map,
287 ty::TyTypeAliasDecl
288);
289
290macro_rules! decl_engine_parsed_decl_id {
291 ($slab:ident, $decl:ty) => {
292 impl DeclEngineGetParsedDeclId<$decl> for DeclEngine {
293 fn get_parsed_decl_id(
294 &self,
295 decl_id: &DeclId<$decl>,
296 ) -> Option<ParsedDeclId<<$decl as TyDeclParsedType>::ParsedType>> {
297 let parsed_decl_id_map = self.$slab.read();
298 if let Some(parsed_decl_id) = parsed_decl_id_map.get(&decl_id) {
299 return Some(parsed_decl_id.clone());
300 } else {
301 None
302 }
303 }
304 }
305 };
306}
307
308decl_engine_parsed_decl_id!(function_parsed_decl_id_map, ty::TyFunctionDecl);
309decl_engine_parsed_decl_id!(trait_parsed_decl_id_map, ty::TyTraitDecl);
310decl_engine_parsed_decl_id!(trait_fn_parsed_decl_id_map, ty::TyTraitFn);
311decl_engine_parsed_decl_id!(trait_type_parsed_decl_id_map, ty::TyTraitType);
312decl_engine_parsed_decl_id!(impl_self_or_trait_parsed_decl_id_map, ty::TyImplSelfOrTrait);
313decl_engine_parsed_decl_id!(struct_parsed_decl_id_map, ty::TyStructDecl);
314decl_engine_parsed_decl_id!(storage_parsed_decl_id_map, ty::TyStorageDecl);
315decl_engine_parsed_decl_id!(abi_parsed_decl_id_map, ty::TyAbiDecl);
316decl_engine_parsed_decl_id!(constant_parsed_decl_id_map, ty::TyConstantDecl);
317decl_engine_parsed_decl_id!(configurable_parsed_decl_id_map, ty::TyConfigurableDecl);
318decl_engine_parsed_decl_id!(enum_parsed_decl_id_map, ty::TyEnumDecl);
319decl_engine_parsed_decl_id!(type_alias_parsed_decl_id_map, ty::TyTypeAliasDecl);
320
321macro_rules! decl_engine_parsed_decl {
322 ($slab:ident, $decl:ty, $ctor:expr) => {
323 impl DeclEngineGetParsedDecl<$decl> for DeclEngine {
324 fn get_parsed_decl(&self, decl_id: &DeclId<$decl>) -> Option<Declaration> {
325 let parsed_decl_id_map = self.$slab.read();
326 if let Some(parsed_decl_id) = parsed_decl_id_map.get(&decl_id) {
327 return Some($ctor(parsed_decl_id.clone()));
328 } else {
329 None
330 }
331 }
332 }
333 };
334}
335
336decl_engine_parsed_decl!(
337 function_parsed_decl_id_map,
338 ty::TyFunctionDecl,
339 Declaration::FunctionDeclaration
340);
341decl_engine_parsed_decl!(
342 trait_parsed_decl_id_map,
343 ty::TyTraitDecl,
344 Declaration::TraitDeclaration
345);
346decl_engine_parsed_decl!(
347 trait_fn_parsed_decl_id_map,
348 ty::TyTraitFn,
349 Declaration::TraitFnDeclaration
350);
351decl_engine_parsed_decl!(
352 trait_type_parsed_decl_id_map,
353 ty::TyTraitType,
354 Declaration::TraitTypeDeclaration
355);
356decl_engine_parsed_decl!(
357 impl_self_or_trait_parsed_decl_id_map,
358 ty::TyImplSelfOrTrait,
359 Declaration::ImplSelfOrTrait
360);
361decl_engine_parsed_decl!(
362 struct_parsed_decl_id_map,
363 ty::TyStructDecl,
364 Declaration::StructDeclaration
365);
366decl_engine_parsed_decl!(
367 storage_parsed_decl_id_map,
368 ty::TyStorageDecl,
369 Declaration::StorageDeclaration
370);
371decl_engine_parsed_decl!(
372 abi_parsed_decl_id_map,
373 ty::TyAbiDecl,
374 Declaration::AbiDeclaration
375);
376decl_engine_parsed_decl!(
377 constant_parsed_decl_id_map,
378 ty::TyConstantDecl,
379 Declaration::ConstantDeclaration
380);
381decl_engine_parsed_decl!(
382 configurable_parsed_decl_id_map,
383 ty::TyConfigurableDecl,
384 Declaration::ConfigurableDeclaration
385);
386decl_engine_parsed_decl!(
387 enum_parsed_decl_id_map,
388 ty::TyEnumDecl,
389 Declaration::EnumDeclaration
390);
391decl_engine_parsed_decl!(
392 type_alias_parsed_decl_id_map,
393 ty::TyTypeAliasDecl,
394 Declaration::TypeAliasDeclaration
395);
396
397macro_rules! decl_engine_replace {
398 ($slab:ident, $decl:ty) => {
399 impl DeclEngineReplace<$decl> for DeclEngine {
400 fn replace(&self, index: DeclId<$decl>, decl: $decl) {
401 self.$slab.replace(index.inner(), decl);
402 }
403 }
404 };
405}
406decl_engine_replace!(function_slab, ty::TyFunctionDecl);
407decl_engine_replace!(trait_slab, ty::TyTraitDecl);
408decl_engine_replace!(trait_fn_slab, ty::TyTraitFn);
409decl_engine_replace!(trait_type_slab, ty::TyTraitType);
410decl_engine_replace!(impl_self_or_trait_slab, ty::TyImplSelfOrTrait);
411decl_engine_replace!(struct_slab, ty::TyStructDecl);
412decl_engine_replace!(storage_slab, ty::TyStorageDecl);
413decl_engine_replace!(abi_slab, ty::TyAbiDecl);
414decl_engine_replace!(constant_slab, ty::TyConstantDecl);
415decl_engine_replace!(configurable_slab, ty::TyConfigurableDecl);
416decl_engine_replace!(enum_slab, ty::TyEnumDecl);
417decl_engine_replace!(type_alias_slab, ty::TyTypeAliasDecl);
418
419macro_rules! decl_engine_index {
420 ($slab:ident, $decl:ty) => {
421 impl DeclEngineIndex<$decl> for DeclEngine {}
422 };
423}
424decl_engine_index!(function_slab, ty::TyFunctionDecl);
425decl_engine_index!(trait_slab, ty::TyTraitDecl);
426decl_engine_index!(trait_fn_slab, ty::TyTraitFn);
427decl_engine_index!(trait_type_slab, ty::TyTraitType);
428decl_engine_index!(impl_self_or_trait_slab, ty::TyImplSelfOrTrait);
429decl_engine_index!(struct_slab, ty::TyStructDecl);
430decl_engine_index!(storage_slab, ty::TyStorageDecl);
431decl_engine_index!(abi_slab, ty::TyAbiDecl);
432decl_engine_index!(constant_slab, ty::TyConstantDecl);
433decl_engine_index!(configurable_slab, ty::TyConfigurableDecl);
434decl_engine_index!(enum_slab, ty::TyEnumDecl);
435decl_engine_index!(type_alias_slab, ty::TyTypeAliasDecl);
436
437macro_rules! decl_engine_clear_program {
438 ($($slab:ident, $decl:ty);* $(;)?) => {
439 impl DeclEngine {
440 pub fn clear_program(&mut self, program_id: &ProgramId) {
441 self.parents.write().retain(|key, _| {
442 match key {
443 AssociatedItemDeclId::TraitFn(decl_id) => {
444 self.get_trait_fn(decl_id).span().source_id().map_or(true, |src_id| &src_id.program_id() != program_id)
445 },
446 AssociatedItemDeclId::Function(decl_id) => {
447 self.get_function(decl_id).span().source_id().map_or(true, |src_id| &src_id.program_id() != program_id)
448 },
449 AssociatedItemDeclId::Type(decl_id) => {
450 self.get_type(decl_id).span().source_id().map_or(true, |src_id| &src_id.program_id() != program_id)
451 },
452 AssociatedItemDeclId::Constant(decl_id) => {
453 self.get_constant(decl_id).span().source_id().map_or(true, |src_id| &src_id.program_id() != program_id)
454 },
455 }
456 });
457
458 $(
459 self.$slab.retain(|_k, ty| match ty.span().source_id() {
460 Some(source_id) => &source_id.program_id() != program_id,
461 None => true,
462 });
463 )*
464 }
465 }
466 };
467}
468
469decl_engine_clear_program!(
470 function_slab, ty::TyFunctionDecl;
471 trait_slab, ty::TyTraitDecl;
472 trait_fn_slab, ty::TyTraitFn;
473 trait_type_slab, ty::TyTraitType;
474 impl_self_or_trait_slab, ty::TyImplTrait;
475 struct_slab, ty::TyStructDecl;
476 storage_slab, ty::TyStorageDecl;
477 abi_slab, ty::TyAbiDecl;
478 constant_slab, ty::TyConstantDecl;
479 configurable_slab, ty::TyConfigurableDecl;
480 enum_slab, ty::TyEnumDecl;
481 type_alias_slab, ty::TyTypeAliasDecl;
482);
483
484macro_rules! decl_engine_clear_module {
485 ($($slab:ident, $decl:ty);* $(;)?) => {
486 impl DeclEngine {
487 pub fn clear_module(&mut self, source_id: &SourceId) {
488 self.parents.write().retain(|key, _| {
489 match key {
490 AssociatedItemDeclId::TraitFn(decl_id) => {
491 self.get_trait_fn(decl_id).span().source_id().map_or(true, |src_id| src_id != source_id)
492 },
493 AssociatedItemDeclId::Function(decl_id) => {
494 self.get_function(decl_id).span().source_id().map_or(true, |src_id| src_id != source_id)
495 },
496 AssociatedItemDeclId::Type(decl_id) => {
497 self.get_type(decl_id).span().source_id().map_or(true, |src_id| src_id != source_id)
498 },
499 AssociatedItemDeclId::Constant(decl_id) => {
500 self.get_constant(decl_id).span().source_id().map_or(true, |src_id| src_id != source_id)
501 },
502 }
503 });
504
505 $(
506 self.$slab.retain(|_k, ty| match ty.span().source_id() {
507 Some(src_id) => src_id != source_id,
508 None => true,
509 });
510 )*
511 }
512 }
513 };
514}
515
516decl_engine_clear_module!(
517 function_slab, ty::TyFunctionDecl;
518 trait_slab, ty::TyTraitDecl;
519 trait_fn_slab, ty::TyTraitFn;
520 trait_type_slab, ty::TyTraitType;
521 impl_self_or_trait_slab, ty::TyImplTrait;
522 struct_slab, ty::TyStructDecl;
523 storage_slab, ty::TyStorageDecl;
524 abi_slab, ty::TyAbiDecl;
525 constant_slab, ty::TyConstantDecl;
526 configurable_slab, ty::TyConfigurableDecl;
527 enum_slab, ty::TyEnumDecl;
528 type_alias_slab, ty::TyTypeAliasDecl;
529);
530
531impl DeclEngine {
532 #[allow(clippy::map_entry)]
537 pub(crate) fn find_all_parents<'a, T>(
538 &self,
539 engines: &Engines,
540 index: &'a T,
541 ) -> Vec<AssociatedItemDeclId>
542 where
543 AssociatedItemDeclId: From<&'a T>,
544 {
545 let index: AssociatedItemDeclId = AssociatedItemDeclId::from(index);
546 let parents = self.parents.read();
547 let mut acc_parents: HashMap<AssociatedItemDeclId, AssociatedItemDeclId> = HashMap::new();
548 let mut already_checked: HashSet<AssociatedItemDeclId> = HashSet::new();
549 let mut left_to_check: VecDeque<AssociatedItemDeclId> = VecDeque::from([index]);
550 while let Some(curr) = left_to_check.pop_front() {
551 if !already_checked.insert(curr.clone()) {
552 continue;
553 }
554 if let Some(curr_parents) = parents.get(&curr) {
555 for curr_parent in curr_parents.iter() {
556 if !acc_parents.contains_key(curr_parent) {
557 acc_parents.insert(curr_parent.clone(), curr_parent.clone());
558 }
559 if !left_to_check.iter().any(|x| match (x, curr_parent) {
560 (
561 AssociatedItemDeclId::TraitFn(x_id),
562 AssociatedItemDeclId::TraitFn(curr_parent_id),
563 ) => self.get(x_id).eq(
564 &self.get(curr_parent_id),
565 &PartialEqWithEnginesContext::new(engines),
566 ),
567 (
568 AssociatedItemDeclId::Function(x_id),
569 AssociatedItemDeclId::Function(curr_parent_id),
570 ) => self.get(x_id).eq(
571 &self.get(curr_parent_id),
572 &PartialEqWithEnginesContext::new(engines),
573 ),
574 _ => false,
575 }) {
576 left_to_check.push_back(curr_parent.clone());
577 }
578 }
579 }
580 }
581 acc_parents.values().cloned().collect()
582 }
583
584 pub(crate) fn register_parent<I>(
585 &self,
586 index: AssociatedItemDeclId,
587 parent: AssociatedItemDeclId,
588 ) where
589 AssociatedItemDeclId: From<DeclId<I>>,
590 {
591 let mut parents = self.parents.write();
592 parents
593 .entry(index)
594 .and_modify(|e| e.push(parent.clone()))
595 .or_insert_with(|| vec![parent]);
596 }
597
598 pub fn get_function<I>(&self, index: &I) -> Arc<ty::TyFunctionDecl>
604 where
605 DeclEngine: DeclEngineGet<I, ty::TyFunctionDecl>,
606 {
607 self.get(index)
608 }
609
610 pub fn get_trait<I>(&self, index: &I) -> Arc<ty::TyTraitDecl>
616 where
617 DeclEngine: DeclEngineGet<I, ty::TyTraitDecl>,
618 {
619 self.get(index)
620 }
621
622 pub fn get_traits_by_name(&self, trait_name: &Ident) -> Vec<ty::TyTraitDecl> {
627 let mut vec = vec![];
628 for trait_decl in self.trait_slab.values() {
629 if trait_decl.name == *trait_name {
630 vec.push((*trait_decl).clone())
631 }
632 }
633 vec
634 }
635
636 pub fn get_trait_fn<I>(&self, index: &I) -> Arc<ty::TyTraitFn>
642 where
643 DeclEngine: DeclEngineGet<I, ty::TyTraitFn>,
644 {
645 self.get(index)
646 }
647
648 pub fn get_impl_self_or_trait<I>(&self, index: &I) -> Arc<ty::TyImplSelfOrTrait>
654 where
655 DeclEngine: DeclEngineGet<I, ty::TyImplSelfOrTrait>,
656 {
657 self.get(index)
658 }
659
660 pub fn get_struct<I>(&self, index: &I) -> Arc<ty::TyStructDecl>
666 where
667 DeclEngine: DeclEngineGet<I, ty::TyStructDecl>,
668 {
669 self.get(index)
670 }
671
672 pub fn get_storage<I>(&self, index: &I) -> Arc<ty::TyStorageDecl>
678 where
679 DeclEngine: DeclEngineGet<I, ty::TyStorageDecl>,
680 {
681 self.get(index)
682 }
683
684 pub fn get_abi<I>(&self, index: &I) -> Arc<ty::TyAbiDecl>
690 where
691 DeclEngine: DeclEngineGet<I, ty::TyAbiDecl>,
692 {
693 self.get(index)
694 }
695
696 pub fn get_constant<I>(&self, index: &I) -> Arc<ty::TyConstantDecl>
702 where
703 DeclEngine: DeclEngineGet<I, ty::TyConstantDecl>,
704 {
705 self.get(index)
706 }
707
708 pub fn get_configurable<I>(&self, index: &I) -> Arc<ty::TyConfigurableDecl>
714 where
715 DeclEngine: DeclEngineGet<I, ty::TyConfigurableDecl>,
716 {
717 self.get(index)
718 }
719
720 pub fn get_const_generic<I>(&self, index: &I) -> Arc<ty::TyConstGenericDecl>
726 where
727 DeclEngine: DeclEngineGet<I, ty::TyConstGenericDecl>,
728 {
729 self.get(index)
730 }
731
732 pub fn get_type<I>(&self, index: &I) -> Arc<ty::TyTraitType>
738 where
739 DeclEngine: DeclEngineGet<I, ty::TyTraitType>,
740 {
741 self.get(index)
742 }
743
744 pub fn get_enum<I>(&self, index: &I) -> Arc<ty::TyEnumDecl>
750 where
751 DeclEngine: DeclEngineGet<I, ty::TyEnumDecl>,
752 {
753 self.get(index)
754 }
755
756 pub fn get_type_alias<I>(&self, index: &I) -> Arc<ty::TyTypeAliasDecl>
762 where
763 DeclEngine: DeclEngineGet<I, ty::TyTypeAliasDecl>,
764 {
765 self.get(index)
766 }
767
768 pub fn pretty_print(&self, engines: &Engines) -> String {
772 let mut builder = String::new();
773 let mut list = String::with_capacity(1024 * 1024);
774 let funcs = self.function_slab.values();
775 for (i, func) in funcs.iter().enumerate() {
776 list.push_str(&format!("{i} - {:?}\n", engines.help_out(func)));
777 }
778 write!(builder, "DeclEngine {{\n{list}\n}}").unwrap();
779 builder
780 }
781}