1use std::ops::{Deref, DerefMut};
2use std::sync::Arc;
3
4use cairo_lang_debug::DebugWithDb;
5use cairo_lang_defs::cache::{
6 CacheBlobReader, CrateDefCache, DEF_CACHE_SECTION, DefCacheLoadingData, DefCacheSavingContext,
7 GenericParamCached, GlobalUseIdCached, ImplAliasIdCached, ImplDefIdCached,
8 LanguageElementCached, ModuleDataCached, ModuleIdCached, ModuleItemIdCached,
9 SyntaxStablePtrIdCached,
10};
11use cairo_lang_defs::db::DefsGroup;
12use cairo_lang_defs::diagnostic_utils::StableLocation;
13use cairo_lang_defs::ids::{
14 EnumLongId, ExternFunctionLongId, ExternTypeLongId, FreeFunctionLongId, ImplFunctionLongId,
15 LocalVarId, LocalVarLongId, MemberLongId, ParamId, ParamLongId, StatementConstLongId,
16 StatementItemId, StatementUseLongId, StructLongId, TraitConstantId, TraitConstantLongId,
17 TraitFunctionLongId, TraitImplId, TraitImplLongId, TraitLongId, TraitTypeId, TraitTypeLongId,
18 VarId, VariantLongId,
19};
20use cairo_lang_diagnostics::{Diagnostics, Maybe};
21use cairo_lang_filesystem::db::FilesGroup;
22use cairo_lang_filesystem::ids::CrateId;
23use cairo_lang_syntax::node::TypedStablePtr;
24use cairo_lang_syntax::node::ast::{
25 ExprPtr, FunctionWithBodyPtr, ItemConstantPtr, ItemEnumPtr, ItemExternFunctionPtr,
26 ItemExternTypePtr, ItemStructPtr, ItemTraitPtr, MemberPtr, ParamPtr, TerminalIdentifierPtr,
27 TraitItemConstantPtr, TraitItemFunctionPtr, TraitItemImplPtr, TraitItemTypePtr, UsePathLeafPtr,
28 VariantPtr,
29};
30use cairo_lang_utils::Intern;
31use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
32use cairo_lang_utils::smol_str::SmolStr;
33use num_bigint::BigInt;
34use salsa::Database;
35use serde::{Deserialize, Serialize};
36
37use crate::db::ModuleSemanticDataCacheAndLoadingData;
38use crate::items::constant::{ConstValue, ConstValueId, ImplConstantId};
39use crate::items::feature_kind::FeatureKind;
40use crate::items::functions::{
41 ConcreteFunctionWithBody, GenericFunctionId, GenericFunctionWithBodyId, ImplFunctionBodyId,
42 ImplGenericFunctionId, ImplGenericFunctionWithBodyId,
43};
44use crate::items::generics::{GenericParamConst, GenericParamImpl, GenericParamType};
45use crate::items::imp::{
46 GeneratedImplId, GeneratedImplItems, GeneratedImplLongId, ImplId, ImplImplId, ImplLongId,
47 NegativeImplId, NegativeImplLongId,
48};
49use crate::items::impl_alias::ImplAliasSemantic;
50use crate::items::macro_call::crate_modules_including_generated;
51use crate::items::module::{ModuleItemInfo, ModuleSemantic, ModuleSemanticData};
52use crate::items::trt::ConcreteTraitGenericFunctionLongId;
53use crate::items::visibility::Visibility;
54use crate::types::{
55 ClosureTypeLongId, ConcreteEnumLongId, ConcreteExternTypeLongId, ConcreteStructLongId,
56 ImplTypeId,
57};
58use crate::{
59 ConcreteEnumId, ConcreteExternTypeId, ConcreteFunction, ConcreteFunctionWithBodyId,
60 ConcreteImplId, ConcreteImplLongId, ConcreteStructId, ConcreteTraitId, ConcreteTraitLongId,
61 ConcreteTypeId, ConcreteVariant, ExprVar, ExprVarMemberPath, FunctionId, FunctionLongId,
62 GenericArgumentId, GenericParam, MatchArmSelector, MemberAccessKind, TypeId, TypeLongId,
63 ValueSelectorArm,
64};
65
66type SemanticCache<'db> = (CrateSemanticCache, SemanticCacheLookups);
67
68pub const SEMANTIC_CACHE_SECTION: u8 = DEF_CACHE_SECTION + 1;
69
70pub fn load_cached_crate_modules_semantic<'db>(
72 db: &'db dyn Database,
73 crate_id: CrateId<'db>,
74) -> Option<ModuleSemanticDataCacheAndLoadingData<'db>> {
75 let def_loading_data = db.cached_crate_modules(crate_id)?.1;
76
77 let blob_id = db.crate_config(crate_id)?.cache_file?;
78 let Some(content) = db.blob_content(blob_id) else {
79 return Default::default();
80 };
81
82 let (module_data, semantic_lookups): SemanticCache<'_> =
83 CacheBlobReader::read_section(db, content, SEMANTIC_CACHE_SECTION, crate_id);
84
85 let mut ctx = SemanticCacheLoadingContext::new(db, semantic_lookups, def_loading_data);
86 Some(ModuleSemanticDataCacheAndLoadingData {
87 modules_semantic_data: module_data
88 .modules
89 .into_iter()
90 .map(|(module_id, module_data)| {
91 let module_id = module_id.get_embedded(&ctx.defs_loading_data);
92
93 let module_data = module_data.embed(&mut ctx);
94 (module_id, module_data)
95 })
96 .collect::<OrderedHashMap<_, _>>()
97 .into(),
98 impl_aliases_resolved_impls: module_data
99 .impl_aliases
100 .into_iter()
101 .map(|(impl_alias_id, impl_id)| {
102 let impl_alias_id = impl_alias_id.get_embedded(&ctx.defs_loading_data);
103 let impl_id = impl_id.embed(&mut ctx);
104 (impl_alias_id, impl_id)
105 })
106 .collect::<OrderedHashMap<_, _>>()
107 .into(),
108 loading_data: ctx.data.into(),
109 })
110}
111
112pub fn generate_crate_def_cache<'db>(
114 db: &'db dyn Database,
115 crate_id: cairo_lang_filesystem::ids::CrateId<'db>,
116 ctx: &mut DefCacheSavingContext<'db>,
117) -> Maybe<CrateDefCache<'db>> {
118 Ok(CrateDefCache::new(
119 crate_modules_including_generated(db, crate_id)
120 .into_iter()
121 .map(|module_id| {
122 Ok((
123 ModuleIdCached::new(module_id, ctx),
124 ModuleDataCached::new(db, module_id.module_data(db)?, ctx),
125 ))
126 })
127 .collect::<Maybe<_>>()?,
128 ))
129}
130
131#[derive(Serialize, Deserialize)]
133pub struct CrateSemanticCache {
134 modules: Vec<(ModuleIdCached, ModuleSemanticDataCached)>,
136 impl_aliases: Vec<(ImplAliasIdCached, ImplIdCached)>,
138}
139
140pub fn generate_crate_semantic_cache<'db>(
142 crate_id: CrateId<'db>,
143 ctx: &mut SemanticCacheSavingContext<'db>,
144) -> Maybe<CrateSemanticCache> {
145 let all_modules = crate_modules_including_generated(ctx.db, crate_id);
146
147 let modules_data = all_modules
148 .iter()
149 .map(|module_id| {
150 Ok((
151 ModuleIdCached::new(*module_id, &mut ctx.defs_ctx),
152 ModuleSemanticDataCached::new(
153 ctx.db.priv_module_semantic_data(*module_id)?.clone(),
154 ctx,
155 ),
156 ))
157 })
158 .collect::<Maybe<_>>()?;
159
160 Ok(CrateSemanticCache {
161 modules: modules_data,
162 impl_aliases: all_modules
163 .iter()
164 .flat_map(|id| match ctx.db.module_impl_aliases_ids(*id) {
165 Err(err) => vec![Err(err)],
166 Ok(impl_aliases) => impl_aliases
167 .iter()
168 .map(|id| {
169 Ok((
170 ImplAliasIdCached::new(*id, &mut ctx.defs_ctx),
171 ImplIdCached::new(ctx.db.impl_alias_resolved_impl(*id)?, ctx),
172 ))
173 })
174 .collect::<Vec<_>>(),
175 })
176 .collect::<Maybe<Vec<_>>>()?,
177 })
178}
179
180struct SemanticCacheLoadingContext<'db> {
182 db: &'db dyn Database,
183 data: SemanticCacheLoadingData<'db>,
184}
185
186impl<'db> Deref for SemanticCacheLoadingContext<'db> {
187 type Target = SemanticCacheLoadingData<'db>;
188
189 fn deref(&self) -> &Self::Target {
190 &self.data
191 }
192}
193impl<'db> DerefMut for SemanticCacheLoadingContext<'db> {
194 fn deref_mut(&mut self) -> &mut Self::Target {
195 &mut self.data
196 }
197}
198
199impl<'db> SemanticCacheLoadingContext<'db> {
200 pub fn new(
201 db: &'db dyn Database,
202 lookups: SemanticCacheLookups,
203 defs_loading_data: Arc<DefCacheLoadingData<'db>>,
204 ) -> Self {
205 let mut res = Self { db, data: SemanticCacheLoadingData::new(lookups, defs_loading_data) };
206 res.embed_lookups();
207 res
208 }
209 fn embed_lookups(&mut self) {
210 for id in 0..self.lookups.function_ids_lookup.len() {
211 SemanticFunctionIdCached(id).embed(self);
212 }
213 for id in 0..self.lookups.type_ids_lookup.len() {
214 TypeIdCached(id).embed(self);
215 }
216 for id in 0..self.lookups.impl_ids_lookup.len() {
217 ImplIdCached(id).embed(self);
218 }
219 for id in 0..self.lookups.negative_impl_ids_lookup.len() {
220 NegativeImplIdCached(id).embed(self);
221 }
222 for id in 0..self.lookups.const_value_ids_lookup.len() {
223 ConstValueIdCached(id).embed(self);
224 }
225 }
226}
227
228#[derive(PartialEq, Eq, salsa::Update)]
230pub struct SemanticCacheLoadingData<'db> {
231 pub defs_loading_data: Arc<DefCacheLoadingData<'db>>,
232
233 function_ids: OrderedHashMap<SemanticFunctionIdCached, FunctionId<'db>>,
234 type_ids: OrderedHashMap<TypeIdCached, TypeId<'db>>,
235 impl_ids: OrderedHashMap<ImplIdCached, ImplId<'db>>,
236 negative_impl_ids: OrderedHashMap<NegativeImplIdCached, NegativeImplId<'db>>,
237 const_value_ids: OrderedHashMap<ConstValueIdCached, ConstValueId<'db>>,
238 lookups: SemanticCacheLookups,
239}
240
241impl<'db> SemanticCacheLoadingData<'db> {
242 fn new(
243 lookups: SemanticCacheLookups,
244 defs_loading_data: Arc<DefCacheLoadingData<'db>>,
245 ) -> Self {
246 Self {
247 defs_loading_data,
248 function_ids: OrderedHashMap::default(),
249 type_ids: OrderedHashMap::default(),
250 impl_ids: OrderedHashMap::default(),
251 negative_impl_ids: OrderedHashMap::default(),
252 const_value_ids: OrderedHashMap::default(),
253 lookups,
254 }
255 }
256}
257
258impl<'db> Deref for SemanticCacheLoadingData<'db> {
259 type Target = SemanticCacheLookups;
260
261 fn deref(&self) -> &Self::Target {
262 &self.lookups
263 }
264}
265impl<'db> DerefMut for SemanticCacheLoadingData<'db> {
266 fn deref_mut(&mut self) -> &mut Self::Target {
267 &mut self.lookups
268 }
269}
270
271pub struct SemanticCacheSavingContext<'db> {
273 pub db: &'db dyn Database,
274 pub data: SemanticCacheSavingData<'db>,
275 pub defs_ctx: DefCacheSavingContext<'db>,
276}
277impl<'db> Deref for SemanticCacheSavingContext<'db> {
278 type Target = SemanticCacheSavingData<'db>;
279
280 fn deref(&self) -> &Self::Target {
281 &self.data
282 }
283}
284impl<'db> DerefMut for SemanticCacheSavingContext<'db> {
285 fn deref_mut(&mut self) -> &mut Self::Target {
286 &mut self.data
287 }
288}
289
290#[derive(Default)]
292pub struct SemanticCacheSavingData<'db> {
293 function_ids: OrderedHashMap<FunctionId<'db>, SemanticFunctionIdCached>,
294 type_ids: OrderedHashMap<TypeId<'db>, TypeIdCached>,
295 impl_ids: OrderedHashMap<ImplId<'db>, ImplIdCached>,
296 negative_impl_ids: OrderedHashMap<NegativeImplId<'db>, NegativeImplIdCached>,
297 const_value_ids: OrderedHashMap<ConstValueId<'db>, ConstValueIdCached>,
298 pub lookups: SemanticCacheLookups,
299}
300
301impl<'db> Deref for SemanticCacheSavingData<'db> {
302 type Target = SemanticCacheLookups;
303
304 fn deref(&self) -> &Self::Target {
305 &self.lookups
306 }
307}
308impl<'db> DerefMut for SemanticCacheSavingData<'db> {
309 fn deref_mut(&mut self) -> &mut Self::Target {
310 &mut self.lookups
311 }
312}
313
314#[derive(Serialize, Deserialize, Default, PartialEq, Eq, salsa::Update)]
316pub struct SemanticCacheLookups {
317 function_ids_lookup: Vec<SemanticFunctionCached>,
318 type_ids_lookup: Vec<TypeCached>,
319 impl_ids_lookup: Vec<ImplCached>,
320 negative_impl_ids_lookup: Vec<NegativeImplCached>,
321 const_value_ids_lookup: Vec<ConstValueCached>,
322}
323
324#[derive(Serialize, Deserialize)]
325enum VisibilityCached {
326 Public,
327 PublicInCrate,
328 Private,
329}
330impl VisibilityCached {
331 fn new(visibility: Visibility) -> Self {
332 match visibility {
333 Visibility::Public => VisibilityCached::Public,
334 Visibility::PublicInCrate => VisibilityCached::PublicInCrate,
335 Visibility::Private => VisibilityCached::Private,
336 }
337 }
338 fn embed(self) -> Visibility {
339 match self {
340 VisibilityCached::Public => Visibility::Public,
341 VisibilityCached::PublicInCrate => Visibility::PublicInCrate,
342 VisibilityCached::Private => Visibility::Private,
343 }
344 }
345}
346
347#[derive(Serialize, Deserialize)]
348struct ModuleSemanticDataCached {
349 items: OrderedHashMap<SmolStr, ModuleItemInfoCached>,
350 global_uses: OrderedHashMap<GlobalUseIdCached, VisibilityCached>,
351}
352
353impl ModuleSemanticDataCached {
354 fn new<'db>(
355 module_semantic_data: ModuleSemanticData<'db>,
356 ctx: &mut SemanticCacheSavingContext<'db>,
357 ) -> Self {
358 Self {
359 items: module_semantic_data
360 .items
361 .into_iter()
362 .map(|(item_id, item_info)| {
363 (item_id.long(ctx.db).clone(), ModuleItemInfoCached::new(item_info, ctx))
364 })
365 .collect(),
366 global_uses: module_semantic_data
367 .global_uses
368 .into_iter()
369 .map(|(global_use_id, visibility)| {
370 (
371 GlobalUseIdCached::new(global_use_id, &mut ctx.defs_ctx),
372 VisibilityCached::new(visibility),
373 )
374 })
375 .collect(),
376 }
377 }
378 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ModuleSemanticData<'db> {
379 ModuleSemanticData {
380 items: self
381 .items
382 .into_iter()
383 .map(|(item_id, item_info)| (item_id.intern(ctx.db), item_info.embed(ctx)))
384 .collect(),
385 global_uses: self
386 .global_uses
387 .into_iter()
388 .map(|(global_use_id, visibility)| {
389 (global_use_id.get_embedded(&ctx.defs_loading_data), visibility.embed())
390 })
391 .collect(),
392 diagnostics: Diagnostics::default(),
393 }
394 }
395}
396
397#[derive(Serialize, Deserialize)]
398struct ModuleItemInfoCached {
399 item_id: ModuleItemIdCached,
400 visibility: VisibilityCached,
401 feature_kind: FeatureKindCached,
402}
403
404impl ModuleItemInfoCached {
405 fn new<'db>(
406 module_item_info: ModuleItemInfo<'db>,
407 ctx: &mut SemanticCacheSavingContext<'db>,
408 ) -> Self {
409 Self {
410 item_id: ModuleItemIdCached::new(module_item_info.item_id, &mut ctx.defs_ctx),
411 visibility: VisibilityCached::new(module_item_info.visibility),
412 feature_kind: FeatureKindCached::new(module_item_info.feature_kind, ctx),
413 }
414 }
415 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ModuleItemInfo<'db> {
416 ModuleItemInfo {
417 item_id: self.item_id.get_embedded(&ctx.defs_loading_data),
418 visibility: self.visibility.embed(),
419 feature_kind: self.feature_kind.embed(ctx),
420 }
421 }
422}
423
424#[derive(Serialize, Deserialize)]
426pub enum FeatureKindCached {
427 Stable,
428 Unstable { feature: SmolStr, note: Option<SmolStr> },
429 Deprecated { feature: SmolStr, note: Option<SmolStr> },
430 Internal { feature: SmolStr, note: Option<SmolStr> },
431}
432
433impl FeatureKindCached {
434 fn new<'db>(feature_kind: FeatureKind<'db>, ctx: &mut SemanticCacheSavingContext<'db>) -> Self {
435 match feature_kind {
436 FeatureKind::Stable => FeatureKindCached::Stable,
437 FeatureKind::Unstable { feature, note } => FeatureKindCached::Unstable {
438 feature: feature.long(ctx.db).clone(),
439 note: note.map(|note| note.long(ctx.db).clone()),
440 },
441 FeatureKind::Deprecated { feature, note } => FeatureKindCached::Deprecated {
442 feature: feature.long(ctx.db).clone(),
443 note: note.map(|note| note.long(ctx.db).clone()),
444 },
445 FeatureKind::Internal { feature, note } => FeatureKindCached::Internal {
446 feature: feature.long(ctx.db).clone(),
447 note: note.map(|note| note.long(ctx.db).clone()),
448 },
449 }
450 }
451 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> FeatureKind<'db> {
452 match self {
453 FeatureKindCached::Stable => FeatureKind::Stable,
454 FeatureKindCached::Unstable { feature, note } => FeatureKind::Unstable {
455 feature: feature.intern(ctx.db),
456 note: note.map(|note| note.intern(ctx.db)),
457 },
458 FeatureKindCached::Deprecated { feature, note } => FeatureKind::Deprecated {
459 feature: feature.intern(ctx.db),
460 note: note.map(|note| note.intern(ctx.db)),
461 },
462 FeatureKindCached::Internal { feature, note } => FeatureKind::Internal {
463 feature: feature.intern(ctx.db),
464 note: note.map(|note| note.intern(ctx.db)),
465 },
466 }
467 }
468}
469
470#[derive(Serialize, Deserialize)]
471pub enum MemberAccessKindCached {
472 Struct { concrete_struct_id: ConcreteStructCached, member_id: LanguageElementCached },
473 Index { tuple_ty: TypeIdCached, index: usize },
474}
475impl MemberAccessKindCached {
476 pub fn new<'db>(
477 kind: MemberAccessKind<'db>,
478 ctx: &mut SemanticCacheSavingContext<'db>,
479 ) -> Self {
480 match kind {
481 MemberAccessKind::Struct { concrete_struct_id, member_id } => {
482 MemberAccessKindCached::Struct {
483 concrete_struct_id: ConcreteStructCached::new(concrete_struct_id, ctx),
484 member_id: LanguageElementCached::new(member_id, &mut ctx.defs_ctx),
485 }
486 }
487 MemberAccessKind::Index { tuple_ty, index } => {
488 MemberAccessKindCached::Index { tuple_ty: TypeIdCached::new(tuple_ty, ctx), index }
489 }
490 }
491 }
492 pub fn get_embedded<'db>(
493 self,
494 data: &Arc<SemanticCacheLoadingData<'db>>,
495 db: &'db dyn Database,
496 ) -> MemberAccessKind<'db> {
497 match self {
498 MemberAccessKindCached::Struct { concrete_struct_id, member_id } => {
499 let (module_id, member_stable_ptr) =
500 member_id.get_embedded(&data.defs_loading_data);
501 let member_id = MemberLongId(module_id, MemberPtr(member_stable_ptr)).intern(db);
502 MemberAccessKind::Struct {
503 concrete_struct_id: concrete_struct_id.get_embedded(data, db),
504 member_id,
505 }
506 }
507 MemberAccessKindCached::Index { tuple_ty, index } => {
508 MemberAccessKind::Index { tuple_ty: tuple_ty.get_embedded(data), index }
509 }
510 }
511 }
512}
513
514#[derive(Serialize, Deserialize)]
515pub enum ExprVarMemberPathCached {
516 Var(ExprVarCached),
517 Member {
518 parent: Box<ExprVarMemberPathCached>,
519 kind: MemberAccessKindCached,
520 stable_ptr: SyntaxStablePtrIdCached,
521 ty: TypeIdCached,
522 },
523}
524impl ExprVarMemberPathCached {
525 pub fn new<'db>(
526 expr_var_member_path: ExprVarMemberPath<'db>,
527 ctx: &mut SemanticCacheSavingContext<'db>,
528 ) -> Self {
529 match expr_var_member_path {
530 ExprVarMemberPath::Var(var) => {
531 ExprVarMemberPathCached::Var(ExprVarCached::new(var, ctx))
532 }
533 ExprVarMemberPath::Member { parent, kind, stable_ptr, ty } => {
534 ExprVarMemberPathCached::Member {
535 parent: Box::new(ExprVarMemberPathCached::new(*parent, ctx)),
536 kind: MemberAccessKindCached::new(kind, ctx),
537 stable_ptr: SyntaxStablePtrIdCached::new(
538 stable_ptr.untyped(),
539 &mut ctx.defs_ctx,
540 ),
541 ty: TypeIdCached::new(ty, ctx),
542 }
543 }
544 }
545 }
546 pub fn get_embedded<'db>(
547 self,
548 data: &Arc<SemanticCacheLoadingData<'db>>,
549 db: &'db dyn Database,
550 ) -> ExprVarMemberPath<'db> {
551 match self {
552 ExprVarMemberPathCached::Var(var) => ExprVarMemberPath::Var(var.get_embedded(data, db)),
553 ExprVarMemberPathCached::Member { parent, kind, stable_ptr, ty } => {
554 let parent = Box::new(parent.get_embedded(data, db));
555 ExprVarMemberPath::Member {
556 parent,
557 kind: kind.get_embedded(data, db),
558 stable_ptr: ExprPtr(stable_ptr.get_embedded(&data.defs_loading_data)),
559 ty: ty.get_embedded(data),
560 }
561 }
562 }
563 }
564}
565
566#[derive(Serialize, Deserialize)]
567pub struct ExprVarCached {
568 var: SemanticVarIdCached,
569 ty: TypeIdCached,
570 stable_ptr: SyntaxStablePtrIdCached,
571}
572impl ExprVarCached {
573 fn new<'db>(expr_var: ExprVar<'db>, ctx: &mut SemanticCacheSavingContext<'db>) -> Self {
574 Self {
575 var: SemanticVarIdCached::new(expr_var.var, ctx),
576 ty: TypeIdCached::new(expr_var.ty, ctx),
577 stable_ptr: SyntaxStablePtrIdCached::new(
578 expr_var.stable_ptr.untyped(),
579 &mut ctx.defs_ctx,
580 ),
581 }
582 }
583 pub fn get_embedded<'db>(
584 self,
585 data: &Arc<SemanticCacheLoadingData<'db>>,
586 db: &'db dyn Database,
587 ) -> ExprVar<'db> {
588 ExprVar {
589 var: self.var.get_embedded(data, db),
590 ty: self.ty.get_embedded(data),
591 stable_ptr: ExprPtr(self.stable_ptr.get_embedded(&data.defs_loading_data)),
592 }
593 }
594}
595
596#[derive(Serialize, Deserialize)]
597enum SemanticVarIdCached {
598 Param(SemanticParamIdCached),
599 Local(SemanticLocalVarIdCached),
600 Item(SemanticStatementItemIdCached),
601}
602impl SemanticVarIdCached {
603 fn new<'db>(var_id: VarId<'db>, ctx: &mut SemanticCacheSavingContext<'db>) -> Self {
604 match var_id {
605 VarId::Param(id) => SemanticVarIdCached::Param(SemanticParamIdCached::new(id, ctx)),
606 VarId::Local(id) => SemanticVarIdCached::Local(SemanticLocalVarIdCached::new(id, ctx)),
607 VarId::Item(id) => {
608 SemanticVarIdCached::Item(SemanticStatementItemIdCached::new(id, ctx))
609 }
610 }
611 }
612 pub fn get_embedded<'db>(
613 self,
614 data: &Arc<SemanticCacheLoadingData<'db>>,
615 db: &'db dyn Database,
616 ) -> VarId<'db> {
617 match self {
618 SemanticVarIdCached::Param(id) => VarId::Param(id.get_embedded(data, db)),
619 SemanticVarIdCached::Local(id) => VarId::Local(id.get_embedded(data, db)),
620 SemanticVarIdCached::Item(id) => VarId::Item(id.get_embedded(data, db)),
621 }
622 }
623}
624
625#[derive(Serialize, Deserialize)]
626struct SemanticParamIdCached {
627 language_element: LanguageElementCached,
628}
629impl SemanticParamIdCached {
630 fn new<'db>(param_id: ParamId<'db>, ctx: &mut SemanticCacheSavingContext<'db>) -> Self {
631 Self { language_element: LanguageElementCached::new(param_id, &mut ctx.defs_ctx) }
632 }
633 pub fn get_embedded<'db>(
634 self,
635 data: &Arc<SemanticCacheLoadingData<'db>>,
636 db: &'db dyn Database,
637 ) -> ParamId<'db> {
638 let (module_id, stable_ptr) = self.language_element.get_embedded(&data.defs_loading_data);
639 ParamLongId(module_id, ParamPtr(stable_ptr)).intern(db)
640 }
641}
642
643#[derive(Serialize, Deserialize)]
644struct SemanticLocalVarIdCached {
645 language_element: LanguageElementCached,
646}
647impl SemanticLocalVarIdCached {
648 fn new<'db>(local_var_id: LocalVarId<'db>, ctx: &mut SemanticCacheSavingContext<'db>) -> Self {
649 Self { language_element: LanguageElementCached::new(local_var_id, &mut ctx.defs_ctx) }
650 }
651 pub fn get_embedded<'db>(
652 self,
653 data: &Arc<SemanticCacheLoadingData<'db>>,
654 db: &'db dyn Database,
655 ) -> LocalVarId<'db> {
656 let (module_id, stable_ptr) = self.language_element.get_embedded(&data.defs_loading_data);
657 LocalVarLongId(module_id, TerminalIdentifierPtr(stable_ptr)).intern(db)
658 }
659}
660
661#[derive(Serialize, Deserialize)]
662enum SemanticStatementItemIdCached {
663 Constant(LanguageElementCached),
664 Use(LanguageElementCached),
665}
666
667impl SemanticStatementItemIdCached {
668 fn new<'db>(item_id: StatementItemId<'db>, ctx: &mut SemanticCacheSavingContext<'db>) -> Self {
669 match item_id {
670 StatementItemId::Constant(id) => SemanticStatementItemIdCached::Constant(
671 LanguageElementCached::new(id, &mut ctx.defs_ctx),
672 ),
673 StatementItemId::Use(id) => SemanticStatementItemIdCached::Use(
674 LanguageElementCached::new(id, &mut ctx.defs_ctx),
675 ),
676 }
677 }
678 pub fn get_embedded<'db>(
679 self,
680 data: &Arc<SemanticCacheLoadingData<'db>>,
681 db: &'db dyn Database,
682 ) -> StatementItemId<'db> {
683 match self {
684 SemanticStatementItemIdCached::Constant(id) => {
685 let (module_id, stable_ptr) = id.get_embedded(&data.defs_loading_data);
686 StatementItemId::Constant(
687 StatementConstLongId(module_id, ItemConstantPtr(stable_ptr)).intern(db),
688 )
689 }
690 SemanticStatementItemIdCached::Use(id) => {
691 let (module_id, stable_ptr) = id.get_embedded(&data.defs_loading_data);
692 StatementItemId::Use(
693 StatementUseLongId(module_id, UsePathLeafPtr(stable_ptr)).intern(db),
694 )
695 }
696 }
697 }
698}
699
700#[derive(Serialize, Deserialize)]
701pub enum MatchArmSelectorCached {
702 VariantId(ConcreteVariantCached),
703 Value(usize),
704}
705
706impl MatchArmSelectorCached {
707 pub fn new<'db>(
708 match_arm_selector: MatchArmSelector<'db>,
709 ctx: &mut SemanticCacheSavingContext<'db>,
710 ) -> Self {
711 match match_arm_selector {
712 MatchArmSelector::VariantId(variant_id) => {
713 MatchArmSelectorCached::VariantId(ConcreteVariantCached::new(variant_id, ctx))
714 }
715 MatchArmSelector::Value(value) => MatchArmSelectorCached::Value(value.value),
716 }
717 }
718 pub fn get_embedded<'db>(
719 self,
720 data: &Arc<SemanticCacheLoadingData<'db>>,
721 db: &'db dyn Database,
722 ) -> MatchArmSelector<'db> {
723 match self {
724 MatchArmSelectorCached::VariantId(variant_id) => {
725 MatchArmSelector::VariantId(variant_id.get_embedded(data, db))
726 }
727 MatchArmSelectorCached::Value(value) => {
728 MatchArmSelector::Value(ValueSelectorArm { value })
729 }
730 }
731 }
732}
733
734#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
735enum ConstValueCached {
736 Int(BigInt, TypeIdCached),
737 Struct(Vec<ConstValueIdCached>, TypeIdCached),
738 Enum(ConcreteVariantCached, ConstValueIdCached),
739 NonZero(ConstValueIdCached),
740 Generic(GenericParamCached),
741 ImplConstant(ImplConstantCached),
742}
743impl ConstValueCached {
744 fn new<'db>(const_value: ConstValue<'db>, ctx: &mut SemanticCacheSavingContext<'db>) -> Self {
745 match const_value {
746 ConstValue::Int(value, ty) => ConstValueCached::Int(value, TypeIdCached::new(ty, ctx)),
747 ConstValue::Struct(values, ty) => ConstValueCached::Struct(
748 values.into_iter().map(|v| ConstValueIdCached::new(v, ctx)).collect(),
749 TypeIdCached::new(ty, ctx),
750 ),
751 ConstValue::Enum(variant, value) => ConstValueCached::Enum(
752 ConcreteVariantCached::new(variant, ctx),
753 ConstValueIdCached::new(value, ctx),
754 ),
755 ConstValue::NonZero(value) => {
756 ConstValueCached::NonZero(ConstValueIdCached::new(value, ctx))
757 }
758 ConstValue::Generic(generic_param) => {
759 ConstValueCached::Generic(GenericParamCached::new(generic_param, &mut ctx.defs_ctx))
760 }
761 ConstValue::ImplConstant(impl_constant_id) => {
762 ConstValueCached::ImplConstant(ImplConstantCached::new(impl_constant_id, ctx))
763 }
764 ConstValue::Var(_, _) | ConstValue::Missing(_) => {
765 unreachable!("Const {:#?} is not supported for caching", const_value.debug(ctx.db))
766 }
767 }
768 }
769 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ConstValue<'db> {
770 match self {
771 ConstValueCached::Int(value, ty) => ConstValue::Int(value, ty.embed(ctx)),
772 ConstValueCached::Struct(values, ty) => ConstValue::Struct(
773 values.into_iter().map(|v| v.embed(ctx)).collect(),
774 ty.embed(ctx),
775 ),
776 ConstValueCached::Enum(variant, value) => {
777 ConstValue::Enum(variant.embed(ctx), value.embed(ctx))
778 }
779 ConstValueCached::NonZero(value) => ConstValue::NonZero(value.embed(ctx)),
780 ConstValueCached::Generic(generic_param) => {
781 ConstValue::Generic(generic_param.get_embedded(&ctx.defs_loading_data, ctx.db))
782 }
783 ConstValueCached::ImplConstant(impl_constant_id) => {
784 ConstValue::ImplConstant(impl_constant_id.embed(ctx))
785 }
786 }
787 }
788}
789
790#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
791pub struct ConstValueIdCached(usize);
792
793impl ConstValueIdCached {
794 pub fn new<'db>(
795 const_value_id: ConstValueId<'db>,
796 ctx: &mut SemanticCacheSavingContext<'db>,
797 ) -> Self {
798 if let Some(id) = ctx.const_value_ids.get(&const_value_id) {
799 return *id;
800 }
801 let cached = ConstValueCached::new(const_value_id.long(ctx.db).clone(), ctx);
802 let id = Self(ctx.const_value_ids_lookup.len());
803 ctx.const_value_ids_lookup.push(cached);
804 ctx.const_value_ids.insert(const_value_id, id);
805 id
806 }
807 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ConstValueId<'db> {
808 if let Some(const_value_id) = ctx.const_value_ids.get(&self) {
809 return *const_value_id;
810 }
811
812 let cached = ctx.const_value_ids_lookup[self.0].clone();
813 let id = cached.embed(ctx).intern(ctx.db);
814 ctx.const_value_ids.insert(self, id);
815 id
816 }
817 pub fn get_embedded<'db>(self, data: &Arc<SemanticCacheLoadingData<'db>>) -> ConstValueId<'db> {
818 data.const_value_ids[&self]
819 }
820}
821
822#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
823struct ImplConstantCached {
824 impl_id: ImplIdCached,
825 trait_constant: TraitConstantCached,
826}
827impl ImplConstantCached {
828 fn new<'db>(
829 impl_constant_id: ImplConstantId<'db>,
830 ctx: &mut SemanticCacheSavingContext<'db>,
831 ) -> Self {
832 Self {
833 impl_id: ImplIdCached::new(impl_constant_id.impl_id(), ctx),
834 trait_constant: TraitConstantCached::new(impl_constant_id.trait_constant_id(), ctx),
835 }
836 }
837 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ImplConstantId<'db> {
838 ImplConstantId::new(self.impl_id.embed(ctx), self.trait_constant.embed(ctx), ctx.db)
839 }
840}
841
842#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
843struct TraitConstantCached {
844 language_element: LanguageElementCached,
845}
846impl TraitConstantCached {
847 fn new<'db>(
848 trait_constant_id: TraitConstantId<'db>,
849 ctx: &mut SemanticCacheSavingContext<'db>,
850 ) -> Self {
851 Self { language_element: LanguageElementCached::new(trait_constant_id, &mut ctx.defs_ctx) }
852 }
853 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> TraitConstantId<'db> {
854 let (module_id, stable_ptr) = self.language_element.get_embedded(&ctx.defs_loading_data);
855 TraitConstantLongId(module_id, TraitItemConstantPtr(stable_ptr)).intern(ctx.db)
856 }
857}
858
859#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
860struct SemanticFunctionCached {
861 generic_function: GenericFunctionCached,
862
863 generic_args: Vec<GenericArgumentCached>,
864}
865impl SemanticFunctionCached {
866 fn new<'db>(
867 function_id: FunctionLongId<'db>,
868 ctx: &mut SemanticCacheSavingContext<'db>,
869 ) -> Self {
870 let function = function_id.function;
871 Self {
872 generic_function: GenericFunctionCached::new(function.generic_function, ctx),
873 generic_args: function
874 .generic_args
875 .into_iter()
876 .map(|arg| GenericArgumentCached::new(arg, ctx))
877 .collect(),
878 }
879 }
880 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> FunctionLongId<'db> {
881 FunctionLongId {
882 function: ConcreteFunction {
883 generic_function: self.generic_function.embed(ctx),
884 generic_args: self.generic_args.into_iter().map(|arg| arg.embed(ctx)).collect(),
885 },
886 }
887 }
888}
889#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
890pub struct SemanticFunctionIdCached(usize);
891impl SemanticFunctionIdCached {
892 pub fn new<'db>(
893 function_id: FunctionId<'db>,
894 ctx: &mut SemanticCacheSavingContext<'db>,
895 ) -> Self {
896 if let Some(id) = ctx.function_ids.get(&function_id) {
897 return *id;
898 }
899 let function = SemanticFunctionCached::new(function_id.long(ctx.db).clone(), ctx);
900 let id = SemanticFunctionIdCached(ctx.function_ids_lookup.len());
901 ctx.function_ids_lookup.push(function);
902 ctx.function_ids.insert(function_id, id);
903 id
904 }
905 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> FunctionId<'db> {
906 if let Some(function_id) = ctx.function_ids.get(&self) {
907 return *function_id;
908 }
909
910 let function = ctx.function_ids_lookup[self.0].clone();
911 let function_id = function.embed(ctx).intern(ctx.db);
912 ctx.function_ids.insert(self, function_id);
913 function_id
914 }
915 pub fn get_embedded<'db>(self, data: &Arc<SemanticCacheLoadingData<'db>>) -> FunctionId<'db> {
916 data.function_ids[&self]
917 }
918}
919
920#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
921enum GenericFunctionCached {
922 Free(LanguageElementCached),
923 Extern(LanguageElementCached),
924 Impl(ImplIdCached, LanguageElementCached),
925}
926impl GenericFunctionCached {
927 fn new<'db>(
928 generic_function: GenericFunctionId<'db>,
929 ctx: &mut SemanticCacheSavingContext<'db>,
930 ) -> Self {
931 match generic_function {
932 GenericFunctionId::Free(id) => {
933 GenericFunctionCached::Free(LanguageElementCached::new(id, &mut ctx.defs_ctx))
934 }
935 GenericFunctionId::Extern(id) => {
936 GenericFunctionCached::Extern(LanguageElementCached::new(id, &mut ctx.defs_ctx))
937 }
938 GenericFunctionId::Impl(id) => GenericFunctionCached::Impl(
939 ImplIdCached::new(id.impl_id, ctx),
940 LanguageElementCached::new(id.function, &mut ctx.defs_ctx),
941 ),
942 }
943 }
944 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> GenericFunctionId<'db> {
945 match self {
946 GenericFunctionCached::Free(id) => {
947 let (module_id, stable_ptr) = id.get_embedded(&ctx.defs_loading_data);
948 let id =
949 FreeFunctionLongId(module_id, FunctionWithBodyPtr(stable_ptr)).intern(ctx.db);
950 GenericFunctionId::Free(id)
951 }
952 GenericFunctionCached::Extern(id) => {
953 let (module_id, stable_ptr) = id.get_embedded(&ctx.defs_loading_data);
954 let id = ExternFunctionLongId(module_id, ItemExternFunctionPtr(stable_ptr))
955 .intern(ctx.db);
956 GenericFunctionId::Extern(id)
957 }
958 GenericFunctionCached::Impl(id, name) => {
959 let impl_id = id.embed(ctx);
960 let (module_id, stable_ptr) = name.get_embedded(&ctx.defs_loading_data);
961 let trait_function_id =
962 TraitFunctionLongId(module_id, TraitItemFunctionPtr(stable_ptr)).intern(ctx.db);
963
964 GenericFunctionId::Impl(ImplGenericFunctionId {
965 impl_id,
966 function: trait_function_id,
967 })
968 }
969 }
970 }
971}
972
973#[derive(Serialize, Deserialize, Clone)]
974pub struct SemanticConcreteFunctionWithBodyCached {
975 generic_function: GenericFunctionWithBodyCached,
976 generic_args: Vec<GenericArgumentCached>,
977}
978impl SemanticConcreteFunctionWithBodyCached {
979 pub fn new<'db>(
980 function_id: ConcreteFunctionWithBodyId<'db>,
981 ctx: &mut SemanticCacheSavingContext<'db>,
982 ) -> Self {
983 Self {
984 generic_function: GenericFunctionWithBodyCached::new(
985 function_id.generic_function(ctx.db),
986 ctx,
987 ),
988 generic_args: function_id
989 .long(ctx.db)
990 .generic_args
991 .clone()
992 .into_iter()
993 .map(|arg| GenericArgumentCached::new(arg, ctx))
994 .collect(),
995 }
996 }
997 pub fn get_embedded<'db>(
998 self,
999 data: &Arc<SemanticCacheLoadingData<'db>>,
1000 db: &'db dyn Database,
1001 ) -> ConcreteFunctionWithBodyId<'db> {
1002 let generic_function = self.generic_function.get_embedded(data, db);
1003 let generic_args =
1004 self.generic_args.into_iter().map(|arg| arg.get_embedded(data, db)).collect();
1005 ConcreteFunctionWithBody { generic_function, generic_args }.intern(db)
1006 }
1007}
1008
1009#[derive(Serialize, Deserialize, Clone)]
1010enum GenericFunctionWithBodyCached {
1011 Free(LanguageElementCached),
1012 Impl(ConcreteImplCached, ImplFunctionBodyCached),
1013 Trait(ConcreteTraitCached, LanguageElementCached),
1014}
1015
1016impl GenericFunctionWithBodyCached {
1017 fn new<'db>(
1018 generic_function: GenericFunctionWithBodyId<'db>,
1019 ctx: &mut SemanticCacheSavingContext<'db>,
1020 ) -> Self {
1021 match generic_function {
1022 GenericFunctionWithBodyId::Free(id) => GenericFunctionWithBodyCached::Free(
1023 LanguageElementCached::new(id, &mut ctx.defs_ctx),
1024 ),
1025 GenericFunctionWithBodyId::Impl(id) => GenericFunctionWithBodyCached::Impl(
1026 ConcreteImplCached::new(id.concrete_impl_id, ctx),
1027 ImplFunctionBodyCached::new(id.function_body, ctx),
1028 ),
1029 GenericFunctionWithBodyId::Trait(id) => GenericFunctionWithBodyCached::Trait(
1030 ConcreteTraitCached::new(id.concrete_trait(ctx.db), ctx),
1031 LanguageElementCached::new(id.trait_function(ctx.db), &mut ctx.defs_ctx),
1032 ),
1033 }
1034 }
1035 pub fn get_embedded<'db>(
1036 self,
1037 data: &Arc<SemanticCacheLoadingData<'db>>,
1038 db: &'db dyn Database,
1039 ) -> GenericFunctionWithBodyId<'db> {
1040 match self {
1041 GenericFunctionWithBodyCached::Free(id) => {
1042 let (module_id, stable_ptr) = id.get_embedded(&data.defs_loading_data);
1043 GenericFunctionWithBodyId::Free(
1044 FreeFunctionLongId(module_id, FunctionWithBodyPtr(stable_ptr)).intern(db),
1045 )
1046 }
1047 GenericFunctionWithBodyCached::Impl(id, function_body) => {
1048 GenericFunctionWithBodyId::Impl(ImplGenericFunctionWithBodyId {
1049 concrete_impl_id: id.get_embedded(data, db),
1050 function_body: function_body.get_embedded(data, db),
1051 })
1052 }
1053 GenericFunctionWithBodyCached::Trait(id, name) => {
1054 let (module_id, stable_ptr) = name.get_embedded(&data.defs_loading_data);
1055 GenericFunctionWithBodyId::Trait(
1056 ConcreteTraitGenericFunctionLongId::new(
1057 db,
1058 id.get_embedded(data, db),
1059 TraitFunctionLongId(module_id, TraitItemFunctionPtr(stable_ptr)).intern(db),
1060 )
1061 .intern(db),
1062 )
1063 }
1064 }
1065 }
1066}
1067
1068#[derive(Serialize, Deserialize, Clone)]
1069enum ImplFunctionBodyCached {
1070 Impl(LanguageElementCached),
1071 Trait(LanguageElementCached),
1072}
1073impl ImplFunctionBodyCached {
1074 fn new<'db>(
1075 function_body: ImplFunctionBodyId<'db>,
1076 ctx: &mut SemanticCacheSavingContext<'db>,
1077 ) -> Self {
1078 match function_body {
1079 ImplFunctionBodyId::Impl(id) => {
1080 ImplFunctionBodyCached::Impl(LanguageElementCached::new(id, &mut ctx.defs_ctx))
1081 }
1082 ImplFunctionBodyId::Trait(id) => {
1083 ImplFunctionBodyCached::Trait(LanguageElementCached::new(id, &mut ctx.defs_ctx))
1084 }
1085 }
1086 }
1087 pub fn get_embedded<'db>(
1088 self,
1089 data: &Arc<SemanticCacheLoadingData<'db>>,
1090 db: &'db dyn Database,
1091 ) -> ImplFunctionBodyId<'db> {
1092 match self {
1093 ImplFunctionBodyCached::Impl(id) => {
1094 let (module_id, stable_ptr) = id.get_embedded(&data.defs_loading_data);
1095 ImplFunctionBodyId::Impl(
1096 ImplFunctionLongId(module_id, FunctionWithBodyPtr(stable_ptr)).intern(db),
1097 )
1098 }
1099 ImplFunctionBodyCached::Trait(id) => {
1100 let (module_id, stable_ptr) = id.get_embedded(&data.defs_loading_data);
1101 ImplFunctionBodyId::Trait(
1102 TraitFunctionLongId(module_id, TraitItemFunctionPtr(stable_ptr)).intern(db),
1103 )
1104 }
1105 }
1106 }
1107}
1108
1109#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1110enum GenericArgumentCached {
1111 Type(TypeIdCached),
1112 Value(ConstValueIdCached),
1113 Impl(ImplIdCached),
1114 NegImpl(NegativeImplIdCached),
1115}
1116
1117impl GenericArgumentCached {
1118 fn new<'db>(
1119 generic_argument_id: GenericArgumentId<'db>,
1120 ctx: &mut SemanticCacheSavingContext<'db>,
1121 ) -> Self {
1122 match generic_argument_id {
1123 GenericArgumentId::Type(type_id) => {
1124 GenericArgumentCached::Type(TypeIdCached::new(type_id, ctx))
1125 }
1126 GenericArgumentId::Constant(const_value_id) => {
1127 GenericArgumentCached::Value(ConstValueIdCached::new(const_value_id, ctx))
1128 }
1129 GenericArgumentId::Impl(impl_id) => {
1130 GenericArgumentCached::Impl(ImplIdCached::new(impl_id, ctx))
1131 }
1132 GenericArgumentId::NegImpl(negative_impl) => {
1133 GenericArgumentCached::NegImpl(NegativeImplIdCached::new(negative_impl, ctx))
1134 }
1135 }
1136 }
1137 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> GenericArgumentId<'db> {
1138 match self {
1139 GenericArgumentCached::Type(ty) => GenericArgumentId::Type(ty.embed(ctx)),
1140 GenericArgumentCached::Value(value) => GenericArgumentId::Constant(value.embed(ctx)),
1141 GenericArgumentCached::Impl(imp) => GenericArgumentId::Impl(imp.embed(ctx)),
1142 GenericArgumentCached::NegImpl(negative_impl) => {
1143 GenericArgumentId::NegImpl(negative_impl.embed(ctx))
1144 }
1145 }
1146 }
1147 pub fn get_embedded<'db>(
1148 self,
1149 data: &Arc<SemanticCacheLoadingData<'db>>,
1150 _db: &'db dyn Database,
1151 ) -> GenericArgumentId<'db> {
1152 match self {
1153 GenericArgumentCached::Type(ty) => GenericArgumentId::Type(ty.get_embedded(data)),
1154 GenericArgumentCached::Value(value) => {
1155 GenericArgumentId::Constant(value.get_embedded(data))
1156 }
1157 GenericArgumentCached::Impl(imp) => GenericArgumentId::Impl(imp.get_embedded(data)),
1158 GenericArgumentCached::NegImpl(negative_impl) => {
1159 GenericArgumentId::NegImpl(negative_impl.get_embedded(data))
1160 }
1161 }
1162 }
1163}
1164
1165#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1166enum TypeCached {
1167 Concrete(ConcreteTypeCached),
1168 Tuple(Vec<TypeIdCached>),
1169 Snapshot(TypeIdCached),
1170 GenericParameter(GenericParamCached),
1171 ImplType(ImplTypeCached),
1172 FixedSizeArray(TypeIdCached, ConstValueIdCached),
1173 ClosureType(ClosureTypeCached),
1174 Coupon(SemanticFunctionIdCached),
1175}
1176
1177impl TypeCached {
1178 fn new<'db>(type_id: TypeLongId<'db>, ctx: &mut SemanticCacheSavingContext<'db>) -> Self {
1179 match type_id {
1180 TypeLongId::Concrete(concrete_type_id) => {
1181 TypeCached::Concrete(ConcreteTypeCached::new(concrete_type_id, ctx))
1182 }
1183 TypeLongId::Tuple(vec) => {
1184 TypeCached::Tuple(vec.into_iter().map(|ty| TypeIdCached::new(ty, ctx)).collect())
1185 }
1186 TypeLongId::Snapshot(type_id) => TypeCached::Snapshot(TypeIdCached::new(type_id, ctx)),
1187 TypeLongId::GenericParameter(generic_param_id) => TypeCached::GenericParameter(
1188 GenericParamCached::new(generic_param_id, &mut ctx.defs_ctx),
1189 ),
1190 TypeLongId::ImplType(impl_type_id) => {
1191 TypeCached::ImplType(ImplTypeCached::new(impl_type_id, ctx))
1192 }
1193 TypeLongId::FixedSizeArray { type_id, size } => TypeCached::FixedSizeArray(
1194 TypeIdCached::new(type_id, ctx),
1195 ConstValueIdCached::new(size, ctx),
1196 ),
1197 TypeLongId::Closure(closure_ty) => {
1198 TypeCached::ClosureType(ClosureTypeCached::new(closure_ty, ctx))
1199 }
1200 TypeLongId::Coupon(func_id) => {
1201 TypeCached::Coupon(SemanticFunctionIdCached::new(func_id, ctx))
1202 }
1203 TypeLongId::Var(_) | TypeLongId::NumericLiteral(_) | TypeLongId::Missing(_) => {
1204 unreachable!("type {:?} is not supported for caching", type_id.debug(ctx.db))
1205 }
1206 }
1207 }
1208 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> TypeLongId<'db> {
1209 match self {
1210 TypeCached::Concrete(concrete_type) => TypeLongId::Concrete(concrete_type.embed(ctx)),
1211 TypeCached::Tuple(vec) => {
1212 TypeLongId::Tuple(vec.into_iter().map(|ty| ty.embed(ctx)).collect())
1213 }
1214 TypeCached::Snapshot(type_id) => TypeLongId::Snapshot(type_id.embed(ctx)),
1215 TypeCached::GenericParameter(generic_param) => TypeLongId::GenericParameter(
1216 generic_param.get_embedded(&ctx.defs_loading_data, ctx.db),
1217 ),
1218 TypeCached::ImplType(impl_type) => TypeLongId::ImplType(impl_type.embed(ctx)),
1219 TypeCached::FixedSizeArray(type_id, size) => {
1220 TypeLongId::FixedSizeArray { type_id: type_id.embed(ctx), size: size.embed(ctx) }
1221 }
1222 TypeCached::ClosureType(closure_ty) => TypeLongId::Closure(closure_ty.embed(ctx)),
1223 TypeCached::Coupon(coupon) => TypeLongId::Coupon(coupon.embed(ctx)),
1224 }
1225 }
1226}
1227
1228#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1229pub struct TypeIdCached(usize);
1230
1231impl TypeIdCached {
1232 pub fn new<'db>(ty: TypeId<'db>, ctx: &mut SemanticCacheSavingContext<'db>) -> Self {
1233 if let Some(id) = ctx.type_ids.get(&ty) {
1234 return *id;
1235 }
1236 let ty_long = TypeCached::new(ty.long(ctx.db).clone(), ctx);
1237 let id = TypeIdCached(ctx.type_ids_lookup.len());
1238 ctx.type_ids_lookup.push(ty_long);
1239 ctx.type_ids.insert(ty, id);
1240 id
1241 }
1242 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> TypeId<'db> {
1243 if let Some(type_id) = ctx.type_ids.get(&self) {
1244 return *type_id;
1245 }
1246
1247 let ty = ctx.type_ids_lookup[self.0].clone();
1248 let ty = ty.embed(ctx).intern(ctx.db);
1249 ctx.type_ids.insert(self, ty);
1250 ty
1251 }
1252 pub fn get_embedded<'db>(self, data: &Arc<SemanticCacheLoadingData<'db>>) -> TypeId<'db> {
1253 data.type_ids[&self]
1254 }
1255}
1256
1257#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1258enum ConcreteTypeCached {
1259 Struct(ConcreteStructCached),
1260 Enum(ConcreteEnumCached),
1261 Extern(ConcreteExternTypeCached),
1262}
1263
1264impl ConcreteTypeCached {
1265 fn new<'db>(
1266 concrete_type_id: ConcreteTypeId<'db>,
1267 ctx: &mut SemanticCacheSavingContext<'db>,
1268 ) -> Self {
1269 match concrete_type_id {
1270 ConcreteTypeId::Struct(id) => {
1271 ConcreteTypeCached::Struct(ConcreteStructCached::new(id, ctx))
1272 }
1273 ConcreteTypeId::Enum(id) => ConcreteTypeCached::Enum(ConcreteEnumCached::new(id, ctx)),
1274 ConcreteTypeId::Extern(id) => {
1275 ConcreteTypeCached::Extern(ConcreteExternTypeCached::new(id, ctx))
1276 }
1277 }
1278 }
1279 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ConcreteTypeId<'db> {
1280 match self {
1281 ConcreteTypeCached::Struct(s) => ConcreteTypeId::Struct(s.embed(ctx)),
1282 ConcreteTypeCached::Enum(e) => ConcreteTypeId::Enum(e.embed(ctx)),
1283 ConcreteTypeCached::Extern(e) => ConcreteTypeId::Extern(e.embed(ctx)),
1284 }
1285 }
1286}
1287
1288#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1289struct ImplTypeCached {
1290 impl_id: ImplIdCached,
1291 trait_type: TraitTypeCached,
1292}
1293impl ImplTypeCached {
1294 fn new<'db>(impl_type_id: ImplTypeId<'db>, ctx: &mut SemanticCacheSavingContext<'db>) -> Self {
1295 Self {
1296 impl_id: ImplIdCached::new(impl_type_id.impl_id(), ctx),
1297 trait_type: TraitTypeCached::new(impl_type_id.ty(), ctx),
1298 }
1299 }
1300 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ImplTypeId<'db> {
1301 let impl_id = self.impl_id.embed(ctx);
1302 let ty = self.trait_type.embed(ctx);
1303 ImplTypeId::new(impl_id, ty, ctx.db)
1304 }
1305}
1306#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1307struct ClosureTypeCached {
1308 param_tys: Vec<TypeIdCached>,
1309 ret_ty: TypeIdCached,
1310 captured_types: Vec<TypeIdCached>,
1311 parent_function: SemanticFunctionIdCached,
1312 params_location: SyntaxStablePtrIdCached,
1313}
1314
1315impl ClosureTypeCached {
1316 fn new<'db>(
1317 closure_type_id: ClosureTypeLongId<'db>,
1318 ctx: &mut SemanticCacheSavingContext<'db>,
1319 ) -> Self {
1320 Self {
1321 param_tys: closure_type_id
1322 .param_tys
1323 .iter()
1324 .map(|ty| TypeIdCached::new(*ty, ctx))
1325 .collect(),
1326 ret_ty: TypeIdCached::new(closure_type_id.ret_ty, ctx),
1327 captured_types: closure_type_id
1328 .captured_types
1329 .iter()
1330 .map(|ty| TypeIdCached::new(*ty, ctx))
1331 .collect(),
1332 parent_function: SemanticFunctionIdCached::new(
1333 closure_type_id.parent_function.unwrap(),
1334 ctx,
1335 ),
1336 params_location: SyntaxStablePtrIdCached::new(
1337 closure_type_id.params_location.stable_ptr(),
1338 &mut ctx.defs_ctx,
1339 ),
1340 }
1341 }
1342 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ClosureTypeLongId<'db> {
1343 ClosureTypeLongId {
1344 param_tys: self.param_tys.into_iter().map(|ty| ty.embed(ctx)).collect(),
1345 ret_ty: self.ret_ty.embed(ctx),
1346 captured_types: self.captured_types.into_iter().map(|ty| ty.embed(ctx)).collect(),
1347 parent_function: Ok(self.parent_function.embed(ctx)),
1348 params_location: StableLocation::new(
1349 self.params_location.get_embedded(&ctx.defs_loading_data),
1350 ),
1351 }
1352 }
1353}
1354
1355#[derive(Serialize, Deserialize, Clone, Hash, PartialEq, Eq)]
1356struct TraitTypeCached {
1357 language_element: LanguageElementCached,
1358}
1359impl TraitTypeCached {
1360 fn new<'db>(
1361 trait_type_id: TraitTypeId<'db>,
1362 ctx: &mut SemanticCacheSavingContext<'db>,
1363 ) -> Self {
1364 Self { language_element: LanguageElementCached::new(trait_type_id, &mut ctx.defs_ctx) }
1365 }
1366 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> TraitTypeId<'db> {
1367 let (module_id, stable_ptr) = self.language_element.get_embedded(&ctx.defs_loading_data);
1368 TraitTypeLongId(module_id, TraitItemTypePtr(stable_ptr)).intern(ctx.db)
1369 }
1370}
1371
1372#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1373enum ImplCached {
1374 Concrete(ConcreteImplCached),
1375 GenericParameter(GenericParamCached),
1376 ImplImpl(ImplImplCached),
1377 GeneratedImpl(GeneratedImplCached),
1378 SelfImpl(ConcreteTraitCached),
1379}
1380impl ImplCached {
1381 fn new<'db>(impl_id: ImplLongId<'db>, ctx: &mut SemanticCacheSavingContext<'db>) -> Self {
1382 match impl_id {
1383 ImplLongId::Concrete(concrete_impl) => {
1384 ImplCached::Concrete(ConcreteImplCached::new(concrete_impl, ctx))
1385 }
1386 ImplLongId::GenericParameter(generic_param_id) => ImplCached::GenericParameter(
1387 GenericParamCached::new(generic_param_id, &mut ctx.defs_ctx),
1388 ),
1389 ImplLongId::GeneratedImpl(generated_impl) => {
1390 ImplCached::GeneratedImpl(GeneratedImplCached::new(generated_impl, ctx))
1391 }
1392 ImplLongId::ImplImpl(impl_impl) => {
1393 ImplCached::ImplImpl(ImplImplCached::new(impl_impl, ctx))
1394 }
1395 ImplLongId::SelfImpl(concrete_trait) => {
1396 ImplCached::SelfImpl(ConcreteTraitCached::new(concrete_trait, ctx))
1397 }
1398 ImplLongId::ImplVar(_) => {
1399 unreachable!("impl {:?} is not supported for caching", impl_id.debug(ctx.db))
1400 }
1401 }
1402 }
1403 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ImplLongId<'db> {
1404 match self {
1405 ImplCached::Concrete(concrete_impl) => ImplLongId::Concrete(concrete_impl.embed(ctx)),
1406 ImplCached::ImplImpl(impl_impl) => ImplLongId::ImplImpl(impl_impl.embed(ctx)),
1407 ImplCached::GenericParameter(generic_param) => ImplLongId::GenericParameter(
1408 generic_param.get_embedded(&ctx.defs_loading_data, ctx.db),
1409 ),
1410 ImplCached::GeneratedImpl(generated_impl) => {
1411 ImplLongId::GeneratedImpl(generated_impl.embed(ctx))
1412 }
1413 ImplCached::SelfImpl(concrete_trait) => ImplLongId::SelfImpl(concrete_trait.embed(ctx)),
1414 }
1415 }
1416}
1417#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1418pub struct ImplIdCached(usize);
1419
1420impl ImplIdCached {
1421 pub fn new<'db>(impl_id: ImplId<'db>, ctx: &mut SemanticCacheSavingContext<'db>) -> Self {
1422 if let Some(id) = ctx.impl_ids.get(&impl_id) {
1423 return *id;
1424 }
1425 let imp = ImplCached::new(impl_id.long(ctx.db).clone(), ctx);
1426 let id = ImplIdCached(ctx.impl_ids_lookup.len());
1427 ctx.impl_ids_lookup.push(imp);
1428 ctx.impl_ids.insert(impl_id, id);
1429 id
1430 }
1431 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ImplId<'db> {
1432 if let Some(impl_id) = ctx.impl_ids.get(&self) {
1433 return *impl_id;
1434 }
1435
1436 let imp = ctx.impl_ids_lookup[self.0].clone();
1437 let imp = imp.embed(ctx).intern(ctx.db);
1438 ctx.impl_ids.insert(self, imp);
1439 imp
1440 }
1441 pub fn get_embedded<'db>(self, data: &Arc<SemanticCacheLoadingData<'db>>) -> ImplId<'db> {
1442 data.impl_ids[&self]
1443 }
1444}
1445
1446#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1447struct ConcreteImplCached {
1448 impl_def_id: ImplDefIdCached,
1449 generic_args: Vec<GenericArgumentCached>,
1450}
1451impl ConcreteImplCached {
1452 fn new<'db>(
1453 concrete_impl: ConcreteImplId<'db>,
1454 ctx: &mut SemanticCacheSavingContext<'db>,
1455 ) -> Self {
1456 let long_id = concrete_impl.long(ctx.db);
1457 Self {
1458 impl_def_id: ImplDefIdCached::new(long_id.impl_def_id, &mut ctx.defs_ctx),
1459 generic_args: long_id
1460 .generic_args
1461 .clone()
1462 .into_iter()
1463 .map(|arg| GenericArgumentCached::new(arg, ctx))
1464 .collect(),
1465 }
1466 }
1467 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ConcreteImplId<'db> {
1468 let impl_def_id = self.impl_def_id.get_embedded(&ctx.defs_loading_data);
1469 let long_id = ConcreteImplLongId {
1470 impl_def_id,
1471 generic_args: self.generic_args.into_iter().map(|arg| arg.embed(ctx)).collect(),
1472 };
1473 long_id.intern(ctx.db)
1474 }
1475 pub fn get_embedded<'db>(
1476 self,
1477 data: &Arc<SemanticCacheLoadingData<'db>>,
1478 db: &'db dyn Database,
1479 ) -> ConcreteImplId<'db> {
1480 let impl_def_id = self.impl_def_id.get_embedded(&data.defs_loading_data);
1481 let long_id = ConcreteImplLongId {
1482 impl_def_id,
1483 generic_args: self
1484 .generic_args
1485 .into_iter()
1486 .map(|arg| arg.get_embedded(data, db))
1487 .collect(),
1488 };
1489 long_id.intern(db)
1490 }
1491}
1492
1493#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1494struct ImplImplCached {
1495 impl_id: ImplIdCached,
1496 trait_impl_id: TraitImplCached,
1497}
1498impl ImplImplCached {
1499 fn new<'db>(impl_impl_id: ImplImplId<'db>, ctx: &mut SemanticCacheSavingContext<'db>) -> Self {
1500 Self {
1501 impl_id: ImplIdCached::new(impl_impl_id.impl_id(), ctx),
1502 trait_impl_id: TraitImplCached::new(impl_impl_id.trait_impl_id(), ctx),
1503 }
1504 }
1505 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ImplImplId<'db> {
1506 let impl_id = self.impl_id.embed(ctx);
1507 let trait_impl_id = self.trait_impl_id.embed(ctx);
1508 ImplImplId::new(impl_id, trait_impl_id, ctx.db)
1509 }
1510}
1511
1512#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1513struct TraitImplCached {
1514 language_element: LanguageElementCached,
1515}
1516impl TraitImplCached {
1517 fn new<'db>(
1518 trait_impl_id: TraitImplId<'db>,
1519 ctx: &mut SemanticCacheSavingContext<'db>,
1520 ) -> Self {
1521 Self { language_element: LanguageElementCached::new(trait_impl_id, &mut ctx.defs_ctx) }
1522 }
1523 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> TraitImplId<'db> {
1524 let (module_id, stable_ptr) = self.language_element.get_embedded(&ctx.defs_loading_data);
1525 TraitImplLongId(module_id, TraitItemImplPtr(stable_ptr)).intern(ctx.db)
1526 }
1527}
1528
1529#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1530struct GeneratedImplCached {
1531 pub concrete_trait: ConcreteTraitCached,
1532 pub generic_params: Vec<SemanticGenericParamCached>,
1533 pub impl_items: OrderedHashMap<TraitTypeCached, TypeIdCached>,
1534}
1535impl GeneratedImplCached {
1536 fn new<'db>(
1537 generated_impl: GeneratedImplId<'db>,
1538 ctx: &mut SemanticCacheSavingContext<'db>,
1539 ) -> Self {
1540 let generated_impl = generated_impl.long(ctx.db);
1541 Self {
1542 concrete_trait: ConcreteTraitCached::new(generated_impl.concrete_trait, ctx),
1543 generic_params: generated_impl
1544 .generic_params
1545 .clone()
1546 .into_iter()
1547 .map(|param| SemanticGenericParamCached::new(param, ctx))
1548 .collect(),
1549 impl_items: generated_impl
1550 .impl_items
1551 .0
1552 .clone()
1553 .into_iter()
1554 .map(|(k, v)| (TraitTypeCached::new(k, ctx), TypeIdCached::new(v, ctx)))
1555 .collect(),
1556 }
1557 }
1558 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> GeneratedImplId<'db> {
1559 GeneratedImplLongId {
1560 concrete_trait: self.concrete_trait.embed(ctx),
1561 generic_params: self.generic_params.into_iter().map(|param| param.embed(ctx)).collect(),
1562 impl_items: GeneratedImplItems(
1563 self.impl_items.into_iter().map(|(k, v)| (k.embed(ctx), v.embed(ctx))).collect(),
1564 ),
1565 }
1566 .intern(ctx.db)
1567 }
1568}
1569
1570#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1571enum NegativeImplCached {
1572 Solved(ConcreteTraitCached),
1573 GenericParameter(GenericParamCached),
1574}
1575impl NegativeImplCached {
1576 fn new<'db>(
1577 negative_impl_id: NegativeImplLongId<'db>,
1578 ctx: &mut SemanticCacheSavingContext<'db>,
1579 ) -> Self {
1580 match negative_impl_id {
1581 NegativeImplLongId::Solved(concrete_trait_id) => {
1582 NegativeImplCached::Solved(ConcreteTraitCached::new(concrete_trait_id, ctx))
1583 }
1584 NegativeImplLongId::GenericParameter(generic_param_id) => {
1585 NegativeImplCached::GenericParameter(GenericParamCached::new(
1586 generic_param_id,
1587 &mut ctx.defs_ctx,
1588 ))
1589 }
1590 NegativeImplLongId::NegativeImplVar(_) => {
1591 unreachable!("negative impl var is not supported for caching",)
1592 }
1593 }
1594 }
1595 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> NegativeImplLongId<'db> {
1596 match self {
1597 NegativeImplCached::Solved(concrete_trait) => {
1598 NegativeImplLongId::Solved(concrete_trait.embed(ctx))
1599 }
1600 NegativeImplCached::GenericParameter(generic_param) => {
1601 NegativeImplLongId::GenericParameter(
1602 generic_param.get_embedded(&ctx.defs_loading_data, ctx.db),
1603 )
1604 }
1605 }
1606 }
1607}
1608
1609#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1610struct NegativeImplIdCached(usize);
1611
1612impl NegativeImplIdCached {
1613 fn new<'db>(
1614 negative_impl_id: NegativeImplId<'db>,
1615 ctx: &mut SemanticCacheSavingContext<'db>,
1616 ) -> Self {
1617 if let Some(id) = ctx.negative_impl_ids.get(&negative_impl_id) {
1618 return *id;
1619 }
1620 let imp = NegativeImplCached::new(negative_impl_id.long(ctx.db).clone(), ctx);
1621 let id = NegativeImplIdCached(ctx.negative_impl_ids_lookup.len());
1622 ctx.negative_impl_ids_lookup.push(imp);
1623 ctx.negative_impl_ids.insert(negative_impl_id, id);
1624 id
1625 }
1626 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> NegativeImplId<'db> {
1627 if let Some(negative_impl_id) = ctx.negative_impl_ids.get(&self) {
1628 return *negative_impl_id;
1629 }
1630
1631 let imp = ctx.negative_impl_ids_lookup[self.0].clone();
1632 let imp = imp.embed(ctx).intern(ctx.db);
1633 ctx.negative_impl_ids.insert(self, imp);
1634 imp
1635 }
1636 pub fn get_embedded<'db>(
1637 self,
1638 data: &Arc<SemanticCacheLoadingData<'db>>,
1639 ) -> NegativeImplId<'db> {
1640 data.negative_impl_ids[&self]
1641 }
1642}
1643
1644#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1645enum SemanticGenericParamCached {
1646 Type(GenericParamTypeCached),
1647 Const(GenericParamConstCached),
1648 Impl(GenericParamImplCached),
1649 NegImpl(GenericParamImplCached),
1650}
1651impl SemanticGenericParamCached {
1652 fn new<'db>(
1653 generic_param_id: GenericParam<'db>,
1654 ctx: &mut SemanticCacheSavingContext<'db>,
1655 ) -> Self {
1656 match generic_param_id {
1657 GenericParam::Type(generic_param) => {
1658 SemanticGenericParamCached::Type(GenericParamTypeCached::new(generic_param, ctx))
1659 }
1660 GenericParam::Const(generic_param) => {
1661 SemanticGenericParamCached::Const(GenericParamConstCached::new(generic_param, ctx))
1662 }
1663 GenericParam::Impl(generic_param) => {
1664 SemanticGenericParamCached::Impl(GenericParamImplCached::new(generic_param, ctx))
1665 }
1666 GenericParam::NegImpl(generic_param) => {
1667 SemanticGenericParamCached::NegImpl(GenericParamImplCached::new(generic_param, ctx))
1668 }
1669 }
1670 }
1671 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> GenericParam<'db> {
1672 match self {
1673 SemanticGenericParamCached::Type(generic_param) => {
1674 GenericParam::Type(generic_param.embed(ctx))
1675 }
1676 SemanticGenericParamCached::Const(generic_param) => {
1677 GenericParam::Const(generic_param.embed(ctx))
1678 }
1679 SemanticGenericParamCached::Impl(generic_param) => {
1680 GenericParam::Impl(generic_param.embed(ctx))
1681 }
1682 SemanticGenericParamCached::NegImpl(generic_param) => {
1683 GenericParam::NegImpl(generic_param.embed(ctx))
1684 }
1685 }
1686 }
1687}
1688
1689#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1690struct GenericParamTypeCached {
1691 id: GenericParamCached,
1692}
1693
1694impl GenericParamTypeCached {
1695 fn new<'db>(
1696 generic_param: GenericParamType<'db>,
1697 ctx: &mut SemanticCacheSavingContext<'db>,
1698 ) -> Self {
1699 Self { id: GenericParamCached::new(generic_param.id, &mut ctx.defs_ctx) }
1700 }
1701 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> GenericParamType<'db> {
1702 GenericParamType { id: self.id.get_embedded(&ctx.defs_loading_data, ctx.db) }
1703 }
1704}
1705
1706#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1707struct GenericParamConstCached {
1708 id: GenericParamCached,
1709 ty: TypeIdCached,
1710}
1711
1712impl GenericParamConstCached {
1713 fn new<'db>(
1714 generic_param: GenericParamConst<'db>,
1715 ctx: &mut SemanticCacheSavingContext<'db>,
1716 ) -> Self {
1717 Self {
1718 id: GenericParamCached::new(generic_param.id, &mut ctx.defs_ctx),
1719 ty: TypeIdCached::new(generic_param.ty, ctx),
1720 }
1721 }
1722 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> GenericParamConst<'db> {
1723 GenericParamConst {
1724 id: self.id.get_embedded(&ctx.defs_loading_data, ctx.db),
1725 ty: self.ty.embed(ctx),
1726 }
1727 }
1728}
1729
1730#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1731struct GenericParamImplCached {
1732 id: GenericParamCached,
1733 concrete_trait: ConcreteTraitCached,
1734 type_constraints: OrderedHashMap<TraitTypeCached, TypeIdCached>,
1735}
1736
1737impl GenericParamImplCached {
1738 fn new<'db>(
1739 generic_param: GenericParamImpl<'db>,
1740 ctx: &mut SemanticCacheSavingContext<'db>,
1741 ) -> Self {
1742 Self {
1743 id: GenericParamCached::new(generic_param.id, &mut ctx.defs_ctx),
1744 concrete_trait: ConcreteTraitCached::new(generic_param.concrete_trait.unwrap(), ctx),
1745
1746 type_constraints: generic_param
1747 .type_constraints
1748 .into_iter()
1749 .map(|(k, v)| (TraitTypeCached::new(k, ctx), TypeIdCached::new(v, ctx)))
1750 .collect(),
1751 }
1752 }
1753 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> GenericParamImpl<'db> {
1754 GenericParamImpl {
1755 id: self.id.get_embedded(&ctx.defs_loading_data, ctx.db),
1756 concrete_trait: Ok(self.concrete_trait.embed(ctx)),
1757 type_constraints: self
1758 .type_constraints
1759 .into_iter()
1760 .map(|(k, v)| (k.embed(ctx), v.embed(ctx)))
1761 .collect(),
1762 }
1763 }
1764}
1765
1766#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1767pub struct ConcreteVariantCached {
1768 concrete_enum_id: ConcreteEnumCached,
1769 id: LanguageElementCached,
1770 ty: TypeIdCached,
1771 idx: usize,
1772}
1773impl ConcreteVariantCached {
1774 pub fn new<'db>(
1775 concrete_variant: ConcreteVariant<'db>,
1776 ctx: &mut SemanticCacheSavingContext<'db>,
1777 ) -> Self {
1778 Self {
1779 concrete_enum_id: ConcreteEnumCached::new(concrete_variant.concrete_enum_id, ctx),
1780 id: LanguageElementCached::new(concrete_variant.id, &mut ctx.defs_ctx),
1781 ty: TypeIdCached::new(concrete_variant.ty, ctx),
1782 idx: concrete_variant.idx,
1783 }
1784 }
1785 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ConcreteVariant<'db> {
1786 let concrete_enum_id = self.concrete_enum_id.embed(ctx);
1787 let ty = self.ty.embed(ctx);
1788 let (module_id, stable_ptr) = self.id.get_embedded(&ctx.defs_loading_data);
1789
1790 let id = VariantLongId(module_id, VariantPtr(stable_ptr)).intern(ctx.db);
1791 ConcreteVariant { concrete_enum_id, id, ty, idx: self.idx }
1792 }
1793 pub fn get_embedded<'db>(
1794 self,
1795 data: &Arc<SemanticCacheLoadingData<'db>>,
1796 db: &'db dyn Database,
1797 ) -> ConcreteVariant<'db> {
1798 let concrete_enum_id = self.concrete_enum_id.get_embedded(data, db);
1799 let ty = self.ty.get_embedded(data);
1800 let (module_id, stable_ptr) = self.id.get_embedded(&data.defs_loading_data);
1801 let id = VariantLongId(module_id, VariantPtr(stable_ptr)).intern(db);
1802 ConcreteVariant { concrete_enum_id, id, ty, idx: self.idx }
1803 }
1804}
1805
1806#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1807pub struct ConcreteEnumCached {
1808 enum_id: LanguageElementCached,
1809 generic_args: Vec<GenericArgumentCached>,
1810}
1811
1812impl ConcreteEnumCached {
1813 pub fn new<'db>(
1814 concrete_enum: ConcreteEnumId<'db>,
1815 ctx: &mut SemanticCacheSavingContext<'db>,
1816 ) -> Self {
1817 let long_id = concrete_enum.long(ctx.db);
1818 Self {
1819 enum_id: LanguageElementCached::new(long_id.enum_id, &mut ctx.defs_ctx),
1820 generic_args: long_id
1821 .generic_args
1822 .clone()
1823 .into_iter()
1824 .map(|arg| GenericArgumentCached::new(arg, ctx))
1825 .collect(),
1826 }
1827 }
1828 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ConcreteEnumId<'db> {
1829 let (module_id, stable_ptr) = self.enum_id.get_embedded(&ctx.defs_loading_data);
1830
1831 let long_id = ConcreteEnumLongId {
1832 enum_id: EnumLongId(module_id, ItemEnumPtr(stable_ptr)).intern(ctx.db),
1833 generic_args: self.generic_args.into_iter().map(|arg| arg.embed(ctx)).collect(),
1834 };
1835 long_id.intern(ctx.db)
1836 }
1837 pub fn get_embedded<'db>(
1838 self,
1839 data: &Arc<SemanticCacheLoadingData<'db>>,
1840 db: &'db dyn Database,
1841 ) -> ConcreteEnumId<'db> {
1842 let (module_id, stable_ptr) = self.enum_id.get_embedded(&data.defs_loading_data);
1843 let id = EnumLongId(module_id, ItemEnumPtr(stable_ptr)).intern(db);
1844 ConcreteEnumLongId {
1845 enum_id: id,
1846 generic_args: self
1847 .generic_args
1848 .into_iter()
1849 .map(|arg| arg.get_embedded(data, db))
1850 .collect(),
1851 }
1852 .intern(db)
1853 }
1854}
1855
1856#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1857pub struct ConcreteStructCached {
1858 struct_id: LanguageElementCached,
1859 generic_args: Vec<GenericArgumentCached>,
1860}
1861impl ConcreteStructCached {
1862 fn new<'db>(
1863 concrete_struct: ConcreteStructId<'db>,
1864 ctx: &mut SemanticCacheSavingContext<'db>,
1865 ) -> Self {
1866 let long_id = concrete_struct.long(ctx.db);
1867 Self {
1868 struct_id: LanguageElementCached::new(long_id.struct_id, &mut ctx.defs_ctx),
1869 generic_args: long_id
1870 .generic_args
1871 .clone()
1872 .into_iter()
1873 .map(|arg| GenericArgumentCached::new(arg, ctx))
1874 .collect(),
1875 }
1876 }
1877 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ConcreteStructId<'db> {
1878 let (module_id, stable_ptr) = self.struct_id.get_embedded(&ctx.defs_loading_data);
1879
1880 let long_id = ConcreteStructLongId {
1881 struct_id: StructLongId(module_id, ItemStructPtr(stable_ptr)).intern(ctx.db),
1882 generic_args: self.generic_args.into_iter().map(|arg| arg.embed(ctx)).collect(),
1883 };
1884 long_id.intern(ctx.db)
1885 }
1886 pub fn get_embedded<'db>(
1887 self,
1888 data: &Arc<SemanticCacheLoadingData<'db>>,
1889 db: &'db dyn Database,
1890 ) -> ConcreteStructId<'db> {
1891 let (module_id, stable_ptr) = self.struct_id.get_embedded(&data.defs_loading_data);
1892 let long_id = ConcreteStructLongId {
1893 struct_id: StructLongId(module_id, ItemStructPtr(stable_ptr)).intern(db),
1894 generic_args: self
1895 .generic_args
1896 .into_iter()
1897 .map(|arg| arg.get_embedded(data, db))
1898 .collect(),
1899 };
1900 long_id.intern(db)
1901 }
1902}
1903
1904#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1905struct ConcreteExternTypeCached {
1906 language_element: LanguageElementCached,
1907 generic_args: Vec<GenericArgumentCached>,
1908}
1909impl ConcreteExternTypeCached {
1910 fn new<'db>(
1911 concrete_extern_type: ConcreteExternTypeId<'db>,
1912 ctx: &mut SemanticCacheSavingContext<'db>,
1913 ) -> Self {
1914 let long_id = concrete_extern_type.long(ctx.db);
1915 Self {
1916 language_element: LanguageElementCached::new(long_id.extern_type_id, &mut ctx.defs_ctx),
1917 generic_args: long_id
1918 .generic_args
1919 .clone()
1920 .into_iter()
1921 .map(|arg| GenericArgumentCached::new(arg, ctx))
1922 .collect(),
1923 }
1924 }
1925 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ConcreteExternTypeId<'db> {
1926 let (module_id, stable_ptr) = self.language_element.get_embedded(&ctx.defs_loading_data);
1927
1928 let long_id = ConcreteExternTypeLongId {
1929 extern_type_id: ExternTypeLongId(module_id, ItemExternTypePtr(stable_ptr))
1930 .intern(ctx.db),
1931 generic_args: self.generic_args.into_iter().map(|arg| arg.embed(ctx)).collect(),
1932 };
1933 long_id.intern(ctx.db)
1934 }
1935}
1936
1937#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1938struct ConcreteTraitCached {
1939 trait_id: LanguageElementCached,
1940 generic_args: Vec<GenericArgumentCached>,
1941}
1942
1943impl ConcreteTraitCached {
1944 fn new<'db>(
1945 concrete_trait: ConcreteTraitId<'db>,
1946 ctx: &mut SemanticCacheSavingContext<'db>,
1947 ) -> Self {
1948 let long_id = concrete_trait.long(ctx.db);
1949 Self {
1950 trait_id: LanguageElementCached::new(long_id.trait_id, &mut ctx.defs_ctx),
1951 generic_args: long_id
1952 .generic_args
1953 .clone()
1954 .into_iter()
1955 .map(|arg| GenericArgumentCached::new(arg, ctx))
1956 .collect(),
1957 }
1958 }
1959 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ConcreteTraitId<'db> {
1960 let (module_id, stable_ptr) = self.trait_id.get_embedded(&ctx.defs_loading_data);
1961
1962 let long_id = ConcreteTraitLongId {
1963 trait_id: TraitLongId(module_id, ItemTraitPtr(stable_ptr)).intern(ctx.db),
1964 generic_args: self.generic_args.into_iter().map(|arg| arg.embed(ctx)).collect(),
1965 };
1966 long_id.intern(ctx.db)
1967 }
1968 pub fn get_embedded<'db>(
1969 self,
1970 data: &Arc<SemanticCacheLoadingData<'db>>,
1971 db: &'db dyn Database,
1972 ) -> ConcreteTraitId<'db> {
1973 let (module_id, stable_ptr) = self.trait_id.get_embedded(&data.defs_loading_data);
1974 let long_id = ConcreteTraitLongId {
1975 trait_id: TraitLongId(module_id, ItemTraitPtr(stable_ptr)).intern(db),
1976 generic_args: self
1977 .generic_args
1978 .into_iter()
1979 .map(|arg| arg.get_embedded(data, db))
1980 .collect(),
1981 };
1982 long_id.intern(db)
1983 }
1984}