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