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