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