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}
125
126pub trait DeclEngineGetParsedDeclId<T>
127where
128 T: TyDeclParsedType,
129{
130 fn get_parsed_decl_id(&self, decl_id: &DeclId<T>) -> Option<ParsedDeclId<T::ParsedType>>;
131}
132
133pub trait DeclEngineGetParsedDecl<T>
134where
135 T: TyDeclParsedType,
136{
137 fn get_parsed_decl(&self, decl_id: &DeclId<T>) -> Option<Declaration>;
138}
139
140pub trait DeclEngineInsert<T>
141where
142 T: Named + Spanned + TyDeclParsedType,
143{
144 fn insert(
145 &self,
146 decl: T,
147 parsed_decl_id: Option<&ParsedDeclId<T::ParsedType>>,
148 ) -> DeclRef<DeclId<T>>;
149}
150
151pub trait DeclEngineInsertArc<T>
152where
153 T: Named + Spanned + TyDeclParsedType,
154{
155 fn insert_arc(
156 &self,
157 decl: Arc<T>,
158 parsed_decl_id: Option<&ParsedDeclId<T::ParsedType>>,
159 ) -> DeclRef<DeclId<T>>;
160}
161
162pub trait DeclEngineReplace<T> {
163 fn replace(&self, index: DeclId<T>, decl: T);
164}
165
166pub trait DeclEngineIndex<T>: DeclEngineGet<DeclId<T>, T> + DeclEngineReplace<T>
167where
168 T: Named + Spanned,
169{
170}
171
172macro_rules! decl_engine_get {
173 ($slab:ident, $decl:ty) => {
174 impl DeclEngineGet<DeclId<$decl>, $decl> for DeclEngine {
175 fn get(&self, index: &DeclId<$decl>) -> Arc<$decl> {
176 self.$slab.get(index.inner())
177 }
178 }
179
180 impl DeclEngineGet<DeclRef<DeclId<$decl>>, $decl> for DeclEngine {
181 fn get(&self, index: &DeclRef<DeclId<$decl>>) -> Arc<$decl> {
182 self.$slab.get(index.id().inner())
183 }
184 }
185 };
186}
187decl_engine_get!(function_slab, ty::TyFunctionDecl);
188decl_engine_get!(trait_slab, ty::TyTraitDecl);
189decl_engine_get!(trait_fn_slab, ty::TyTraitFn);
190decl_engine_get!(trait_type_slab, ty::TyTraitType);
191decl_engine_get!(impl_self_or_trait_slab, ty::TyImplSelfOrTrait);
192decl_engine_get!(struct_slab, ty::TyStructDecl);
193decl_engine_get!(storage_slab, ty::TyStorageDecl);
194decl_engine_get!(abi_slab, ty::TyAbiDecl);
195decl_engine_get!(constant_slab, ty::TyConstantDecl);
196decl_engine_get!(configurable_slab, ty::TyConfigurableDecl);
197decl_engine_get!(const_generics_slab, ty::TyConstGenericDecl);
198decl_engine_get!(enum_slab, ty::TyEnumDecl);
199decl_engine_get!(type_alias_slab, ty::TyTypeAliasDecl);
200
201macro_rules! decl_engine_insert {
202 ($slab:ident, $parsed_slab:ident, $decl:ty) => {
203 impl DeclEngineInsert<$decl> for DeclEngine {
204 fn insert(
205 &self,
206 decl: $decl,
207 parsed_decl_id: Option<&ParsedDeclId<<$decl as TyDeclParsedType>::ParsedType>>,
208 ) -> DeclRef<DeclId<$decl>> {
209 let span = decl.span();
210 let decl_name = decl.name().clone();
211 let decl_id = DeclId::new(self.$slab.insert(decl));
212 if let Some(parsed_decl_id) = parsed_decl_id {
213 self.$parsed_slab
214 .write()
215 .insert(decl_id, parsed_decl_id.clone());
216 }
217 DeclRef::new(decl_name, decl_id, span)
218 }
219 }
220 impl DeclEngineInsertArc<$decl> for DeclEngine {
221 fn insert_arc(
222 &self,
223 decl: Arc<$decl>,
224 parsed_decl_id: Option<&ParsedDeclId<<$decl as TyDeclParsedType>::ParsedType>>,
225 ) -> DeclRef<DeclId<$decl>> {
226 let span = decl.span();
227 let decl_name = decl.name().clone();
228 let decl_id = DeclId::new(self.$slab.insert_arc(decl));
229 if let Some(parsed_decl_id) = parsed_decl_id {
230 self.$parsed_slab
231 .write()
232 .insert(decl_id, parsed_decl_id.clone());
233 }
234 DeclRef::new(decl_name, decl_id, span)
235 }
236 }
237 };
238}
239decl_engine_insert!(
240 function_slab,
241 function_parsed_decl_id_map,
242 ty::TyFunctionDecl
243);
244decl_engine_insert!(trait_slab, trait_parsed_decl_id_map, ty::TyTraitDecl);
245decl_engine_insert!(trait_fn_slab, trait_fn_parsed_decl_id_map, ty::TyTraitFn);
246decl_engine_insert!(
247 trait_type_slab,
248 trait_type_parsed_decl_id_map,
249 ty::TyTraitType
250);
251decl_engine_insert!(
252 impl_self_or_trait_slab,
253 impl_self_or_trait_parsed_decl_id_map,
254 ty::TyImplSelfOrTrait
255);
256decl_engine_insert!(struct_slab, struct_parsed_decl_id_map, ty::TyStructDecl);
257decl_engine_insert!(storage_slab, storage_parsed_decl_id_map, ty::TyStorageDecl);
258decl_engine_insert!(abi_slab, abi_parsed_decl_id_map, ty::TyAbiDecl);
259decl_engine_insert!(
260 constant_slab,
261 constant_parsed_decl_id_map,
262 ty::TyConstantDecl
263);
264decl_engine_insert!(
265 configurable_slab,
266 configurable_parsed_decl_id_map,
267 ty::TyConfigurableDecl
268);
269decl_engine_insert!(
270 const_generics_slab,
271 const_generics_parsed_decl_id_map,
272 ty::TyConstGenericDecl
273);
274decl_engine_insert!(enum_slab, enum_parsed_decl_id_map, ty::TyEnumDecl);
275decl_engine_insert!(
276 type_alias_slab,
277 type_alias_parsed_decl_id_map,
278 ty::TyTypeAliasDecl
279);
280
281macro_rules! decl_engine_parsed_decl_id {
282 ($slab:ident, $decl:ty) => {
283 impl DeclEngineGetParsedDeclId<$decl> for DeclEngine {
284 fn get_parsed_decl_id(
285 &self,
286 decl_id: &DeclId<$decl>,
287 ) -> Option<ParsedDeclId<<$decl as TyDeclParsedType>::ParsedType>> {
288 let parsed_decl_id_map = self.$slab.read();
289 if let Some(parsed_decl_id) = parsed_decl_id_map.get(&decl_id) {
290 return Some(parsed_decl_id.clone());
291 } else {
292 None
293 }
294 }
295 }
296 };
297}
298
299decl_engine_parsed_decl_id!(function_parsed_decl_id_map, ty::TyFunctionDecl);
300decl_engine_parsed_decl_id!(trait_parsed_decl_id_map, ty::TyTraitDecl);
301decl_engine_parsed_decl_id!(trait_fn_parsed_decl_id_map, ty::TyTraitFn);
302decl_engine_parsed_decl_id!(trait_type_parsed_decl_id_map, ty::TyTraitType);
303decl_engine_parsed_decl_id!(impl_self_or_trait_parsed_decl_id_map, ty::TyImplSelfOrTrait);
304decl_engine_parsed_decl_id!(struct_parsed_decl_id_map, ty::TyStructDecl);
305decl_engine_parsed_decl_id!(storage_parsed_decl_id_map, ty::TyStorageDecl);
306decl_engine_parsed_decl_id!(abi_parsed_decl_id_map, ty::TyAbiDecl);
307decl_engine_parsed_decl_id!(constant_parsed_decl_id_map, ty::TyConstantDecl);
308decl_engine_parsed_decl_id!(configurable_parsed_decl_id_map, ty::TyConfigurableDecl);
309decl_engine_parsed_decl_id!(enum_parsed_decl_id_map, ty::TyEnumDecl);
310decl_engine_parsed_decl_id!(type_alias_parsed_decl_id_map, ty::TyTypeAliasDecl);
311
312macro_rules! decl_engine_parsed_decl {
313 ($slab:ident, $decl:ty, $ctor:expr) => {
314 impl DeclEngineGetParsedDecl<$decl> for DeclEngine {
315 fn get_parsed_decl(&self, decl_id: &DeclId<$decl>) -> Option<Declaration> {
316 let parsed_decl_id_map = self.$slab.read();
317 if let Some(parsed_decl_id) = parsed_decl_id_map.get(&decl_id) {
318 return Some($ctor(parsed_decl_id.clone()));
319 } else {
320 None
321 }
322 }
323 }
324 };
325}
326
327decl_engine_parsed_decl!(
328 function_parsed_decl_id_map,
329 ty::TyFunctionDecl,
330 Declaration::FunctionDeclaration
331);
332decl_engine_parsed_decl!(
333 trait_parsed_decl_id_map,
334 ty::TyTraitDecl,
335 Declaration::TraitDeclaration
336);
337decl_engine_parsed_decl!(
338 trait_fn_parsed_decl_id_map,
339 ty::TyTraitFn,
340 Declaration::TraitFnDeclaration
341);
342decl_engine_parsed_decl!(
343 trait_type_parsed_decl_id_map,
344 ty::TyTraitType,
345 Declaration::TraitTypeDeclaration
346);
347decl_engine_parsed_decl!(
348 impl_self_or_trait_parsed_decl_id_map,
349 ty::TyImplSelfOrTrait,
350 Declaration::ImplSelfOrTrait
351);
352decl_engine_parsed_decl!(
353 struct_parsed_decl_id_map,
354 ty::TyStructDecl,
355 Declaration::StructDeclaration
356);
357decl_engine_parsed_decl!(
358 storage_parsed_decl_id_map,
359 ty::TyStorageDecl,
360 Declaration::StorageDeclaration
361);
362decl_engine_parsed_decl!(
363 abi_parsed_decl_id_map,
364 ty::TyAbiDecl,
365 Declaration::AbiDeclaration
366);
367decl_engine_parsed_decl!(
368 constant_parsed_decl_id_map,
369 ty::TyConstantDecl,
370 Declaration::ConstantDeclaration
371);
372decl_engine_parsed_decl!(
373 configurable_parsed_decl_id_map,
374 ty::TyConfigurableDecl,
375 Declaration::ConfigurableDeclaration
376);
377decl_engine_parsed_decl!(
378 enum_parsed_decl_id_map,
379 ty::TyEnumDecl,
380 Declaration::EnumDeclaration
381);
382decl_engine_parsed_decl!(
383 type_alias_parsed_decl_id_map,
384 ty::TyTypeAliasDecl,
385 Declaration::TypeAliasDeclaration
386);
387
388macro_rules! decl_engine_replace {
389 ($slab:ident, $decl:ty) => {
390 impl DeclEngineReplace<$decl> for DeclEngine {
391 fn replace(&self, index: DeclId<$decl>, decl: $decl) {
392 self.$slab.replace(index.inner(), decl);
393 }
394 }
395 };
396}
397decl_engine_replace!(function_slab, ty::TyFunctionDecl);
398decl_engine_replace!(trait_slab, ty::TyTraitDecl);
399decl_engine_replace!(trait_fn_slab, ty::TyTraitFn);
400decl_engine_replace!(trait_type_slab, ty::TyTraitType);
401decl_engine_replace!(impl_self_or_trait_slab, ty::TyImplSelfOrTrait);
402decl_engine_replace!(struct_slab, ty::TyStructDecl);
403decl_engine_replace!(storage_slab, ty::TyStorageDecl);
404decl_engine_replace!(abi_slab, ty::TyAbiDecl);
405decl_engine_replace!(constant_slab, ty::TyConstantDecl);
406decl_engine_replace!(configurable_slab, ty::TyConfigurableDecl);
407decl_engine_replace!(enum_slab, ty::TyEnumDecl);
408decl_engine_replace!(type_alias_slab, ty::TyTypeAliasDecl);
409
410macro_rules! decl_engine_index {
411 ($slab:ident, $decl:ty) => {
412 impl DeclEngineIndex<$decl> for DeclEngine {}
413 };
414}
415decl_engine_index!(function_slab, ty::TyFunctionDecl);
416decl_engine_index!(trait_slab, ty::TyTraitDecl);
417decl_engine_index!(trait_fn_slab, ty::TyTraitFn);
418decl_engine_index!(trait_type_slab, ty::TyTraitType);
419decl_engine_index!(impl_self_or_trait_slab, ty::TyImplSelfOrTrait);
420decl_engine_index!(struct_slab, ty::TyStructDecl);
421decl_engine_index!(storage_slab, ty::TyStorageDecl);
422decl_engine_index!(abi_slab, ty::TyAbiDecl);
423decl_engine_index!(constant_slab, ty::TyConstantDecl);
424decl_engine_index!(configurable_slab, ty::TyConfigurableDecl);
425decl_engine_index!(enum_slab, ty::TyEnumDecl);
426decl_engine_index!(type_alias_slab, ty::TyTypeAliasDecl);
427
428macro_rules! decl_engine_clear_program {
429 ($($slab:ident, $decl:ty);* $(;)?) => {
430 impl DeclEngine {
431 pub fn clear_program(&mut self, program_id: &ProgramId) {
432 self.parents.write().retain(|key, _| {
433 match key {
434 AssociatedItemDeclId::TraitFn(decl_id) => {
435 self.get_trait_fn(decl_id).span().source_id().map_or(true, |src_id| &src_id.program_id() != program_id)
436 },
437 AssociatedItemDeclId::Function(decl_id) => {
438 self.get_function(decl_id).span().source_id().map_or(true, |src_id| &src_id.program_id() != program_id)
439 },
440 AssociatedItemDeclId::Type(decl_id) => {
441 self.get_type(decl_id).span().source_id().map_or(true, |src_id| &src_id.program_id() != program_id)
442 },
443 AssociatedItemDeclId::Constant(decl_id) => {
444 self.get_constant(decl_id).span().source_id().map_or(true, |src_id| &src_id.program_id() != program_id)
445 },
446 }
447 });
448
449 $(
450 self.$slab.retain(|_k, ty| match ty.span().source_id() {
451 Some(source_id) => &source_id.program_id() != program_id,
452 None => true,
453 });
454 )*
455 }
456 }
457 };
458}
459
460decl_engine_clear_program!(
461 function_slab, ty::TyFunctionDecl;
462 trait_slab, ty::TyTraitDecl;
463 trait_fn_slab, ty::TyTraitFn;
464 trait_type_slab, ty::TyTraitType;
465 impl_self_or_trait_slab, ty::TyImplTrait;
466 struct_slab, ty::TyStructDecl;
467 storage_slab, ty::TyStorageDecl;
468 abi_slab, ty::TyAbiDecl;
469 constant_slab, ty::TyConstantDecl;
470 configurable_slab, ty::TyConfigurableDecl;
471 enum_slab, ty::TyEnumDecl;
472 type_alias_slab, ty::TyTypeAliasDecl;
473);
474
475macro_rules! decl_engine_clear_module {
476 ($($slab:ident, $decl:ty);* $(;)?) => {
477 impl DeclEngine {
478 pub fn clear_module(&mut self, source_id: &SourceId) {
479 self.parents.write().retain(|key, _| {
480 match key {
481 AssociatedItemDeclId::TraitFn(decl_id) => {
482 self.get_trait_fn(decl_id).span().source_id().map_or(true, |src_id| src_id != source_id)
483 },
484 AssociatedItemDeclId::Function(decl_id) => {
485 self.get_function(decl_id).span().source_id().map_or(true, |src_id| src_id != source_id)
486 },
487 AssociatedItemDeclId::Type(decl_id) => {
488 self.get_type(decl_id).span().source_id().map_or(true, |src_id| src_id != source_id)
489 },
490 AssociatedItemDeclId::Constant(decl_id) => {
491 self.get_constant(decl_id).span().source_id().map_or(true, |src_id| src_id != source_id)
492 },
493 }
494 });
495
496 $(
497 self.$slab.retain(|_k, ty| match ty.span().source_id() {
498 Some(src_id) => src_id != source_id,
499 None => true,
500 });
501 )*
502 }
503 }
504 };
505}
506
507decl_engine_clear_module!(
508 function_slab, ty::TyFunctionDecl;
509 trait_slab, ty::TyTraitDecl;
510 trait_fn_slab, ty::TyTraitFn;
511 trait_type_slab, ty::TyTraitType;
512 impl_self_or_trait_slab, ty::TyImplTrait;
513 struct_slab, ty::TyStructDecl;
514 storage_slab, ty::TyStorageDecl;
515 abi_slab, ty::TyAbiDecl;
516 constant_slab, ty::TyConstantDecl;
517 configurable_slab, ty::TyConfigurableDecl;
518 enum_slab, ty::TyEnumDecl;
519 type_alias_slab, ty::TyTypeAliasDecl;
520);
521
522impl DeclEngine {
523 #[allow(clippy::map_entry)]
528 pub(crate) fn find_all_parents<'a, T>(
529 &self,
530 engines: &Engines,
531 index: &'a T,
532 ) -> Vec<AssociatedItemDeclId>
533 where
534 AssociatedItemDeclId: From<&'a T>,
535 {
536 let index: AssociatedItemDeclId = AssociatedItemDeclId::from(index);
537 let parents = self.parents.read();
538 let mut acc_parents: HashMap<AssociatedItemDeclId, AssociatedItemDeclId> = HashMap::new();
539 let mut already_checked: HashSet<AssociatedItemDeclId> = HashSet::new();
540 let mut left_to_check: VecDeque<AssociatedItemDeclId> = VecDeque::from([index]);
541 while let Some(curr) = left_to_check.pop_front() {
542 if !already_checked.insert(curr.clone()) {
543 continue;
544 }
545 if let Some(curr_parents) = parents.get(&curr) {
546 for curr_parent in curr_parents.iter() {
547 if !acc_parents.contains_key(curr_parent) {
548 acc_parents.insert(curr_parent.clone(), curr_parent.clone());
549 }
550 if !left_to_check.iter().any(|x| match (x, curr_parent) {
551 (
552 AssociatedItemDeclId::TraitFn(x_id),
553 AssociatedItemDeclId::TraitFn(curr_parent_id),
554 ) => self.get(x_id).eq(
555 &self.get(curr_parent_id),
556 &PartialEqWithEnginesContext::new(engines),
557 ),
558 (
559 AssociatedItemDeclId::Function(x_id),
560 AssociatedItemDeclId::Function(curr_parent_id),
561 ) => self.get(x_id).eq(
562 &self.get(curr_parent_id),
563 &PartialEqWithEnginesContext::new(engines),
564 ),
565 _ => false,
566 }) {
567 left_to_check.push_back(curr_parent.clone());
568 }
569 }
570 }
571 }
572 acc_parents.values().cloned().collect()
573 }
574
575 pub(crate) fn register_parent<I>(
576 &self,
577 index: AssociatedItemDeclId,
578 parent: AssociatedItemDeclId,
579 ) where
580 AssociatedItemDeclId: From<DeclId<I>>,
581 {
582 let mut parents = self.parents.write();
583 parents
584 .entry(index)
585 .and_modify(|e| e.push(parent.clone()))
586 .or_insert_with(|| vec![parent]);
587 }
588
589 pub fn get_function<I>(&self, index: &I) -> Arc<ty::TyFunctionDecl>
595 where
596 DeclEngine: DeclEngineGet<I, ty::TyFunctionDecl>,
597 {
598 self.get(index)
599 }
600
601 pub fn get_trait<I>(&self, index: &I) -> Arc<ty::TyTraitDecl>
607 where
608 DeclEngine: DeclEngineGet<I, ty::TyTraitDecl>,
609 {
610 self.get(index)
611 }
612
613 pub fn get_traits_by_name(&self, trait_name: &Ident) -> Vec<ty::TyTraitDecl> {
618 let mut vec = vec![];
619 for trait_decl in self.trait_slab.values() {
620 if trait_decl.name == *trait_name {
621 vec.push((*trait_decl).clone())
622 }
623 }
624 vec
625 }
626
627 pub fn get_trait_fn<I>(&self, index: &I) -> Arc<ty::TyTraitFn>
633 where
634 DeclEngine: DeclEngineGet<I, ty::TyTraitFn>,
635 {
636 self.get(index)
637 }
638
639 pub fn get_impl_self_or_trait<I>(&self, index: &I) -> Arc<ty::TyImplSelfOrTrait>
645 where
646 DeclEngine: DeclEngineGet<I, ty::TyImplSelfOrTrait>,
647 {
648 self.get(index)
649 }
650
651 pub fn get_struct<I>(&self, index: &I) -> Arc<ty::TyStructDecl>
657 where
658 DeclEngine: DeclEngineGet<I, ty::TyStructDecl>,
659 {
660 self.get(index)
661 }
662
663 pub fn get_storage<I>(&self, index: &I) -> Arc<ty::TyStorageDecl>
669 where
670 DeclEngine: DeclEngineGet<I, ty::TyStorageDecl>,
671 {
672 self.get(index)
673 }
674
675 pub fn get_abi<I>(&self, index: &I) -> Arc<ty::TyAbiDecl>
681 where
682 DeclEngine: DeclEngineGet<I, ty::TyAbiDecl>,
683 {
684 self.get(index)
685 }
686
687 pub fn get_constant<I>(&self, index: &I) -> Arc<ty::TyConstantDecl>
693 where
694 DeclEngine: DeclEngineGet<I, ty::TyConstantDecl>,
695 {
696 self.get(index)
697 }
698
699 pub fn get_configurable<I>(&self, index: &I) -> Arc<ty::TyConfigurableDecl>
705 where
706 DeclEngine: DeclEngineGet<I, ty::TyConfigurableDecl>,
707 {
708 self.get(index)
709 }
710
711 pub fn get_const_generic<I>(&self, index: &I) -> Arc<ty::TyConstGenericDecl>
717 where
718 DeclEngine: DeclEngineGet<I, ty::TyConstGenericDecl>,
719 {
720 self.get(index)
721 }
722
723 pub fn get_type<I>(&self, index: &I) -> Arc<ty::TyTraitType>
729 where
730 DeclEngine: DeclEngineGet<I, ty::TyTraitType>,
731 {
732 self.get(index)
733 }
734
735 pub fn get_enum<I>(&self, index: &I) -> Arc<ty::TyEnumDecl>
741 where
742 DeclEngine: DeclEngineGet<I, ty::TyEnumDecl>,
743 {
744 self.get(index)
745 }
746
747 pub fn get_type_alias<I>(&self, index: &I) -> Arc<ty::TyTypeAliasDecl>
753 where
754 DeclEngine: DeclEngineGet<I, ty::TyTypeAliasDecl>,
755 {
756 self.get(index)
757 }
758
759 pub fn pretty_print(&self, engines: &Engines) -> String {
763 let mut builder = String::new();
764 let mut list = String::with_capacity(1024 * 1024);
765 let funcs = self.function_slab.values();
766 for (i, func) in funcs.iter().enumerate() {
767 list.push_str(&format!("{i} - {:?}\n", engines.help_out(func)));
768 }
769 write!(builder, "DeclEngine {{\n{list}\n}}").unwrap();
770 builder
771 }
772}