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