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