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 enum_parsed_decl_id_map: RwLock<HashMap<DeclId<TyEnumDecl>, ParsedDeclId<EnumDeclaration>>>,
67 type_alias_parsed_decl_id_map:
68 RwLock<HashMap<DeclId<TyTypeAliasDecl>, ParsedDeclId<TypeAliasDeclaration>>>,
69
70 parents: RwLock<HashMap<AssociatedItemDeclId, Vec<AssociatedItemDeclId>>>,
71}
72
73impl Clone for DeclEngine {
74 fn clone(&self) -> Self {
75 DeclEngine {
76 function_slab: self.function_slab.clone(),
77 trait_slab: self.trait_slab.clone(),
78 trait_fn_slab: self.trait_fn_slab.clone(),
79 trait_type_slab: self.trait_type_slab.clone(),
80 impl_self_or_trait_slab: self.impl_self_or_trait_slab.clone(),
81 struct_slab: self.struct_slab.clone(),
82 storage_slab: self.storage_slab.clone(),
83 abi_slab: self.abi_slab.clone(),
84 constant_slab: self.constant_slab.clone(),
85 configurable_slab: self.configurable_slab.clone(),
86 const_generics_slab: self.const_generics_slab.clone(),
87 enum_slab: self.enum_slab.clone(),
88 type_alias_slab: self.type_alias_slab.clone(),
89 function_parsed_decl_id_map: RwLock::new(
90 self.function_parsed_decl_id_map.read().clone(),
91 ),
92 trait_parsed_decl_id_map: RwLock::new(self.trait_parsed_decl_id_map.read().clone()),
93 trait_fn_parsed_decl_id_map: RwLock::new(
94 self.trait_fn_parsed_decl_id_map.read().clone(),
95 ),
96 trait_type_parsed_decl_id_map: RwLock::new(
97 self.trait_type_parsed_decl_id_map.read().clone(),
98 ),
99 impl_self_or_trait_parsed_decl_id_map: RwLock::new(
100 self.impl_self_or_trait_parsed_decl_id_map.read().clone(),
101 ),
102 struct_parsed_decl_id_map: RwLock::new(self.struct_parsed_decl_id_map.read().clone()),
103 storage_parsed_decl_id_map: RwLock::new(self.storage_parsed_decl_id_map.read().clone()),
104 abi_parsed_decl_id_map: RwLock::new(self.abi_parsed_decl_id_map.read().clone()),
105 constant_parsed_decl_id_map: RwLock::new(
106 self.constant_parsed_decl_id_map.read().clone(),
107 ),
108 const_generic_parsed_decl_id_map: RwLock::new(
109 self.const_generic_parsed_decl_id_map.read().clone(),
110 ),
111 configurable_parsed_decl_id_map: RwLock::new(
112 self.configurable_parsed_decl_id_map.read().clone(),
113 ),
114 enum_parsed_decl_id_map: RwLock::new(self.enum_parsed_decl_id_map.read().clone()),
115 type_alias_parsed_decl_id_map: RwLock::new(
116 self.type_alias_parsed_decl_id_map.read().clone(),
117 ),
118 parents: RwLock::new(self.parents.read().clone()),
119 }
120 }
121}
122
123pub trait DeclEngineGet<I, U> {
124 fn get(&self, index: &I) -> Arc<U>;
125 fn map<R>(&self, index: &I, f: impl FnOnce(&U) -> R) -> R;
126}
127
128pub trait DeclEngineGetParsedDeclId<T>
129where
130 T: TyDeclParsedType,
131{
132 fn get_parsed_decl_id(&self, decl_id: &DeclId<T>) -> Option<ParsedDeclId<T::ParsedType>>;
133}
134
135pub trait DeclEngineGetParsedDecl<T>
136where
137 T: TyDeclParsedType,
138{
139 fn get_parsed_decl(&self, decl_id: &DeclId<T>) -> Option<Declaration>;
140}
141
142pub trait DeclEngineInsert<T>
143where
144 T: Named + Spanned + TyDeclParsedType,
145{
146 fn insert(&self, decl: T, parsed_decl_id: ParsedDeclId<T::ParsedType>) -> DeclRef<DeclId<T>>;
152
153 fn insert_modified(&self, modified_decl: T, original_decl: DeclId<T>) -> 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: 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 self.$parsed_slab.write().insert(decl_id, parsed_decl_id);
228 DeclRef::new(decl_name, decl_id, span)
229 }
230
231 fn insert_modified(
232 &self,
233 modified_decl: $decl,
234 original_decl: DeclId<$decl>,
235 ) -> DeclRef<DeclId<$decl>> {
236 self.insert(
237 modified_decl,
238 self.get_parsed_decl_id(&original_decl)
239 .expect("`original_decl` must have a corresponding parsed declaration"),
240 )
241 }
242 }
243 };
244}
245
246impl DeclEngineInsert<ty::TyFunctionDecl> for DeclEngine {
252 fn insert(
253 &self,
254 decl: ty::TyFunctionDecl,
255 parsed_decl_id: ParsedDeclId<<ty::TyFunctionDecl as TyDeclParsedType>::ParsedType>,
256 ) -> DeclRef<DeclId<ty::TyFunctionDecl>> {
257 let span = decl.span();
258 let decl_name = decl.name().clone();
259 let decl_id = DeclId::new(self.function_slab.insert(decl));
260 self.function_parsed_decl_id_map
261 .write()
262 .insert(decl_id, parsed_decl_id);
263 DeclRef::new(decl_name, decl_id, span)
264 }
265
266 fn insert_modified(
267 &self,
268 modified_decl: ty::TyFunctionDecl,
269 original_decl: DeclId<ty::TyFunctionDecl>,
270 ) -> DeclRef<DeclId<ty::TyFunctionDecl>> {
271 match self.get_parsed_decl_id(&original_decl) {
272 Some(parsed_decl_id) => self.insert(modified_decl, parsed_decl_id),
275 None => self.insert_dummy_func(modified_decl),
279 }
280 }
281}
282
283decl_engine_insert!(trait_slab, trait_parsed_decl_id_map, ty::TyTraitDecl);
284decl_engine_insert!(trait_fn_slab, trait_fn_parsed_decl_id_map, ty::TyTraitFn);
285decl_engine_insert!(
286 trait_type_slab,
287 trait_type_parsed_decl_id_map,
288 ty::TyTraitType
289);
290decl_engine_insert!(
291 impl_self_or_trait_slab,
292 impl_self_or_trait_parsed_decl_id_map,
293 ty::TyImplSelfOrTrait
294);
295decl_engine_insert!(struct_slab, struct_parsed_decl_id_map, ty::TyStructDecl);
296decl_engine_insert!(storage_slab, storage_parsed_decl_id_map, ty::TyStorageDecl);
297decl_engine_insert!(abi_slab, abi_parsed_decl_id_map, ty::TyAbiDecl);
298decl_engine_insert!(
299 constant_slab,
300 constant_parsed_decl_id_map,
301 ty::TyConstantDecl
302);
303decl_engine_insert!(
304 configurable_slab,
305 configurable_parsed_decl_id_map,
306 ty::TyConfigurableDecl
307);
308decl_engine_insert!(
309 const_generics_slab,
310 const_generic_parsed_decl_id_map,
311 ty::TyConstGenericDecl
312);
313decl_engine_insert!(enum_slab, enum_parsed_decl_id_map, ty::TyEnumDecl);
314decl_engine_insert!(
315 type_alias_slab,
316 type_alias_parsed_decl_id_map,
317 ty::TyTypeAliasDecl
318);
319
320macro_rules! decl_engine_parsed_decl_id {
321 ($slab:ident, $decl:ty) => {
322 impl DeclEngineGetParsedDeclId<$decl> for DeclEngine {
323 fn get_parsed_decl_id(
324 &self,
325 decl_id: &DeclId<$decl>,
326 ) -> Option<ParsedDeclId<<$decl as TyDeclParsedType>::ParsedType>> {
327 let parsed_decl_id_map = self.$slab.read();
328 if let Some(parsed_decl_id) = parsed_decl_id_map.get(&decl_id) {
329 return Some(parsed_decl_id.clone());
330 } else {
331 None
332 }
333 }
334 }
335 };
336}
337
338decl_engine_parsed_decl_id!(function_parsed_decl_id_map, ty::TyFunctionDecl);
339decl_engine_parsed_decl_id!(trait_parsed_decl_id_map, ty::TyTraitDecl);
340decl_engine_parsed_decl_id!(trait_fn_parsed_decl_id_map, ty::TyTraitFn);
341decl_engine_parsed_decl_id!(trait_type_parsed_decl_id_map, ty::TyTraitType);
342decl_engine_parsed_decl_id!(impl_self_or_trait_parsed_decl_id_map, ty::TyImplSelfOrTrait);
343decl_engine_parsed_decl_id!(struct_parsed_decl_id_map, ty::TyStructDecl);
344decl_engine_parsed_decl_id!(storage_parsed_decl_id_map, ty::TyStorageDecl);
345decl_engine_parsed_decl_id!(abi_parsed_decl_id_map, ty::TyAbiDecl);
346decl_engine_parsed_decl_id!(constant_parsed_decl_id_map, ty::TyConstantDecl);
347decl_engine_parsed_decl_id!(const_generic_parsed_decl_id_map, ty::TyConstGenericDecl);
348decl_engine_parsed_decl_id!(configurable_parsed_decl_id_map, ty::TyConfigurableDecl);
349decl_engine_parsed_decl_id!(enum_parsed_decl_id_map, ty::TyEnumDecl);
350decl_engine_parsed_decl_id!(type_alias_parsed_decl_id_map, ty::TyTypeAliasDecl);
351
352macro_rules! decl_engine_parsed_decl {
353 ($slab:ident, $decl:ty, $ctor:expr) => {
354 impl DeclEngineGetParsedDecl<$decl> for DeclEngine {
355 fn get_parsed_decl(&self, decl_id: &DeclId<$decl>) -> Option<Declaration> {
356 let parsed_decl_id_map = self.$slab.read();
357 if let Some(parsed_decl_id) = parsed_decl_id_map.get(&decl_id) {
358 return Some($ctor(parsed_decl_id.clone()));
359 } else {
360 None
361 }
362 }
363 }
364 };
365}
366
367decl_engine_parsed_decl!(
368 function_parsed_decl_id_map,
369 ty::TyFunctionDecl,
370 Declaration::FunctionDeclaration
371);
372decl_engine_parsed_decl!(
373 trait_parsed_decl_id_map,
374 ty::TyTraitDecl,
375 Declaration::TraitDeclaration
376);
377decl_engine_parsed_decl!(
378 trait_fn_parsed_decl_id_map,
379 ty::TyTraitFn,
380 Declaration::TraitFnDeclaration
381);
382decl_engine_parsed_decl!(
383 trait_type_parsed_decl_id_map,
384 ty::TyTraitType,
385 Declaration::TraitTypeDeclaration
386);
387decl_engine_parsed_decl!(
388 impl_self_or_trait_parsed_decl_id_map,
389 ty::TyImplSelfOrTrait,
390 Declaration::ImplSelfOrTrait
391);
392decl_engine_parsed_decl!(
393 struct_parsed_decl_id_map,
394 ty::TyStructDecl,
395 Declaration::StructDeclaration
396);
397decl_engine_parsed_decl!(
398 storage_parsed_decl_id_map,
399 ty::TyStorageDecl,
400 Declaration::StorageDeclaration
401);
402decl_engine_parsed_decl!(
403 abi_parsed_decl_id_map,
404 ty::TyAbiDecl,
405 Declaration::AbiDeclaration
406);
407decl_engine_parsed_decl!(
408 constant_parsed_decl_id_map,
409 ty::TyConstantDecl,
410 Declaration::ConstantDeclaration
411);
412decl_engine_parsed_decl!(
413 const_generic_parsed_decl_id_map,
414 ty::TyConstGenericDecl,
415 Declaration::ConstGenericDeclaration
416);
417decl_engine_parsed_decl!(
418 configurable_parsed_decl_id_map,
419 ty::TyConfigurableDecl,
420 Declaration::ConfigurableDeclaration
421);
422decl_engine_parsed_decl!(
423 enum_parsed_decl_id_map,
424 ty::TyEnumDecl,
425 Declaration::EnumDeclaration
426);
427decl_engine_parsed_decl!(
428 type_alias_parsed_decl_id_map,
429 ty::TyTypeAliasDecl,
430 Declaration::TypeAliasDeclaration
431);
432
433macro_rules! decl_engine_replace {
434 ($slab:ident, $decl:ty) => {
435 impl DeclEngineReplace<$decl> for DeclEngine {
436 fn replace(&self, index: DeclId<$decl>, decl: $decl) {
437 self.$slab.replace(index.inner(), decl);
438 }
439 }
440 };
441}
442decl_engine_replace!(function_slab, ty::TyFunctionDecl);
443decl_engine_replace!(trait_slab, ty::TyTraitDecl);
444decl_engine_replace!(trait_fn_slab, ty::TyTraitFn);
445decl_engine_replace!(trait_type_slab, ty::TyTraitType);
446decl_engine_replace!(impl_self_or_trait_slab, ty::TyImplSelfOrTrait);
447decl_engine_replace!(struct_slab, ty::TyStructDecl);
448decl_engine_replace!(storage_slab, ty::TyStorageDecl);
449decl_engine_replace!(abi_slab, ty::TyAbiDecl);
450decl_engine_replace!(constant_slab, ty::TyConstantDecl);
451decl_engine_replace!(configurable_slab, ty::TyConfigurableDecl);
452decl_engine_replace!(enum_slab, ty::TyEnumDecl);
453decl_engine_replace!(type_alias_slab, ty::TyTypeAliasDecl);
454
455macro_rules! decl_engine_index {
456 ($slab:ident, $decl:ty) => {
457 impl DeclEngineIndex<$decl> for DeclEngine {}
458 };
459}
460decl_engine_index!(function_slab, ty::TyFunctionDecl);
461decl_engine_index!(trait_slab, ty::TyTraitDecl);
462decl_engine_index!(trait_fn_slab, ty::TyTraitFn);
463decl_engine_index!(trait_type_slab, ty::TyTraitType);
464decl_engine_index!(impl_self_or_trait_slab, ty::TyImplSelfOrTrait);
465decl_engine_index!(struct_slab, ty::TyStructDecl);
466decl_engine_index!(storage_slab, ty::TyStorageDecl);
467decl_engine_index!(abi_slab, ty::TyAbiDecl);
468decl_engine_index!(constant_slab, ty::TyConstantDecl);
469decl_engine_index!(configurable_slab, ty::TyConfigurableDecl);
470decl_engine_index!(enum_slab, ty::TyEnumDecl);
471decl_engine_index!(type_alias_slab, ty::TyTypeAliasDecl);
472
473macro_rules! decl_engine_clear_program {
474 ($($slab:ident, $decl:ty);* $(;)?) => {
475 impl DeclEngine {
476 pub fn clear_program(&mut self, program_id: &ProgramId) {
477 self.parents.write().retain(|key, _| {
478 match key {
479 AssociatedItemDeclId::TraitFn(decl_id) => {
480 self.get_trait_fn(decl_id).span().source_id().map_or(true, |src_id| &src_id.program_id() != program_id)
481 },
482 AssociatedItemDeclId::Function(decl_id) => {
483 self.get_function(decl_id).span().source_id().map_or(true, |src_id| &src_id.program_id() != program_id)
484 },
485 AssociatedItemDeclId::Type(decl_id) => {
486 self.get_type(decl_id).span().source_id().map_or(true, |src_id| &src_id.program_id() != program_id)
487 },
488 AssociatedItemDeclId::Constant(decl_id) => {
489 self.get_constant(decl_id).span().source_id().map_or(true, |src_id| &src_id.program_id() != program_id)
490 },
491 }
492 });
493
494 $(
495 self.$slab.retain(|_k, ty| match ty.span().source_id() {
496 Some(source_id) => &source_id.program_id() != program_id,
497 None => true,
498 });
499 )*
500 }
501 }
502 };
503}
504
505decl_engine_clear_program!(
506 function_slab, ty::TyFunctionDecl;
507 trait_slab, ty::TyTraitDecl;
508 trait_fn_slab, ty::TyTraitFn;
509 trait_type_slab, ty::TyTraitType;
510 impl_self_or_trait_slab, ty::TyImplTrait;
511 struct_slab, ty::TyStructDecl;
512 storage_slab, ty::TyStorageDecl;
513 abi_slab, ty::TyAbiDecl;
514 constant_slab, ty::TyConstantDecl;
515 configurable_slab, ty::TyConfigurableDecl;
516 enum_slab, ty::TyEnumDecl;
517 type_alias_slab, ty::TyTypeAliasDecl;
518);
519
520macro_rules! decl_engine_clear_module {
521 ($($slab:ident, $decl:ty);* $(;)?) => {
522 impl DeclEngine {
523 pub fn clear_module(&mut self, source_id: &SourceId) {
524 self.parents.write().retain(|key, _| {
525 match key {
526 AssociatedItemDeclId::TraitFn(decl_id) => {
527 self.get_trait_fn(decl_id).span().source_id().map_or(true, |src_id| src_id != source_id)
528 },
529 AssociatedItemDeclId::Function(decl_id) => {
530 self.get_function(decl_id).span().source_id().map_or(true, |src_id| src_id != source_id)
531 },
532 AssociatedItemDeclId::Type(decl_id) => {
533 self.get_type(decl_id).span().source_id().map_or(true, |src_id| src_id != source_id)
534 },
535 AssociatedItemDeclId::Constant(decl_id) => {
536 self.get_constant(decl_id).span().source_id().map_or(true, |src_id| src_id != source_id)
537 },
538 }
539 });
540
541 $(
542 self.$slab.retain(|_k, ty| match ty.span().source_id() {
543 Some(src_id) => src_id != source_id,
544 None => true,
545 });
546 )*
547 }
548 }
549 };
550}
551
552decl_engine_clear_module!(
553 function_slab, ty::TyFunctionDecl;
554 trait_slab, ty::TyTraitDecl;
555 trait_fn_slab, ty::TyTraitFn;
556 trait_type_slab, ty::TyTraitType;
557 impl_self_or_trait_slab, ty::TyImplTrait;
558 struct_slab, ty::TyStructDecl;
559 storage_slab, ty::TyStorageDecl;
560 abi_slab, ty::TyAbiDecl;
561 constant_slab, ty::TyConstantDecl;
562 configurable_slab, ty::TyConfigurableDecl;
563 enum_slab, ty::TyEnumDecl;
564 type_alias_slab, ty::TyTypeAliasDecl;
565);
566
567impl DeclEngine {
568 #[allow(clippy::map_entry)]
573 pub(crate) fn find_all_parents<'a, T>(
574 &self,
575 engines: &Engines,
576 index: &'a T,
577 ) -> Vec<AssociatedItemDeclId>
578 where
579 AssociatedItemDeclId: From<&'a T>,
580 {
581 let index: AssociatedItemDeclId = AssociatedItemDeclId::from(index);
582 let parents = self.parents.read();
583 let mut acc_parents: HashMap<AssociatedItemDeclId, AssociatedItemDeclId> = HashMap::new();
584 let mut already_checked: HashSet<AssociatedItemDeclId> = HashSet::new();
585 let mut left_to_check: VecDeque<AssociatedItemDeclId> = VecDeque::from([index]);
586 while let Some(curr) = left_to_check.pop_front() {
587 if !already_checked.insert(curr.clone()) {
588 continue;
589 }
590 if let Some(curr_parents) = parents.get(&curr) {
591 for curr_parent in curr_parents.iter() {
592 if !acc_parents.contains_key(curr_parent) {
593 acc_parents.insert(curr_parent.clone(), curr_parent.clone());
594 }
595 if !left_to_check.iter().any(|x| match (x, curr_parent) {
596 (
597 AssociatedItemDeclId::TraitFn(x_id),
598 AssociatedItemDeclId::TraitFn(curr_parent_id),
599 ) => self.get(x_id).eq(
600 &self.get(curr_parent_id),
601 &PartialEqWithEnginesContext::new(engines),
602 ),
603 (
604 AssociatedItemDeclId::Function(x_id),
605 AssociatedItemDeclId::Function(curr_parent_id),
606 ) => self.get(x_id).eq(
607 &self.get(curr_parent_id),
608 &PartialEqWithEnginesContext::new(engines),
609 ),
610 _ => false,
611 }) {
612 left_to_check.push_back(curr_parent.clone());
613 }
614 }
615 }
616 }
617 acc_parents.values().cloned().collect()
618 }
619
620 pub(crate) fn register_parent<I>(
621 &self,
622 index: AssociatedItemDeclId,
623 parent: AssociatedItemDeclId,
624 ) where
625 AssociatedItemDeclId: From<DeclId<I>>,
626 {
627 let mut parents = self.parents.write();
628 parents
629 .entry(index)
630 .and_modify(|e| e.push(parent.clone()))
631 .or_insert_with(|| vec![parent]);
632 }
633
634 pub fn insert_dummy_func(
653 &self,
654 decl: ty::TyFunctionDecl,
655 ) -> DeclRef<DeclId<ty::TyFunctionDecl>> {
656 assert!(
657 decl.is_trait_method_dummy,
658 "`insert_dummy_func` must only be called with trait-interface dummy functions"
659 );
660 let span = decl.span();
661 let decl_name = decl.name().clone();
662 let decl_id = DeclId::new(self.function_slab.insert(decl));
663 DeclRef::new(decl_name, decl_id, span)
664 }
665
666 pub fn get_function<I>(&self, index: &I) -> Arc<ty::TyFunctionDecl>
672 where
673 DeclEngine: DeclEngineGet<I, ty::TyFunctionDecl>,
674 {
675 self.get(index)
676 }
677
678 pub fn get_trait<I>(&self, index: &I) -> Arc<ty::TyTraitDecl>
684 where
685 DeclEngine: DeclEngineGet<I, ty::TyTraitDecl>,
686 {
687 self.get(index)
688 }
689
690 pub fn get_traits_by_name(&self, trait_name: &Ident) -> Vec<ty::TyTraitDecl> {
695 let mut vec = vec![];
696 for trait_decl in self.trait_slab.values() {
697 if trait_decl.name == *trait_name {
698 vec.push((*trait_decl).clone())
699 }
700 }
701 vec
702 }
703
704 pub fn get_trait_fn<I>(&self, index: &I) -> Arc<ty::TyTraitFn>
710 where
711 DeclEngine: DeclEngineGet<I, ty::TyTraitFn>,
712 {
713 self.get(index)
714 }
715
716 pub fn get_impl_self_or_trait<I>(&self, index: &I) -> Arc<ty::TyImplSelfOrTrait>
722 where
723 DeclEngine: DeclEngineGet<I, ty::TyImplSelfOrTrait>,
724 {
725 self.get(index)
726 }
727
728 pub fn get_struct<I>(&self, index: &I) -> Arc<ty::TyStructDecl>
734 where
735 DeclEngine: DeclEngineGet<I, ty::TyStructDecl>,
736 {
737 self.get(index)
738 }
739
740 pub fn get_storage<I>(&self, index: &I) -> Arc<ty::TyStorageDecl>
746 where
747 DeclEngine: DeclEngineGet<I, ty::TyStorageDecl>,
748 {
749 self.get(index)
750 }
751
752 pub fn get_abi<I>(&self, index: &I) -> Arc<ty::TyAbiDecl>
758 where
759 DeclEngine: DeclEngineGet<I, ty::TyAbiDecl>,
760 {
761 self.get(index)
762 }
763
764 pub fn get_constant<I>(&self, index: &I) -> Arc<ty::TyConstantDecl>
770 where
771 DeclEngine: DeclEngineGet<I, ty::TyConstantDecl>,
772 {
773 self.get(index)
774 }
775
776 pub fn get_configurable<I>(&self, index: &I) -> Arc<ty::TyConfigurableDecl>
782 where
783 DeclEngine: DeclEngineGet<I, ty::TyConfigurableDecl>,
784 {
785 self.get(index)
786 }
787
788 pub fn get_const_generic<I>(&self, index: &I) -> Arc<ty::TyConstGenericDecl>
794 where
795 DeclEngine: DeclEngineGet<I, ty::TyConstGenericDecl>,
796 {
797 self.get(index)
798 }
799
800 pub fn get_type<I>(&self, index: &I) -> Arc<ty::TyTraitType>
806 where
807 DeclEngine: DeclEngineGet<I, ty::TyTraitType>,
808 {
809 self.get(index)
810 }
811
812 pub fn get_enum<I>(&self, index: &I) -> Arc<ty::TyEnumDecl>
818 where
819 DeclEngine: DeclEngineGet<I, ty::TyEnumDecl>,
820 {
821 self.get(index)
822 }
823
824 pub fn get_type_alias<I>(&self, index: &I) -> Arc<ty::TyTypeAliasDecl>
830 where
831 DeclEngine: DeclEngineGet<I, ty::TyTypeAliasDecl>,
832 {
833 self.get(index)
834 }
835
836 pub fn pretty_print(&self, engines: &Engines) -> String {
840 let mut builder = String::new();
841 let mut list = String::with_capacity(1024 * 1024);
842 let funcs = self.function_slab.values();
843 for (i, func) in funcs.iter().enumerate() {
844 list.push_str(&format!("{i} - {:?}\n", engines.help_out(func)));
845 }
846 write!(builder, "DeclEngine {{\n{list}\n}}").unwrap();
847 builder
848 }
849
850 pub fn metrics(&self) -> DeclEngineMetrics {
851 DeclEngineMetrics {
852 slabs: vec![
853 self.function_slab.metrics("function_slab".into()),
854 self.struct_slab.metrics("struct_slab".into()),
855 self.enum_slab.metrics("enum_slab".into()),
856 self.trait_slab.metrics("trait_slab".into()),
857 self.trait_fn_slab.metrics("trait_fn_slab".into()),
858 self.trait_type_slab.metrics("trait_type_slab".into()),
859 self.impl_self_or_trait_slab
860 .metrics("impl_self_or_trait_slab".into()),
861 self.storage_slab.metrics("storage_slab".into()),
862 self.abi_slab.metrics("abi_slab".into()),
863 self.constant_slab.metrics("constant_slab".into()),
864 self.configurable_slab.metrics("configurable_slab".into()),
865 self.const_generics_slab
866 .metrics("const_generics_slab".into()),
867 self.type_alias_slab.metrics("type_alias_slab".into()),
868 ],
869 }
870 }
871}