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