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}
1199
1200impl TypeCached {
1201 fn new<'db>(type_id: TypeLongId<'db>, ctx: &mut SemanticCacheSavingContext<'db>) -> Self {
1202 match type_id {
1203 TypeLongId::Concrete(concrete_type_id) => {
1204 TypeCached::Concrete(ConcreteTypeCached::new(concrete_type_id, ctx))
1205 }
1206 TypeLongId::Tuple(vec) => {
1207 TypeCached::Tuple(vec.into_iter().map(|ty| TypeIdCached::new(ty, ctx)).collect())
1208 }
1209 TypeLongId::Snapshot(type_id) => {
1210 TypeCached::Snapshot(Box::new(TypeIdCached::new(type_id, ctx)))
1211 }
1212 TypeLongId::GenericParameter(generic_param_id) => TypeCached::GenericParameter(
1213 GenericParamCached::new(generic_param_id, &mut ctx.defs_ctx),
1214 ),
1215 TypeLongId::ImplType(impl_type_id) => {
1216 TypeCached::ImplType(ImplTypeCached::new(impl_type_id, ctx))
1217 }
1218 TypeLongId::FixedSizeArray { type_id, size } => TypeCached::FixedSizeArray(
1219 TypeIdCached::new(type_id, ctx),
1220 ConstValueCached::new(size.long(ctx.db).clone(), ctx),
1221 ),
1222 TypeLongId::Closure(closure_ty) => {
1223 TypeCached::ClosureType(ClosureTypeCached::new(closure_ty, ctx))
1224 }
1225 TypeLongId::Var(_) | TypeLongId::Missing(_) | TypeLongId::Coupon(_) => {
1226 unreachable!("type {:?} is not supported for caching", type_id.debug(ctx.db))
1227 }
1228 }
1229 }
1230 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> TypeLongId<'db> {
1231 match self {
1232 TypeCached::Concrete(concrete_type) => TypeLongId::Concrete(concrete_type.embed(ctx)),
1233 TypeCached::Tuple(vec) => {
1234 TypeLongId::Tuple(vec.into_iter().map(|ty| ty.embed(ctx)).collect())
1235 }
1236 TypeCached::Snapshot(type_id) => TypeLongId::Snapshot(type_id.embed(ctx)),
1237 TypeCached::GenericParameter(generic_param) => TypeLongId::GenericParameter(
1238 generic_param.get_embedded(&ctx.defs_loading_data, ctx.db),
1239 ),
1240 TypeCached::ImplType(impl_type) => TypeLongId::ImplType(impl_type.embed(ctx)),
1241 TypeCached::FixedSizeArray(type_id, size) => TypeLongId::FixedSizeArray {
1242 type_id: type_id.embed(ctx),
1243 size: size.embed(ctx).intern(ctx.db),
1244 },
1245 TypeCached::ClosureType(closure_ty) => TypeLongId::Closure(closure_ty.embed(ctx)),
1246 }
1247 }
1248}
1249
1250#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1251pub struct TypeIdCached(usize);
1252
1253impl TypeIdCached {
1254 pub fn new<'db>(ty: TypeId<'db>, ctx: &mut SemanticCacheSavingContext<'db>) -> Self {
1255 if let Some(id) = ctx.type_ids.get(&ty) {
1256 return *id;
1257 }
1258 let ty_long = TypeCached::new(ty.long(ctx.db).clone(), ctx);
1259 let id = TypeIdCached(ctx.type_ids_lookup.len());
1260 ctx.type_ids_lookup.push(ty_long);
1261 ctx.type_ids.insert(ty, id);
1262 id
1263 }
1264 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> TypeId<'db> {
1265 if let Some(type_id) = ctx.type_ids.get(&self) {
1266 return *type_id;
1267 }
1268
1269 let ty = ctx.type_ids_lookup[self.0].clone();
1270 let ty = ty.embed(ctx).intern(ctx.db);
1271 ctx.type_ids.insert(self, ty);
1272 ty
1273 }
1274 pub fn get_embedded<'db>(self, data: &Arc<SemanticCacheLoadingData<'db>>) -> TypeId<'db> {
1275 data.type_ids[&self]
1276 }
1277}
1278
1279#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1280enum ConcreteTypeCached {
1281 Struct(ConcreteStructCached),
1282 Enum(ConcreteEnumCached),
1283 Extern(ConcreteExternTypeCached),
1284}
1285
1286impl ConcreteTypeCached {
1287 fn new<'db>(
1288 concrete_type_id: ConcreteTypeId<'db>,
1289 ctx: &mut SemanticCacheSavingContext<'db>,
1290 ) -> Self {
1291 match concrete_type_id {
1292 ConcreteTypeId::Struct(id) => {
1293 ConcreteTypeCached::Struct(ConcreteStructCached::new(id, ctx))
1294 }
1295 ConcreteTypeId::Enum(id) => ConcreteTypeCached::Enum(ConcreteEnumCached::new(id, ctx)),
1296 ConcreteTypeId::Extern(id) => {
1297 ConcreteTypeCached::Extern(ConcreteExternTypeCached::new(id, ctx))
1298 }
1299 }
1300 }
1301 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ConcreteTypeId<'db> {
1302 match self {
1303 ConcreteTypeCached::Struct(s) => ConcreteTypeId::Struct(s.embed(ctx)),
1304 ConcreteTypeCached::Enum(e) => ConcreteTypeId::Enum(e.embed(ctx)),
1305 ConcreteTypeCached::Extern(e) => ConcreteTypeId::Extern(e.embed(ctx)),
1306 }
1307 }
1308}
1309
1310#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1311struct ImplTypeCached {
1312 impl_id: ImplIdCached,
1313 trait_type: TraitTypeCached,
1314}
1315impl ImplTypeCached {
1316 fn new<'db>(impl_type_id: ImplTypeId<'db>, ctx: &mut SemanticCacheSavingContext<'db>) -> Self {
1317 Self {
1318 impl_id: ImplIdCached::new(impl_type_id.impl_id(), ctx),
1319 trait_type: TraitTypeCached::new(impl_type_id.ty(), ctx),
1320 }
1321 }
1322 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ImplTypeId<'db> {
1323 let impl_id = self.impl_id.embed(ctx);
1324 let ty = self.trait_type.embed(ctx);
1325 ImplTypeId::new(impl_id, ty, ctx.db)
1326 }
1327}
1328#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1329struct ClosureTypeCached {
1330 param_tys: Vec<TypeIdCached>,
1331 ret_ty: TypeIdCached,
1332 captured_types: Vec<TypeIdCached>,
1333 parent_function: SemanticFunctionIdCached,
1334 wrapper_location: SyntaxStablePtrIdCached,
1335}
1336
1337impl ClosureTypeCached {
1338 fn new<'db>(
1339 closure_type_id: ClosureTypeLongId<'db>,
1340 ctx: &mut SemanticCacheSavingContext<'db>,
1341 ) -> Self {
1342 Self {
1343 param_tys: closure_type_id
1344 .param_tys
1345 .iter()
1346 .map(|ty| TypeIdCached::new(*ty, ctx))
1347 .collect(),
1348 ret_ty: TypeIdCached::new(closure_type_id.ret_ty, ctx),
1349 captured_types: closure_type_id
1350 .captured_types
1351 .iter()
1352 .map(|ty| TypeIdCached::new(*ty, ctx))
1353 .collect(),
1354 parent_function: SemanticFunctionIdCached::new(
1355 closure_type_id.parent_function.unwrap(),
1356 ctx,
1357 ),
1358 wrapper_location: SyntaxStablePtrIdCached::new(
1359 closure_type_id.wrapper_location.stable_ptr(),
1360 &mut ctx.defs_ctx,
1361 ),
1362 }
1363 }
1364 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ClosureTypeLongId<'db> {
1365 ClosureTypeLongId {
1366 param_tys: self.param_tys.into_iter().map(|ty| ty.embed(ctx)).collect(),
1367 ret_ty: self.ret_ty.embed(ctx),
1368 captured_types: self.captured_types.into_iter().map(|ty| ty.embed(ctx)).collect(),
1369 parent_function: Ok(self.parent_function.embed(ctx)),
1370 wrapper_location: StableLocation::new(
1371 self.wrapper_location.get_embedded(&ctx.defs_loading_data),
1372 ),
1373 }
1374 }
1375}
1376
1377#[derive(Serialize, Deserialize, Clone, Hash, PartialEq, Eq)]
1378struct TraitTypeCached {
1379 language_element: LanguageElementCached,
1380}
1381impl TraitTypeCached {
1382 fn new<'db>(
1383 trait_type_id: TraitTypeId<'db>,
1384 ctx: &mut SemanticCacheSavingContext<'db>,
1385 ) -> Self {
1386 Self { language_element: LanguageElementCached::new(trait_type_id, &mut ctx.defs_ctx) }
1387 }
1388 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> TraitTypeId<'db> {
1389 let (module_id, stable_ptr) = self.language_element.get_embedded(&ctx.defs_loading_data);
1390 TraitTypeLongId(module_id, TraitItemTypePtr(stable_ptr)).intern(ctx.db)
1391 }
1392}
1393
1394#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1395enum ImplCached {
1396 Concrete(ConcreteImplCached),
1397 GenericParameter(GenericParamCached),
1398 ImplImpl(ImplImplCached),
1399 GeneratedImpl(GeneratedImplCached),
1400 SelfImpl(ConcreteTraitCached),
1401}
1402impl ImplCached {
1403 fn new<'db>(impl_id: ImplLongId<'db>, ctx: &mut SemanticCacheSavingContext<'db>) -> Self {
1404 match impl_id {
1405 ImplLongId::Concrete(concrete_impl) => {
1406 ImplCached::Concrete(ConcreteImplCached::new(concrete_impl, ctx))
1407 }
1408 ImplLongId::GenericParameter(generic_param_id) => ImplCached::GenericParameter(
1409 GenericParamCached::new(generic_param_id, &mut ctx.defs_ctx),
1410 ),
1411 ImplLongId::GeneratedImpl(generated_impl) => {
1412 ImplCached::GeneratedImpl(GeneratedImplCached::new(generated_impl, ctx))
1413 }
1414 ImplLongId::ImplImpl(impl_impl) => {
1415 ImplCached::ImplImpl(ImplImplCached::new(impl_impl, ctx))
1416 }
1417 ImplLongId::SelfImpl(concrete_trait) => {
1418 ImplCached::SelfImpl(ConcreteTraitCached::new(concrete_trait, ctx))
1419 }
1420 ImplLongId::ImplVar(_) => {
1421 unreachable!("impl {:?} is not supported for caching", impl_id.debug(ctx.db))
1422 }
1423 }
1424 }
1425 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ImplLongId<'db> {
1426 match self {
1427 ImplCached::Concrete(concrete_impl) => ImplLongId::Concrete(concrete_impl.embed(ctx)),
1428 ImplCached::ImplImpl(impl_impl) => ImplLongId::ImplImpl(impl_impl.embed(ctx)),
1429 ImplCached::GenericParameter(generic_param) => ImplLongId::GenericParameter(
1430 generic_param.get_embedded(&ctx.defs_loading_data, ctx.db),
1431 ),
1432 ImplCached::GeneratedImpl(generated_impl) => {
1433 ImplLongId::GeneratedImpl(generated_impl.embed(ctx))
1434 }
1435 ImplCached::SelfImpl(concrete_trait) => ImplLongId::SelfImpl(concrete_trait.embed(ctx)),
1436 }
1437 }
1438}
1439#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1440pub struct ImplIdCached(usize);
1441
1442impl ImplIdCached {
1443 pub fn new<'db>(impl_id: ImplId<'db>, ctx: &mut SemanticCacheSavingContext<'db>) -> Self {
1444 if let Some(id) = ctx.impl_ids.get(&impl_id) {
1445 return *id;
1446 }
1447 let imp = ImplCached::new(impl_id.long(ctx.db).clone(), ctx);
1448 let id = ImplIdCached(ctx.impl_ids_lookup.len());
1449 ctx.impl_ids_lookup.push(imp);
1450 ctx.impl_ids.insert(impl_id, id);
1451 id
1452 }
1453 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ImplId<'db> {
1454 if let Some(impl_id) = ctx.impl_ids.get(&self) {
1455 return *impl_id;
1456 }
1457
1458 let imp = ctx.impl_ids_lookup[self.0].clone();
1459 let imp = imp.embed(ctx).intern(ctx.db);
1460 ctx.impl_ids.insert(self, imp);
1461 imp
1462 }
1463 pub fn get_embedded<'db>(self, data: &Arc<SemanticCacheLoadingData<'db>>) -> ImplId<'db> {
1464 data.impl_ids[&self]
1465 }
1466}
1467
1468#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1469struct ConcreteImplCached {
1470 impl_def_id: ImplDefIdCached,
1471 generic_args: Vec<GenericArgumentCached>,
1472}
1473impl ConcreteImplCached {
1474 fn new<'db>(
1475 concrete_impl: ConcreteImplId<'db>,
1476 ctx: &mut SemanticCacheSavingContext<'db>,
1477 ) -> Self {
1478 let long_id = concrete_impl.long(ctx.db);
1479 Self {
1480 impl_def_id: ImplDefIdCached::new(long_id.impl_def_id, &mut ctx.defs_ctx),
1481 generic_args: long_id
1482 .generic_args
1483 .clone()
1484 .into_iter()
1485 .map(|arg| GenericArgumentCached::new(arg, ctx))
1486 .collect(),
1487 }
1488 }
1489 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ConcreteImplId<'db> {
1490 let impl_def_id = self.impl_def_id.get_embedded(&ctx.defs_loading_data);
1491 let long_id = ConcreteImplLongId {
1492 impl_def_id,
1493 generic_args: self.generic_args.into_iter().map(|arg| arg.embed(ctx)).collect(),
1494 };
1495 long_id.intern(ctx.db)
1496 }
1497 pub fn get_embedded<'db>(
1498 self,
1499 data: &Arc<SemanticCacheLoadingData<'db>>,
1500 db: &'db dyn Database,
1501 ) -> ConcreteImplId<'db> {
1502 let impl_def_id = self.impl_def_id.get_embedded(&data.defs_loading_data);
1503 let long_id = ConcreteImplLongId {
1504 impl_def_id,
1505 generic_args: self
1506 .generic_args
1507 .into_iter()
1508 .map(|arg| arg.get_embedded(data, db))
1509 .collect(),
1510 };
1511 long_id.intern(db)
1512 }
1513}
1514
1515#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1516struct ImplImplCached {
1517 impl_id: ImplIdCached,
1518 trait_impl_id: TraitImplCached,
1519}
1520impl ImplImplCached {
1521 fn new<'db>(impl_impl_id: ImplImplId<'db>, ctx: &mut SemanticCacheSavingContext<'db>) -> Self {
1522 Self {
1523 impl_id: ImplIdCached::new(impl_impl_id.impl_id(), ctx),
1524 trait_impl_id: TraitImplCached::new(impl_impl_id.trait_impl_id(), ctx),
1525 }
1526 }
1527 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ImplImplId<'db> {
1528 let impl_id = self.impl_id.embed(ctx);
1529 let trait_impl_id = self.trait_impl_id.embed(ctx);
1530 ImplImplId::new(impl_id, trait_impl_id, ctx.db)
1531 }
1532}
1533
1534#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1535struct TraitImplCached {
1536 language_element: LanguageElementCached,
1537}
1538impl TraitImplCached {
1539 fn new<'db>(
1540 trait_impl_id: TraitImplId<'db>,
1541 ctx: &mut SemanticCacheSavingContext<'db>,
1542 ) -> Self {
1543 Self { language_element: LanguageElementCached::new(trait_impl_id, &mut ctx.defs_ctx) }
1544 }
1545 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> TraitImplId<'db> {
1546 let (module_id, stable_ptr) = self.language_element.get_embedded(&ctx.defs_loading_data);
1547 TraitImplLongId(module_id, TraitItemImplPtr(stable_ptr)).intern(ctx.db)
1548 }
1549}
1550
1551#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1552struct GeneratedImplCached {
1553 pub concrete_trait: ConcreteTraitCached,
1554 pub generic_params: Vec<SemanticGenericParamCached>,
1555 pub impl_items: OrderedHashMap<TraitTypeCached, TypeIdCached>,
1556}
1557impl GeneratedImplCached {
1558 fn new<'db>(
1559 generated_impl: GeneratedImplId<'db>,
1560 ctx: &mut SemanticCacheSavingContext<'db>,
1561 ) -> Self {
1562 let generated_impl = generated_impl.long(ctx.db);
1563 Self {
1564 concrete_trait: ConcreteTraitCached::new(generated_impl.concrete_trait, ctx),
1565 generic_params: generated_impl
1566 .generic_params
1567 .clone()
1568 .into_iter()
1569 .map(|param| SemanticGenericParamCached::new(param, ctx))
1570 .collect(),
1571 impl_items: generated_impl
1572 .impl_items
1573 .0
1574 .clone()
1575 .into_iter()
1576 .map(|(k, v)| (TraitTypeCached::new(k, ctx), TypeIdCached::new(v, ctx)))
1577 .collect(),
1578 }
1579 }
1580 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> GeneratedImplId<'db> {
1581 GeneratedImplLongId {
1582 concrete_trait: self.concrete_trait.embed(ctx),
1583 generic_params: self.generic_params.into_iter().map(|param| param.embed(ctx)).collect(),
1584 impl_items: GeneratedImplItems(
1585 self.impl_items.into_iter().map(|(k, v)| (k.embed(ctx), v.embed(ctx))).collect(),
1586 ),
1587 }
1588 .intern(ctx.db)
1589 }
1590}
1591
1592#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1593enum NegativeImplCached {
1594 Solved(ConcreteTraitCached),
1595 GenericParameter(GenericParamCached),
1596}
1597impl NegativeImplCached {
1598 fn new<'db>(
1599 negative_impl_id: NegativeImplLongId<'db>,
1600 ctx: &mut SemanticCacheSavingContext<'db>,
1601 ) -> Self {
1602 match negative_impl_id {
1603 NegativeImplLongId::Solved(concrete_trait_id) => {
1604 NegativeImplCached::Solved(ConcreteTraitCached::new(concrete_trait_id, ctx))
1605 }
1606 NegativeImplLongId::GenericParameter(generic_param_id) => {
1607 NegativeImplCached::GenericParameter(GenericParamCached::new(
1608 generic_param_id,
1609 &mut ctx.defs_ctx,
1610 ))
1611 }
1612 NegativeImplLongId::NegativeImplVar(_) => {
1613 unreachable!("negative impl var is not supported for caching",)
1614 }
1615 }
1616 }
1617 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> NegativeImplLongId<'db> {
1618 match self {
1619 NegativeImplCached::Solved(concrete_trait) => {
1620 NegativeImplLongId::Solved(concrete_trait.embed(ctx))
1621 }
1622 NegativeImplCached::GenericParameter(generic_param) => {
1623 NegativeImplLongId::GenericParameter(
1624 generic_param.get_embedded(&ctx.defs_loading_data, ctx.db),
1625 )
1626 }
1627 }
1628 }
1629}
1630
1631#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1632struct NegativeImplIdCached(usize);
1633
1634impl NegativeImplIdCached {
1635 fn new<'db>(
1636 negative_impl_id: NegativeImplId<'db>,
1637 ctx: &mut SemanticCacheSavingContext<'db>,
1638 ) -> Self {
1639 if let Some(id) = ctx.negative_impl_ids.get(&negative_impl_id) {
1640 return *id;
1641 }
1642 let imp = NegativeImplCached::new(negative_impl_id.long(ctx.db).clone(), ctx);
1643 let id = NegativeImplIdCached(ctx.negative_impl_ids_lookup.len());
1644 ctx.negative_impl_ids_lookup.push(imp);
1645 ctx.negative_impl_ids.insert(negative_impl_id, id);
1646 id
1647 }
1648 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> NegativeImplId<'db> {
1649 if let Some(negative_impl_id) = ctx.negative_impl_ids.get(&self) {
1650 return *negative_impl_id;
1651 }
1652
1653 let imp = ctx.negative_impl_ids_lookup[self.0].clone();
1654 let imp = imp.embed(ctx).intern(ctx.db);
1655 ctx.negative_impl_ids.insert(self, imp);
1656 imp
1657 }
1658 pub fn get_embedded<'db>(
1659 self,
1660 data: &Arc<SemanticCacheLoadingData<'db>>,
1661 ) -> NegativeImplId<'db> {
1662 data.negative_impl_ids[&self]
1663 }
1664}
1665
1666#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1667enum SemanticGenericParamCached {
1668 Type(GenericParamTypeCached),
1669 Const(GenericParamConstCached),
1670 Impl(GenericParamImplCached),
1671 NegImpl(GenericParamImplCached),
1672}
1673impl SemanticGenericParamCached {
1674 fn new<'db>(
1675 generic_param_id: GenericParam<'db>,
1676 ctx: &mut SemanticCacheSavingContext<'db>,
1677 ) -> Self {
1678 match generic_param_id {
1679 GenericParam::Type(generic_param) => {
1680 SemanticGenericParamCached::Type(GenericParamTypeCached::new(generic_param, ctx))
1681 }
1682 GenericParam::Const(generic_param) => {
1683 SemanticGenericParamCached::Const(GenericParamConstCached::new(generic_param, ctx))
1684 }
1685 GenericParam::Impl(generic_param) => {
1686 SemanticGenericParamCached::Impl(GenericParamImplCached::new(generic_param, ctx))
1687 }
1688 GenericParam::NegImpl(generic_param) => {
1689 SemanticGenericParamCached::NegImpl(GenericParamImplCached::new(generic_param, ctx))
1690 }
1691 }
1692 }
1693 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> GenericParam<'db> {
1694 match self {
1695 SemanticGenericParamCached::Type(generic_param) => {
1696 GenericParam::Type(generic_param.embed(ctx))
1697 }
1698 SemanticGenericParamCached::Const(generic_param) => {
1699 GenericParam::Const(generic_param.embed(ctx))
1700 }
1701 SemanticGenericParamCached::Impl(generic_param) => {
1702 GenericParam::Impl(generic_param.embed(ctx))
1703 }
1704 SemanticGenericParamCached::NegImpl(generic_param) => {
1705 GenericParam::NegImpl(generic_param.embed(ctx))
1706 }
1707 }
1708 }
1709}
1710
1711#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1712struct GenericParamTypeCached {
1713 id: GenericParamCached,
1714}
1715
1716impl GenericParamTypeCached {
1717 fn new<'db>(
1718 generic_param: GenericParamType<'db>,
1719 ctx: &mut SemanticCacheSavingContext<'db>,
1720 ) -> Self {
1721 Self { id: GenericParamCached::new(generic_param.id, &mut ctx.defs_ctx) }
1722 }
1723 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> GenericParamType<'db> {
1724 GenericParamType { id: self.id.get_embedded(&ctx.defs_loading_data, ctx.db) }
1725 }
1726}
1727
1728#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1729struct GenericParamConstCached {
1730 id: GenericParamCached,
1731 ty: TypeIdCached,
1732}
1733
1734impl GenericParamConstCached {
1735 fn new<'db>(
1736 generic_param: GenericParamConst<'db>,
1737 ctx: &mut SemanticCacheSavingContext<'db>,
1738 ) -> Self {
1739 Self {
1740 id: GenericParamCached::new(generic_param.id, &mut ctx.defs_ctx),
1741 ty: TypeIdCached::new(generic_param.ty, ctx),
1742 }
1743 }
1744 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> GenericParamConst<'db> {
1745 GenericParamConst {
1746 id: self.id.get_embedded(&ctx.defs_loading_data, ctx.db),
1747 ty: self.ty.embed(ctx),
1748 }
1749 }
1750}
1751
1752#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1753struct GenericParamImplCached {
1754 id: GenericParamCached,
1755 concrete_trait: ConcreteTraitCached,
1756 type_constraints: OrderedHashMap<TraitTypeCached, TypeIdCached>,
1757}
1758
1759impl GenericParamImplCached {
1760 fn new<'db>(
1761 generic_param: GenericParamImpl<'db>,
1762 ctx: &mut SemanticCacheSavingContext<'db>,
1763 ) -> Self {
1764 Self {
1765 id: GenericParamCached::new(generic_param.id, &mut ctx.defs_ctx),
1766 concrete_trait: ConcreteTraitCached::new(generic_param.concrete_trait.unwrap(), ctx),
1767
1768 type_constraints: generic_param
1769 .type_constraints
1770 .into_iter()
1771 .map(|(k, v)| (TraitTypeCached::new(k, ctx), TypeIdCached::new(v, ctx)))
1772 .collect(),
1773 }
1774 }
1775 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> GenericParamImpl<'db> {
1776 GenericParamImpl {
1777 id: self.id.get_embedded(&ctx.defs_loading_data, ctx.db),
1778 concrete_trait: Ok(self.concrete_trait.embed(ctx)),
1779 type_constraints: self
1780 .type_constraints
1781 .into_iter()
1782 .map(|(k, v)| (k.embed(ctx), v.embed(ctx)))
1783 .collect(),
1784 }
1785 }
1786}
1787
1788#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1789pub struct ConcreteVariantCached {
1790 concrete_enum_id: ConcreteEnumCached,
1791 id: LanguageElementCached,
1792 ty: TypeIdCached,
1793 idx: usize,
1794}
1795impl ConcreteVariantCached {
1796 pub fn new<'db>(
1797 concrete_variant: ConcreteVariant<'db>,
1798 ctx: &mut SemanticCacheSavingContext<'db>,
1799 ) -> Self {
1800 Self {
1801 concrete_enum_id: ConcreteEnumCached::new(concrete_variant.concrete_enum_id, ctx),
1802 id: LanguageElementCached::new(concrete_variant.id, &mut ctx.defs_ctx),
1803 ty: TypeIdCached::new(concrete_variant.ty, ctx),
1804 idx: concrete_variant.idx,
1805 }
1806 }
1807 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ConcreteVariant<'db> {
1808 let concrete_enum_id = self.concrete_enum_id.embed(ctx);
1809 let ty = self.ty.embed(ctx);
1810 let (module_id, stable_ptr) = self.id.get_embedded(&ctx.defs_loading_data);
1811
1812 let id = VariantLongId(module_id, VariantPtr(stable_ptr)).intern(ctx.db);
1813 ConcreteVariant { concrete_enum_id, id, ty, idx: self.idx }
1814 }
1815 pub fn get_embedded<'db>(
1816 self,
1817 data: &Arc<SemanticCacheLoadingData<'db>>,
1818 db: &'db dyn Database,
1819 ) -> ConcreteVariant<'db> {
1820 let concrete_enum_id = self.concrete_enum_id.get_embedded(data, db);
1821 let ty = self.ty.get_embedded(data);
1822 let (module_id, stable_ptr) = self.id.get_embedded(&data.defs_loading_data);
1823 let id = VariantLongId(module_id, VariantPtr(stable_ptr)).intern(db);
1824 ConcreteVariant { concrete_enum_id, id, ty, idx: self.idx }
1825 }
1826}
1827
1828#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1829pub struct ConcreteEnumCached {
1830 enum_id: LanguageElementCached,
1831 generic_args: Vec<GenericArgumentCached>,
1832}
1833
1834impl ConcreteEnumCached {
1835 pub fn new<'db>(
1836 concrete_enum: ConcreteEnumId<'db>,
1837 ctx: &mut SemanticCacheSavingContext<'db>,
1838 ) -> Self {
1839 let long_id = concrete_enum.long(ctx.db);
1840 Self {
1841 enum_id: LanguageElementCached::new(long_id.enum_id, &mut ctx.defs_ctx),
1842 generic_args: long_id
1843 .generic_args
1844 .clone()
1845 .into_iter()
1846 .map(|arg| GenericArgumentCached::new(arg, ctx))
1847 .collect(),
1848 }
1849 }
1850 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ConcreteEnumId<'db> {
1851 let (module_id, stable_ptr) = self.enum_id.get_embedded(&ctx.defs_loading_data);
1852
1853 let long_id = ConcreteEnumLongId {
1854 enum_id: EnumLongId(module_id, ItemEnumPtr(stable_ptr)).intern(ctx.db),
1855 generic_args: self.generic_args.into_iter().map(|arg| arg.embed(ctx)).collect(),
1856 };
1857 long_id.intern(ctx.db)
1858 }
1859 pub fn get_embedded<'db>(
1860 self,
1861 data: &Arc<SemanticCacheLoadingData<'db>>,
1862 db: &'db dyn Database,
1863 ) -> ConcreteEnumId<'db> {
1864 let (module_id, stable_ptr) = self.enum_id.get_embedded(&data.defs_loading_data);
1865 let id = EnumLongId(module_id, ItemEnumPtr(stable_ptr)).intern(db);
1866 ConcreteEnumLongId {
1867 enum_id: id,
1868 generic_args: self
1869 .generic_args
1870 .into_iter()
1871 .map(|arg| arg.get_embedded(data, db))
1872 .collect(),
1873 }
1874 .intern(db)
1875 }
1876}
1877
1878#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1879pub struct ConcreteStructCached {
1880 struct_id: LanguageElementCached,
1881 generic_args: Vec<GenericArgumentCached>,
1882}
1883impl ConcreteStructCached {
1884 fn new<'db>(
1885 concrete_struct: ConcreteStructId<'db>,
1886 ctx: &mut SemanticCacheSavingContext<'db>,
1887 ) -> Self {
1888 let long_id = concrete_struct.long(ctx.db);
1889 Self {
1890 struct_id: LanguageElementCached::new(long_id.struct_id, &mut ctx.defs_ctx),
1891 generic_args: long_id
1892 .generic_args
1893 .clone()
1894 .into_iter()
1895 .map(|arg| GenericArgumentCached::new(arg, ctx))
1896 .collect(),
1897 }
1898 }
1899 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ConcreteStructId<'db> {
1900 let (module_id, stable_ptr) = self.struct_id.get_embedded(&ctx.defs_loading_data);
1901
1902 let long_id = ConcreteStructLongId {
1903 struct_id: StructLongId(module_id, ItemStructPtr(stable_ptr)).intern(ctx.db),
1904 generic_args: self.generic_args.into_iter().map(|arg| arg.embed(ctx)).collect(),
1905 };
1906 long_id.intern(ctx.db)
1907 }
1908 pub fn get_embedded<'db>(
1909 self,
1910 data: &Arc<SemanticCacheLoadingData<'db>>,
1911 db: &'db dyn Database,
1912 ) -> ConcreteStructId<'db> {
1913 let (module_id, stable_ptr) = self.struct_id.get_embedded(&data.defs_loading_data);
1914 let long_id = ConcreteStructLongId {
1915 struct_id: StructLongId(module_id, ItemStructPtr(stable_ptr)).intern(db),
1916 generic_args: self
1917 .generic_args
1918 .into_iter()
1919 .map(|arg| arg.get_embedded(data, db))
1920 .collect(),
1921 };
1922 long_id.intern(db)
1923 }
1924}
1925
1926#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1927struct ConcreteExternTypeCached {
1928 language_element: LanguageElementCached,
1929 generic_args: Vec<GenericArgumentCached>,
1930}
1931impl ConcreteExternTypeCached {
1932 fn new<'db>(
1933 concrete_extern_type: ConcreteExternTypeId<'db>,
1934 ctx: &mut SemanticCacheSavingContext<'db>,
1935 ) -> Self {
1936 let long_id = concrete_extern_type.long(ctx.db);
1937 Self {
1938 language_element: LanguageElementCached::new(long_id.extern_type_id, &mut ctx.defs_ctx),
1939 generic_args: long_id
1940 .generic_args
1941 .clone()
1942 .into_iter()
1943 .map(|arg| GenericArgumentCached::new(arg, ctx))
1944 .collect(),
1945 }
1946 }
1947 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ConcreteExternTypeId<'db> {
1948 let (module_id, stable_ptr) = self.language_element.get_embedded(&ctx.defs_loading_data);
1949
1950 let long_id = ConcreteExternTypeLongId {
1951 extern_type_id: ExternTypeLongId(module_id, ItemExternTypePtr(stable_ptr))
1952 .intern(ctx.db),
1953 generic_args: self.generic_args.into_iter().map(|arg| arg.embed(ctx)).collect(),
1954 };
1955 long_id.intern(ctx.db)
1956 }
1957}
1958
1959#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1960struct ConcreteTraitCached {
1961 trait_id: LanguageElementCached,
1962 generic_args: Vec<GenericArgumentCached>,
1963}
1964
1965impl ConcreteTraitCached {
1966 fn new<'db>(
1967 concrete_trait: ConcreteTraitId<'db>,
1968 ctx: &mut SemanticCacheSavingContext<'db>,
1969 ) -> Self {
1970 let long_id = concrete_trait.long(ctx.db);
1971 Self {
1972 trait_id: LanguageElementCached::new(long_id.trait_id, &mut ctx.defs_ctx),
1973 generic_args: long_id
1974 .generic_args
1975 .clone()
1976 .into_iter()
1977 .map(|arg| GenericArgumentCached::new(arg, ctx))
1978 .collect(),
1979 }
1980 }
1981 fn embed<'db>(self, ctx: &mut SemanticCacheLoadingContext<'db>) -> ConcreteTraitId<'db> {
1982 let (module_id, stable_ptr) = self.trait_id.get_embedded(&ctx.defs_loading_data);
1983
1984 let long_id = ConcreteTraitLongId {
1985 trait_id: TraitLongId(module_id, ItemTraitPtr(stable_ptr)).intern(ctx.db),
1986 generic_args: self.generic_args.into_iter().map(|arg| arg.embed(ctx)).collect(),
1987 };
1988 long_id.intern(ctx.db)
1989 }
1990 pub fn get_embedded<'db>(
1991 self,
1992 data: &Arc<SemanticCacheLoadingData<'db>>,
1993 db: &'db dyn Database,
1994 ) -> ConcreteTraitId<'db> {
1995 let (module_id, stable_ptr) = self.trait_id.get_embedded(&data.defs_loading_data);
1996 let long_id = ConcreteTraitLongId {
1997 trait_id: TraitLongId(module_id, ItemTraitPtr(stable_ptr)).intern(db),
1998 generic_args: self
1999 .generic_args
2000 .into_iter()
2001 .map(|arg| arg.get_embedded(data, db))
2002 .collect(),
2003 };
2004 long_id.intern(db)
2005 }
2006}