1#[cfg(test)]
2#[path = "test.rs"]
3mod test;
4
5use std::ops::{Deref, DerefMut};
6use std::sync::Arc;
7
8use cairo_lang_debug::DebugWithDb;
9use cairo_lang_defs::cache::{
10 CachedCrateMetadata, DefCacheLoadingData, DefCacheSavingContext, GenericParamCached,
11 ImplDefIdCached, LanguageElementCached, SyntaxStablePtrIdCached, generate_crate_def_cache,
12};
13use cairo_lang_defs::diagnostic_utils::StableLocation;
14use cairo_lang_defs::ids::{
15 EnumLongId, ExternFunctionLongId, ExternTypeLongId, FreeFunctionLongId, FunctionWithBodyId,
16 ImplFunctionLongId, LocalVarId, LocalVarLongId, MemberLongId, ParamLongId,
17 StatementConstLongId, StatementItemId, StatementUseLongId, StructLongId, TraitConstantId,
18 TraitConstantLongId, TraitFunctionLongId, TraitImplId, TraitImplLongId, TraitLongId,
19 TraitTypeId, TraitTypeLongId, VariantLongId,
20};
21use cairo_lang_diagnostics::{Maybe, skip_diagnostic};
22use cairo_lang_filesystem::ids::CrateId;
23use cairo_lang_semantic::db::SemanticGroup;
24use cairo_lang_semantic::expr::inference::InferenceError;
25use cairo_lang_semantic::items::constant::{ConstValue, ImplConstantId};
26use cairo_lang_semantic::items::functions::{
27 ConcreteFunctionWithBody, GenericFunctionId, GenericFunctionWithBodyId, ImplFunctionBodyId,
28 ImplGenericFunctionId, ImplGenericFunctionWithBodyId,
29};
30use cairo_lang_semantic::items::generics::{GenericParamConst, GenericParamImpl, GenericParamType};
31use cairo_lang_semantic::items::imp::{
32 GeneratedImplId, GeneratedImplItems, GeneratedImplLongId, ImplId, ImplImplId, ImplLongId,
33};
34use cairo_lang_semantic::items::trt::ConcreteTraitGenericFunctionLongId;
35use cairo_lang_semantic::types::{
36 ClosureTypeLongId, ConcreteEnumLongId, ConcreteExternTypeLongId, ConcreteStructLongId,
37 ImplTypeId, TypeInfo,
38};
39use cairo_lang_semantic::{
40 ConcreteFunction, ConcreteImplLongId, ConcreteTraitLongId, GenericParam, MatchArmSelector,
41 TypeId, TypeLongId, ValueSelectorArm,
42};
43use cairo_lang_syntax::node::TypedStablePtr;
44use cairo_lang_syntax::node::ast::{
45 ExprPtr, FunctionWithBodyPtr, ItemConstantPtr, ItemEnumPtr, ItemExternFunctionPtr,
46 ItemExternTypePtr, ItemStructPtr, ItemTraitPtr, MemberPtr, ParamPtr, TerminalIdentifierPtr,
47 TraitItemConstantPtr, TraitItemFunctionPtr, TraitItemImplPtr, TraitItemTypePtr, UsePathLeafPtr,
48 VariantPtr,
49};
50use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
51use cairo_lang_utils::{Intern, LookupIntern};
52use id_arena::Arena;
53use num_bigint::BigInt;
54use serde::{Deserialize, Serialize};
55use {cairo_lang_defs as defs, cairo_lang_semantic as semantic};
56
57use crate::blocks::BlocksBuilder;
58use crate::db::LoweringGroup;
59use crate::ids::{
60 FunctionId, FunctionLongId, GeneratedFunction, GeneratedFunctionKey, LocationId, Signature,
61};
62use crate::lower::{MultiLowering, lower_semantic_function};
63use crate::objects::{
64 BlockId, MatchExternInfo, Statement, StatementCall, StatementConst, StatementStructDestructure,
65 VariableId,
66};
67use crate::{
68 Block, BlockEnd, Location, Lowered, MatchArm, MatchEnumInfo, MatchEnumValue, MatchInfo,
69 StatementDesnap, StatementEnumConstruct, StatementSnapshot, StatementStructConstruct,
70 VarRemapping, VarUsage, Variable,
71};
72
73type LookupCache =
74 (CacheLookups, SemanticCacheLookups, Vec<(DefsFunctionWithBodyIdCached, MultiLoweringCached)>);
75
76pub fn load_cached_crate_functions(
78 db: &dyn LoweringGroup,
79 crate_id: CrateId,
80) -> Option<Arc<OrderedHashMap<defs::ids::FunctionWithBodyId, MultiLowering>>> {
81 let blob_id = db.crate_config(crate_id)?.cache_file?;
82 let Some(content) = db.blob_content(blob_id) else {
83 return Default::default();
84 };
85
86 let def_loading_data = db.cached_crate_modules(crate_id)?.1;
87
88 let def_size = usize::from_be_bytes(content[..8].try_into().unwrap()); let content = &content[16 + def_size..]; let ((lookups, semantic_lookups, lowerings), _): (LookupCache, _) =
93 bincode::serde::decode_from_slice(content, bincode::config::standard()).unwrap_or_else(
94 |e| {
95 panic!(
96 "failed to deserialize lookup cache for crate `{}`: {e}",
97 crate_id.name(db),
98 )
99 },
100 );
101
102 let mut ctx = CacheLoadingContext::new(db, lookups, semantic_lookups, def_loading_data);
105
106 Some(
107 lowerings
108 .into_iter()
109 .map(|(function_id, lowering)| {
110 let function_id = function_id.embed(&mut ctx.semantic_ctx);
111
112 let lowering = lowering.embed(&mut ctx);
113 (function_id, lowering)
114 })
115 .collect::<OrderedHashMap<_, _>>()
116 .into(),
117 )
118}
119
120pub fn generate_crate_cache(
122 db: &dyn LoweringGroup,
123 crate_id: cairo_lang_filesystem::ids::CrateId,
124) -> Maybe<Arc<[u8]>> {
125 let modules = db.crate_modules(crate_id);
126 let mut function_ids = Vec::new();
127 for module_id in modules.iter() {
128 for free_func in db.module_free_functions_ids(*module_id)?.iter() {
129 function_ids.push(FunctionWithBodyId::Free(*free_func));
130 }
131 for impl_id in db.module_impls_ids(*module_id)?.iter() {
132 for impl_func in db.impl_functions(*impl_id)?.values() {
133 function_ids.push(FunctionWithBodyId::Impl(*impl_func));
134 }
135 }
136 for trait_id in db.module_traits_ids(*module_id)?.iter() {
137 for trait_func in db.trait_functions(*trait_id)?.values() {
138 function_ids.push(FunctionWithBodyId::Trait(*trait_func));
139 }
140 }
141 for trait_id in db.module_traits_ids(*module_id)?.iter() {
142 for trait_func in db.trait_functions(*trait_id)?.values() {
143 function_ids.push(FunctionWithBodyId::Trait(*trait_func));
144 }
145 }
146 }
147
148 let mut ctx = CacheSavingContext::new(db, crate_id);
149
150 let def_cache = generate_crate_def_cache(db, crate_id, &mut ctx.semantic_ctx.defs_ctx)?;
151
152 let cached = function_ids
153 .iter()
154 .filter_map(|id| {
155 db.function_body(*id).ok()?;
156 let multi = match lower_semantic_function(db, *id).map(Arc::new) {
157 Ok(multi) => multi,
158 Err(err) => return Some(Err(err)),
159 };
160
161 Some(Ok((
162 DefsFunctionWithBodyIdCached::new(*id, &mut ctx.semantic_ctx),
163 MultiLoweringCached::new((*multi).clone(), &mut ctx),
164 )))
165 })
166 .collect::<Maybe<Vec<_>>>()?;
167
168 let mut artifact = Vec::<u8>::new();
169
170 if let Ok(def) = bincode::serde::encode_to_vec(
171 &(CachedCrateMetadata::new(crate_id, db), def_cache, &ctx.semantic_ctx.defs_ctx.lookups),
172 bincode::config::standard(),
173 ) {
174 artifact.extend(def.len().to_be_bytes());
175 artifact.extend(def);
176 }
177
178 if let Ok(lowered) = bincode::serde::encode_to_vec(
179 &(&ctx.lookups, &ctx.semantic_ctx.lookups, cached),
180 bincode::config::standard(),
181 ) {
182 artifact.extend(lowered.len().to_be_bytes());
183 artifact.extend(lowered);
184 }
185 Ok(Arc::from(artifact.as_slice()))
186}
187
188struct CacheLoadingContext<'db> {
190 lowered_variables_id: Vec<VariableId>,
192 db: &'db dyn LoweringGroup,
193
194 data: CacheLoadingData,
196
197 semantic_ctx: SemanticCacheLoadingContext<'db>,
198}
199
200impl<'db> CacheLoadingContext<'db> {
201 fn new(
202 db: &'db dyn LoweringGroup,
203 lookups: CacheLookups,
204 semantic_lookups: SemanticCacheLookups,
205 defs_loading_data: Arc<DefCacheLoadingData>,
206 ) -> Self {
207 Self {
208 lowered_variables_id: Vec::new(),
209 db,
210 data: CacheLoadingData {
211 function_ids: OrderedHashMap::default(),
212 location_ids: OrderedHashMap::default(),
213 lookups,
214 },
215 semantic_ctx: SemanticCacheLoadingContext::<'db> {
216 db,
217 data: SemanticCacheLoadingData::new(semantic_lookups),
218 defs_loading_data,
219 },
220 }
221 }
222}
223
224impl Deref for CacheLoadingContext<'_> {
225 type Target = CacheLoadingData;
226
227 fn deref(&self) -> &Self::Target {
228 &self.data
229 }
230}
231impl DerefMut for CacheLoadingContext<'_> {
232 fn deref_mut(&mut self) -> &mut Self::Target {
233 &mut self.data
234 }
235}
236
237struct CacheLoadingData {
239 function_ids: OrderedHashMap<FunctionIdCached, FunctionId>,
240 location_ids: OrderedHashMap<LocationIdCached, LocationId>,
241 lookups: CacheLookups,
242}
243impl Deref for CacheLoadingData {
244 type Target = CacheLookups;
245
246 fn deref(&self) -> &Self::Target {
247 &self.lookups
248 }
249}
250impl DerefMut for CacheLoadingData {
251 fn deref_mut(&mut self) -> &mut Self::Target {
252 &mut self.lookups
253 }
254}
255
256struct CacheSavingContext<'db> {
258 db: &'db dyn LoweringGroup,
259 data: CacheSavingData,
260 semantic_ctx: SemanticCacheSavingContext<'db>,
261}
262impl Deref for CacheSavingContext<'_> {
263 type Target = CacheSavingData;
264
265 fn deref(&self) -> &Self::Target {
266 &self.data
267 }
268}
269impl DerefMut for CacheSavingContext<'_> {
270 fn deref_mut(&mut self) -> &mut Self::Target {
271 &mut self.data
272 }
273}
274impl<'db> CacheSavingContext<'db> {
275 fn new(db: &'db dyn LoweringGroup, self_crate_id: CrateId) -> Self {
276 Self {
277 db,
278 data: CacheSavingData::default(),
279 semantic_ctx: SemanticCacheSavingContext {
280 db,
281 data: SemanticCacheSavingData::default(),
282 defs_ctx: DefCacheSavingContext::new(db, self_crate_id),
283 },
284 }
285 }
286}
287
288#[derive(Default)]
290struct CacheSavingData {
291 function_ids: OrderedHashMap<FunctionId, FunctionIdCached>,
292 location_ids: OrderedHashMap<LocationId, LocationIdCached>,
293 lookups: CacheLookups,
294}
295impl Deref for CacheSavingData {
296 type Target = CacheLookups;
297
298 fn deref(&self) -> &Self::Target {
299 &self.lookups
300 }
301}
302impl DerefMut for CacheSavingData {
303 fn deref_mut(&mut self) -> &mut Self::Target {
304 &mut self.lookups
305 }
306}
307
308#[derive(Serialize, Deserialize, Default)]
310struct CacheLookups {
311 function_ids_lookup: Vec<FunctionCached>,
312 location_ids_lookup: Vec<LocationCached>,
313}
314
315struct SemanticCacheLoadingContext<'db> {
317 db: &'db dyn SemanticGroup,
318 data: SemanticCacheLoadingData,
319 defs_loading_data: Arc<DefCacheLoadingData>,
320}
321
322impl Deref for SemanticCacheLoadingContext<'_> {
323 type Target = SemanticCacheLoadingData;
324
325 fn deref(&self) -> &Self::Target {
326 &self.data
327 }
328}
329impl DerefMut for SemanticCacheLoadingContext<'_> {
330 fn deref_mut(&mut self) -> &mut Self::Target {
331 &mut self.data
332 }
333}
334
335struct SemanticCacheLoadingData {
337 function_ids: OrderedHashMap<SemanticFunctionIdCached, semantic::FunctionId>,
338 type_ids: OrderedHashMap<TypeIdCached, TypeId>,
339 impl_ids: OrderedHashMap<ImplIdCached, ImplId>,
340 lookups: SemanticCacheLookups,
341}
342
343impl SemanticCacheLoadingData {
344 fn new(lookups: SemanticCacheLookups) -> Self {
345 Self {
346 function_ids: OrderedHashMap::default(),
347 type_ids: OrderedHashMap::default(),
348 impl_ids: OrderedHashMap::default(),
349 lookups,
350 }
351 }
352}
353
354impl Deref for SemanticCacheLoadingData {
355 type Target = SemanticCacheLookups;
356
357 fn deref(&self) -> &Self::Target {
358 &self.lookups
359 }
360}
361impl DerefMut for SemanticCacheLoadingData {
362 fn deref_mut(&mut self) -> &mut Self::Target {
363 &mut self.lookups
364 }
365}
366
367struct SemanticCacheSavingContext<'db> {
369 db: &'db dyn SemanticGroup,
370 data: SemanticCacheSavingData,
371 defs_ctx: DefCacheSavingContext<'db>,
372}
373impl Deref for SemanticCacheSavingContext<'_> {
374 type Target = SemanticCacheSavingData;
375
376 fn deref(&self) -> &Self::Target {
377 &self.data
378 }
379}
380impl DerefMut for SemanticCacheSavingContext<'_> {
381 fn deref_mut(&mut self) -> &mut Self::Target {
382 &mut self.data
383 }
384}
385
386#[derive(Default)]
388struct SemanticCacheSavingData {
389 function_ids: OrderedHashMap<semantic::FunctionId, SemanticFunctionIdCached>,
390
391 type_ids: OrderedHashMap<TypeId, TypeIdCached>,
392
393 impl_ids: OrderedHashMap<ImplId, ImplIdCached>,
394
395 lookups: SemanticCacheLookups,
396}
397
398impl Deref for SemanticCacheSavingData {
399 type Target = SemanticCacheLookups;
400
401 fn deref(&self) -> &Self::Target {
402 &self.lookups
403 }
404}
405impl DerefMut for SemanticCacheSavingData {
406 fn deref_mut(&mut self) -> &mut Self::Target {
407 &mut self.lookups
408 }
409}
410
411#[derive(Serialize, Deserialize, Default)]
413struct SemanticCacheLookups {
414 function_ids_lookup: Vec<SemanticFunctionCached>,
415 type_ids_lookup: Vec<TypeCached>,
416 impl_ids_lookup: Vec<ImplCached>,
417}
418
419#[derive(Serialize, Deserialize, Hash, Eq, PartialEq)]
422enum DefsFunctionWithBodyIdCached {
423 Free(LanguageElementCached),
424 Impl(LanguageElementCached),
425 Trait(LanguageElementCached),
426}
427impl DefsFunctionWithBodyIdCached {
428 fn new(id: defs::ids::FunctionWithBodyId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
429 match id {
430 defs::ids::FunctionWithBodyId::Free(id) => DefsFunctionWithBodyIdCached::Free(
431 LanguageElementCached::new(id, &mut ctx.defs_ctx),
432 ),
433 defs::ids::FunctionWithBodyId::Impl(id) => DefsFunctionWithBodyIdCached::Impl(
434 LanguageElementCached::new(id, &mut ctx.defs_ctx),
435 ),
436 defs::ids::FunctionWithBodyId::Trait(id) => DefsFunctionWithBodyIdCached::Trait(
437 LanguageElementCached::new(id, &mut ctx.defs_ctx),
438 ),
439 }
440 }
441
442 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> defs::ids::FunctionWithBodyId {
443 match self {
444 DefsFunctionWithBodyIdCached::Free(id) => {
445 let (module_file_id, function_stable_ptr) = id.get_embedded(&ctx.defs_loading_data);
446 defs::ids::FunctionWithBodyId::Free(
447 FreeFunctionLongId(module_file_id, FunctionWithBodyPtr(function_stable_ptr))
448 .intern(ctx.db),
449 )
450 }
451 DefsFunctionWithBodyIdCached::Impl(id) => {
452 let (module_file_id, function_stable_ptr) = id.get_embedded(&ctx.defs_loading_data);
453 defs::ids::FunctionWithBodyId::Impl(
454 ImplFunctionLongId(module_file_id, FunctionWithBodyPtr(function_stable_ptr))
455 .intern(ctx.db),
456 )
457 }
458 DefsFunctionWithBodyIdCached::Trait(id) => {
459 let (module_file_id, function_stable_ptr) = id.get_embedded(&ctx.defs_loading_data);
460 defs::ids::FunctionWithBodyId::Trait(
461 TraitFunctionLongId(module_file_id, TraitItemFunctionPtr(function_stable_ptr))
462 .intern(ctx.db),
463 )
464 }
465 }
466 }
467}
468
469#[derive(Serialize, Deserialize)]
471struct MultiLoweringCached {
472 main_lowering: LoweredCached,
473 generated_lowerings: Vec<(GeneratedFunctionKeyCached, LoweredCached)>,
474}
475impl MultiLoweringCached {
476 fn new(lowering: MultiLowering, ctx: &mut CacheSavingContext<'_>) -> Self {
477 Self {
478 main_lowering: LoweredCached::new(lowering.main_lowering, ctx),
479 generated_lowerings: lowering
480 .generated_lowerings
481 .into_iter()
482 .map(|(key, lowered)| {
483 (GeneratedFunctionKeyCached::new(key, ctx), LoweredCached::new(lowered, ctx))
484 })
485 .collect(),
486 }
487 }
488 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> MultiLowering {
489 MultiLowering {
490 main_lowering: self.main_lowering.embed(ctx),
491 generated_lowerings: self
492 .generated_lowerings
493 .into_iter()
494 .map(|(key, lowered)| (key.embed(ctx), lowered.embed(ctx)))
495 .collect(),
496 }
497 }
498}
499
500#[derive(Serialize, Deserialize)]
501struct LoweredCached {
502 signature: SignatureCached,
504 variables: Vec<VariableCached>,
506 blocks: Vec<BlockCached>,
508 parameters: Vec<usize>,
510}
511impl LoweredCached {
512 fn new(lowered: Lowered, ctx: &mut CacheSavingContext<'_>) -> Self {
513 Self {
514 signature: SignatureCached::new(lowered.signature, ctx),
515 variables: lowered
516 .variables
517 .into_iter()
518 .map(|var| VariableCached::new(var.1, ctx))
519 .collect(),
520 blocks: lowered
521 .blocks
522 .into_iter()
523 .map(|block: (BlockId, &Block)| BlockCached::new(block.1.clone(), ctx))
524 .collect(),
525 parameters: lowered.parameters.iter().map(|var| var.index()).collect(),
526 }
527 }
528 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> Lowered {
529 ctx.lowered_variables_id.clear();
530 let mut variables = Arena::new();
531 for var in self.variables {
532 let id = variables.alloc(var.embed(ctx));
533 ctx.lowered_variables_id.push(id);
534 }
535
536 let mut blocks = BlocksBuilder::new();
537 for block in self.blocks {
538 blocks.alloc(block.embed(ctx));
539 }
540 Lowered {
541 diagnostics: Default::default(),
542 signature: self.signature.embed(ctx),
543 variables,
544 blocks: blocks.build().unwrap(),
545 parameters: self
546 .parameters
547 .into_iter()
548 .map(|var_id| ctx.lowered_variables_id[var_id])
549 .collect(),
550 }
551 }
552}
553
554#[derive(Serialize, Deserialize)]
555struct SignatureCached {
556 params: Vec<ExprVarMemberPathCached>,
558 extra_rets: Vec<ExprVarMemberPathCached>,
560 return_type: TypeIdCached,
562 implicits: Vec<TypeIdCached>,
564 panicable: bool,
566 location: LocationIdCached,
567}
568impl SignatureCached {
569 fn new(signature: Signature, ctx: &mut CacheSavingContext<'_>) -> Self {
570 Self {
571 params: signature
572 .params
573 .into_iter()
574 .map(|var| ExprVarMemberPathCached::new(var, &mut ctx.semantic_ctx))
575 .collect(),
576 extra_rets: signature
577 .extra_rets
578 .into_iter()
579 .map(|var| ExprVarMemberPathCached::new(var, &mut ctx.semantic_ctx))
580 .collect(),
581
582 return_type: TypeIdCached::new(signature.return_type, &mut ctx.semantic_ctx),
583 implicits: signature
584 .implicits
585 .into_iter()
586 .map(|ty| TypeIdCached::new(ty, &mut ctx.semantic_ctx))
587 .collect(),
588 panicable: signature.panicable,
589 location: LocationIdCached::new(signature.location, ctx),
590 }
591 }
592 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> Signature {
593 Signature {
594 params: self.params.into_iter().map(|var| var.embed(&mut ctx.semantic_ctx)).collect(),
595 extra_rets: self
596 .extra_rets
597 .into_iter()
598 .map(|var| var.embed(&mut ctx.semantic_ctx))
599 .collect(),
600 return_type: self.return_type.embed(&mut ctx.semantic_ctx),
601 implicits: self
602 .implicits
603 .into_iter()
604 .map(|ty| ty.embed(&mut ctx.semantic_ctx))
605 .collect(),
606 panicable: self.panicable,
607 location: self.location.embed(ctx),
608 }
609 }
610}
611
612#[derive(Serialize, Deserialize)]
613enum ExprVarMemberPathCached {
614 Var(ExprVarCached),
615 Member {
616 parent: Box<ExprVarMemberPathCached>,
617 member_id: LanguageElementCached,
618 concrete_struct_id: ConcreteStructCached,
619 stable_ptr: SyntaxStablePtrIdCached,
620 ty: TypeIdCached,
621 },
622}
623impl ExprVarMemberPathCached {
624 fn new(
625 expr_var_member_path: semantic::ExprVarMemberPath,
626 ctx: &mut SemanticCacheSavingContext<'_>,
627 ) -> Self {
628 match expr_var_member_path {
629 semantic::ExprVarMemberPath::Var(var) => {
630 ExprVarMemberPathCached::Var(ExprVarCached::new(var, ctx))
631 }
632 semantic::ExprVarMemberPath::Member {
633 parent,
634 member_id,
635 concrete_struct_id,
636 stable_ptr,
637 ty,
638 } => ExprVarMemberPathCached::Member {
639 parent: Box::new(ExprVarMemberPathCached::new(*parent, ctx)),
640 member_id: LanguageElementCached::new(member_id, &mut ctx.defs_ctx),
641 concrete_struct_id: ConcreteStructCached::new(concrete_struct_id, ctx),
642 stable_ptr: SyntaxStablePtrIdCached::new(stable_ptr.untyped(), &mut ctx.defs_ctx),
643 ty: TypeIdCached::new(ty, ctx),
644 },
645 }
646 }
647 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> semantic::ExprVarMemberPath {
648 match self {
649 ExprVarMemberPathCached::Var(var) => semantic::ExprVarMemberPath::Var(var.embed(ctx)),
650 ExprVarMemberPathCached::Member {
651 parent,
652 member_id,
653 concrete_struct_id,
654 stable_ptr,
655 ty,
656 } => {
657 let parent = Box::new(parent.embed(ctx));
658 let (module_file_id, member_stable_ptr) =
659 member_id.get_embedded(&ctx.defs_loading_data);
660 let member_id =
661 MemberLongId(module_file_id, MemberPtr(member_stable_ptr)).intern(ctx.db);
662 semantic::ExprVarMemberPath::Member {
663 parent,
664 member_id,
665 concrete_struct_id: concrete_struct_id.embed(ctx),
666 stable_ptr: ExprPtr(stable_ptr.get_embedded(&ctx.defs_loading_data)),
667 ty: ty.embed(ctx),
668 }
669 }
670 }
671 }
672}
673
674#[derive(Serialize, Deserialize)]
675struct ExprVarCached {
676 var: SemanticVarIdCached,
677 ty: TypeIdCached,
679 stable_ptr: SyntaxStablePtrIdCached,
680}
681impl ExprVarCached {
682 fn new(expr_var: semantic::ExprVar, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
683 Self {
684 var: SemanticVarIdCached::new(expr_var.var, ctx),
685 ty: TypeIdCached::new(expr_var.ty, ctx),
686 stable_ptr: SyntaxStablePtrIdCached::new(
687 expr_var.stable_ptr.untyped(),
688 &mut ctx.defs_ctx,
689 ),
690 }
691 }
692 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> semantic::ExprVar {
693 semantic::ExprVar {
694 var: self.var.embed(ctx),
695 ty: self.ty.embed(ctx),
696 stable_ptr: ExprPtr(self.stable_ptr.get_embedded(&ctx.defs_loading_data)),
697 }
698 }
699}
700
701#[derive(Serialize, Deserialize)]
702enum SemanticVarIdCached {
703 Param(SemanticParamIdCached),
704 Local(SemanticLocalVarIdCached),
705 Item(SemanticStatementItemIdCached),
706}
707impl SemanticVarIdCached {
708 fn new(var_id: semantic::VarId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
709 match var_id {
710 semantic::VarId::Param(id) => {
711 SemanticVarIdCached::Param(SemanticParamIdCached::new(id, ctx))
712 }
713 semantic::VarId::Local(id) => {
714 SemanticVarIdCached::Local(SemanticLocalVarIdCached::new(id, ctx))
715 }
716 semantic::VarId::Item(id) => {
717 SemanticVarIdCached::Item(SemanticStatementItemIdCached::new(id, ctx))
718 }
719 }
720 }
721 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> semantic::VarId {
722 match self {
723 SemanticVarIdCached::Param(id) => semantic::VarId::Param(id.embed(ctx)),
724 SemanticVarIdCached::Local(id) => semantic::VarId::Local(id.embed(ctx)),
725 SemanticVarIdCached::Item(id) => semantic::VarId::Item(id.embed(ctx)),
726 }
727 }
728}
729
730#[derive(Serialize, Deserialize)]
731struct SemanticParamIdCached {
732 language_element: LanguageElementCached,
733}
734impl SemanticParamIdCached {
735 fn new(param_id: semantic::ParamId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
736 Self { language_element: LanguageElementCached::new(param_id, &mut ctx.defs_ctx) }
737 }
738 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> semantic::ParamId {
739 let (module_id, stable_ptr) = self.language_element.get_embedded(&ctx.defs_loading_data);
740 ParamLongId(module_id, ParamPtr(stable_ptr)).intern(ctx.db)
741 }
742}
743
744#[derive(Serialize, Deserialize)]
745struct SemanticLocalVarIdCached {
746 language_element: LanguageElementCached,
747}
748impl SemanticLocalVarIdCached {
749 fn new(local_var_id: LocalVarId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
750 Self { language_element: LanguageElementCached::new(local_var_id, &mut ctx.defs_ctx) }
751 }
752 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> LocalVarId {
753 let (module_id, stable_ptr) = self.language_element.get_embedded(&ctx.defs_loading_data);
754 LocalVarLongId(module_id, TerminalIdentifierPtr(stable_ptr)).intern(ctx.db)
755 }
756}
757
758#[derive(Serialize, Deserialize)]
759enum SemanticStatementItemIdCached {
760 Constant(LanguageElementCached),
761 Use(LanguageElementCached),
762}
763
764impl SemanticStatementItemIdCached {
765 fn new(item_id: StatementItemId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
766 match item_id {
767 StatementItemId::Constant(id) => SemanticStatementItemIdCached::Constant(
768 LanguageElementCached::new(id, &mut ctx.defs_ctx),
769 ),
770 StatementItemId::Use(id) => SemanticStatementItemIdCached::Use(
771 LanguageElementCached::new(id, &mut ctx.defs_ctx),
772 ),
773 }
774 }
775 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> StatementItemId {
776 match self {
777 SemanticStatementItemIdCached::Constant(id) => {
778 let (module_id, stable_ptr) = id.get_embedded(&ctx.defs_loading_data);
779 StatementItemId::Constant(
780 StatementConstLongId(module_id, ItemConstantPtr(stable_ptr)).intern(ctx.db),
781 )
782 }
783 SemanticStatementItemIdCached::Use(id) => {
784 let (module_id, stable_ptr) = id.get_embedded(&ctx.defs_loading_data);
785 StatementItemId::Use(
786 StatementUseLongId(module_id, UsePathLeafPtr(stable_ptr)).intern(ctx.db),
787 )
788 }
789 }
790 }
791}
792
793#[derive(Serialize, Deserialize)]
794struct VariableCached {
795 droppable: Option<ImplIdCached>,
796 copyable: Option<ImplIdCached>,
798 destruct_impl: Option<ImplIdCached>,
800 panic_destruct_impl: Option<ImplIdCached>,
802 ty: TypeIdCached,
804 location: LocationIdCached,
805}
806impl VariableCached {
807 fn new(variable: Variable, ctx: &mut CacheSavingContext<'_>) -> Self {
808 let TypeInfo { droppable, copyable, destruct_impl, panic_destruct_impl } = variable.info;
809 Self {
810 droppable: droppable
811 .map(|impl_id| ImplIdCached::new(impl_id, &mut ctx.semantic_ctx))
812 .ok(),
813 copyable: copyable
814 .map(|impl_id| ImplIdCached::new(impl_id, &mut ctx.semantic_ctx))
815 .ok(),
816 destruct_impl: destruct_impl
817 .map(|impl_id| ImplIdCached::new(impl_id, &mut ctx.semantic_ctx))
818 .ok(),
819 panic_destruct_impl: panic_destruct_impl
820 .map(|impl_id| ImplIdCached::new(impl_id, &mut ctx.semantic_ctx))
821 .ok(),
822 ty: TypeIdCached::new(variable.ty, &mut ctx.semantic_ctx),
823 location: LocationIdCached::new(variable.location, ctx),
824 }
825 }
826 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> Variable {
827 Variable {
828 ty: self.ty.embed(&mut ctx.semantic_ctx),
829 location: self.location.embed(ctx),
830 info: TypeInfo {
831 droppable: self
832 .droppable
833 .map(|impl_id| impl_id.embed(&mut ctx.semantic_ctx))
834 .ok_or(InferenceError::Reported(skip_diagnostic())),
835 copyable: self
836 .copyable
837 .map(|impl_id| impl_id.embed(&mut ctx.semantic_ctx))
838 .ok_or(InferenceError::Reported(skip_diagnostic())),
839 destruct_impl: self
840 .destruct_impl
841 .map(|impl_id| impl_id.embed(&mut ctx.semantic_ctx))
842 .ok_or(InferenceError::Reported(skip_diagnostic())),
843 panic_destruct_impl: self
844 .panic_destruct_impl
845 .map(|impl_id| impl_id.embed(&mut ctx.semantic_ctx))
846 .ok_or(InferenceError::Reported(skip_diagnostic())),
847 },
848 }
849 }
850}
851
852#[derive(Serialize, Deserialize)]
853struct VarUsageCached {
854 var_id: usize,
856 location: LocationIdCached,
858}
859
860impl VarUsageCached {
861 fn new(var_usage: VarUsage, ctx: &mut CacheSavingContext<'_>) -> Self {
862 Self {
863 var_id: var_usage.var_id.index(),
864 location: LocationIdCached::new(var_usage.location, ctx),
865 }
866 }
867 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> VarUsage {
868 VarUsage {
869 var_id: ctx.lowered_variables_id[self.var_id],
870 location: self.location.embed(ctx),
871 }
872 }
873}
874
875#[derive(Serialize, Deserialize)]
876struct BlockCached {
877 statements: Vec<StatementCached>,
879 end: BlockEndCached,
881}
882impl BlockCached {
883 fn new(block: Block, ctx: &mut CacheSavingContext<'_>) -> Self {
884 Self {
885 statements: block
886 .statements
887 .into_iter()
888 .map(|stmt| StatementCached::new(stmt, ctx))
889 .collect(),
890 end: BlockEndCached::new(block.end, ctx),
891 }
892 }
893 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> Block {
894 Block {
895 statements: self.statements.into_iter().map(|stmt| stmt.embed(ctx)).collect(),
896 end: self.end.embed(ctx),
897 }
898 }
899}
900#[derive(Serialize, Deserialize)]
901enum BlockEndCached {
902 NotSet,
905 Return(Vec<VarUsageCached>, LocationIdCached),
907 Panic(VarUsageCached),
909 Goto(usize, VarRemappingCached),
911 Match {
912 info: MatchInfoCached,
913 },
914}
915impl BlockEndCached {
916 fn new(block_end: BlockEnd, ctx: &mut CacheSavingContext<'_>) -> Self {
917 match block_end {
918 BlockEnd::Return(returns, location) => BlockEndCached::Return(
919 returns.iter().map(|var| VarUsageCached::new(*var, ctx)).collect(),
920 LocationIdCached::new(location, ctx),
921 ),
922 BlockEnd::Panic(data) => BlockEndCached::Panic(VarUsageCached::new(data, ctx)),
923 BlockEnd::Goto(block_id, remapping) => {
924 BlockEndCached::Goto(block_id.0, VarRemappingCached::new(remapping, ctx))
925 }
926 BlockEnd::NotSet => BlockEndCached::NotSet,
927 BlockEnd::Match { info } => {
928 BlockEndCached::Match { info: MatchInfoCached::new(info, ctx) }
929 }
930 }
931 }
932 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> BlockEnd {
933 match self {
934 BlockEndCached::Return(returns, location) => BlockEnd::Return(
935 returns.into_iter().map(|var_usage| var_usage.embed(ctx)).collect(),
936 location.embed(ctx),
937 ),
938 BlockEndCached::Panic(var_id) => BlockEnd::Panic(var_id.embed(ctx)),
939 BlockEndCached::Goto(block_id, remapping) => {
940 BlockEnd::Goto(BlockId(block_id), remapping.embed(ctx))
941 }
942 BlockEndCached::NotSet => BlockEnd::NotSet,
943 BlockEndCached::Match { info } => BlockEnd::Match { info: info.embed(ctx) },
944 }
945 }
946}
947
948#[derive(Serialize, Deserialize)]
949struct VarRemappingCached {
950 remapping: OrderedHashMap<usize, VarUsageCached>,
952}
953impl VarRemappingCached {
954 fn new(var_remapping: VarRemapping, ctx: &mut CacheSavingContext<'_>) -> Self {
955 Self {
956 remapping: var_remapping
957 .iter()
958 .map(|(dst, src)| (dst.index(), VarUsageCached::new(*src, ctx)))
959 .collect(),
960 }
961 }
962 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> VarRemapping {
963 let mut remapping = OrderedHashMap::default();
964 for (dst, src) in self.remapping {
965 remapping.insert(ctx.lowered_variables_id[dst], src.embed(ctx));
966 }
967 VarRemapping { remapping }
968 }
969}
970
971#[derive(Serialize, Deserialize)]
972enum MatchInfoCached {
973 Enum(MatchEnumInfoCached),
974 Extern(MatchExternInfoCached),
975 Value(MatchEnumValueCached),
976}
977impl MatchInfoCached {
978 fn new(match_info: MatchInfo, ctx: &mut CacheSavingContext<'_>) -> Self {
979 match match_info {
980 MatchInfo::Enum(info) => MatchInfoCached::Enum(MatchEnumInfoCached::new(info, ctx)),
981 MatchInfo::Extern(info) => {
982 MatchInfoCached::Extern(MatchExternInfoCached::new(info, ctx))
983 }
984 MatchInfo::Value(info) => MatchInfoCached::Value(MatchEnumValueCached::new(info, ctx)),
985 }
986 }
987 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> MatchInfo {
988 match self {
989 MatchInfoCached::Enum(info) => MatchInfo::Enum(info.embed(ctx)),
990 MatchInfoCached::Extern(info) => MatchInfo::Extern(info.embed(ctx)),
991 MatchInfoCached::Value(info) => MatchInfo::Value(info.embed(ctx)),
992 }
993 }
994}
995
996#[derive(Serialize, Deserialize)]
997struct MatchEnumInfoCached {
998 concrete_enum_id: ConcreteEnumCached,
999 input: VarUsageCached,
1001 arms: Vec<MatchArmCached>,
1004 location: LocationIdCached,
1005}
1006impl MatchEnumInfoCached {
1007 fn new(match_enum_info: MatchEnumInfo, ctx: &mut CacheSavingContext<'_>) -> Self {
1008 Self {
1009 concrete_enum_id: ConcreteEnumCached::new(
1010 match_enum_info.concrete_enum_id,
1011 &mut ctx.semantic_ctx,
1012 ),
1013 input: VarUsageCached::new(match_enum_info.input, ctx),
1014 arms: match_enum_info
1015 .arms
1016 .into_iter()
1017 .map(|arm| MatchArmCached::new(arm, ctx))
1018 .collect(),
1019 location: LocationIdCached::new(match_enum_info.location, ctx),
1020 }
1021 }
1022 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> MatchEnumInfo {
1023 MatchEnumInfo {
1024 concrete_enum_id: self.concrete_enum_id.embed(&mut ctx.semantic_ctx),
1025 input: self.input.embed(ctx),
1026 arms: self.arms.into_iter().map(|arm| arm.embed(ctx)).collect(),
1027 location: self.location.embed(ctx),
1028 }
1029 }
1030}
1031
1032#[derive(Serialize, Deserialize)]
1033struct MatchExternInfoCached {
1034 function: FunctionIdCached,
1036 inputs: Vec<VarUsageCached>,
1038 arms: Vec<MatchArmCached>,
1041 location: LocationIdCached,
1042}
1043
1044impl MatchExternInfoCached {
1045 fn new(match_extern_info: MatchExternInfo, ctx: &mut CacheSavingContext<'_>) -> Self {
1046 Self {
1047 function: FunctionIdCached::new(match_extern_info.function, ctx),
1048 inputs: match_extern_info
1049 .inputs
1050 .iter()
1051 .map(|var| VarUsageCached::new(*var, ctx))
1052 .collect(),
1053 arms: match_extern_info
1054 .arms
1055 .into_iter()
1056 .map(|arm| MatchArmCached::new(arm, ctx))
1057 .collect(),
1058 location: LocationIdCached::new(match_extern_info.location, ctx),
1059 }
1060 }
1061 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> MatchExternInfo {
1062 MatchExternInfo {
1063 function: self.function.embed(ctx),
1064 inputs: self.inputs.into_iter().map(|var_id| var_id.embed(ctx)).collect(),
1065 arms: self.arms.into_iter().map(|arm| arm.embed(ctx)).collect(),
1066 location: self.location.embed(ctx),
1067 }
1068 }
1069}
1070
1071#[derive(Serialize, Deserialize)]
1072struct MatchEnumValueCached {
1073 num_of_arms: usize,
1074
1075 input: VarUsageCached,
1077 arms: Vec<MatchArmCached>,
1079 location: LocationIdCached,
1080}
1081
1082impl MatchEnumValueCached {
1083 fn new(match_enum_value: MatchEnumValue, ctx: &mut CacheSavingContext<'_>) -> Self {
1084 Self {
1085 num_of_arms: match_enum_value.num_of_arms,
1086 input: VarUsageCached::new(match_enum_value.input, ctx),
1087 arms: match_enum_value
1088 .arms
1089 .into_iter()
1090 .map(|arm| MatchArmCached::new(arm, ctx))
1091 .collect(),
1092 location: LocationIdCached::new(match_enum_value.location, ctx),
1093 }
1094 }
1095 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> MatchEnumValue {
1096 MatchEnumValue {
1097 num_of_arms: self.num_of_arms,
1098 input: self.input.embed(ctx),
1099 arms: self.arms.into_iter().map(|arm| arm.embed(ctx)).collect(),
1100 location: self.location.embed(ctx),
1101 }
1102 }
1103}
1104#[derive(Serialize, Deserialize)]
1106struct MatchArmCached {
1107 arm_selector: MatchArmSelectorCached,
1109
1110 block_id: usize,
1112
1113 var_ids: Vec<usize>,
1115}
1116
1117impl MatchArmCached {
1118 fn new(match_arm: MatchArm, ctx: &mut CacheSavingContext<'_>) -> Self {
1119 Self {
1120 arm_selector: MatchArmSelectorCached::new(
1121 match_arm.arm_selector,
1122 &mut ctx.semantic_ctx,
1123 ),
1124 block_id: match_arm.block_id.0,
1125 var_ids: match_arm.var_ids.iter().map(|var| var.index()).collect(),
1126 }
1127 }
1128 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> MatchArm {
1129 MatchArm {
1130 arm_selector: self.arm_selector.embed(ctx),
1131 block_id: BlockId(self.block_id),
1132 var_ids: self
1133 .var_ids
1134 .into_iter()
1135 .map(|var_id| ctx.lowered_variables_id[var_id])
1136 .collect(),
1137 }
1138 }
1139}
1140
1141#[derive(Serialize, Deserialize)]
1142enum MatchArmSelectorCached {
1143 VariantId(ConcreteVariantCached),
1144 Value(usize),
1145}
1146
1147impl MatchArmSelectorCached {
1148 fn new(match_arm_selector: MatchArmSelector, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
1149 match match_arm_selector {
1150 MatchArmSelector::VariantId(variant_id) => {
1151 MatchArmSelectorCached::VariantId(ConcreteVariantCached::new(variant_id, ctx))
1152 }
1153 MatchArmSelector::Value(value) => MatchArmSelectorCached::Value(value.value),
1154 }
1155 }
1156 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> MatchArmSelector {
1157 match self {
1158 MatchArmSelectorCached::VariantId(variant_id) => {
1159 MatchArmSelector::VariantId(variant_id.embed(&mut ctx.semantic_ctx))
1160 }
1161 MatchArmSelectorCached::Value(value) => {
1162 MatchArmSelector::Value(ValueSelectorArm { value })
1163 }
1164 }
1165 }
1166}
1167
1168#[derive(Serialize, Deserialize)]
1169enum StatementCached {
1170 Const(StatementConstCached),
1172
1173 Call(StatementCallCached),
1175
1176 StructConstruct(StatementStructConstructCached),
1178 StructDestructure(StatementStructDestructureCached),
1179
1180 EnumConstruct(StatementEnumConstructCached),
1182
1183 Snapshot(StatementSnapshotCached),
1184 Desnap(StatementDesnapCached),
1185}
1186
1187impl StatementCached {
1188 fn new(stmt: Statement, ctx: &mut CacheSavingContext<'_>) -> Self {
1189 match stmt {
1190 Statement::Const(stmt) => StatementCached::Const(StatementConstCached::new(stmt, ctx)),
1191 Statement::Call(stmt) => StatementCached::Call(StatementCallCached::new(stmt, ctx)),
1192 Statement::StructConstruct(stmt) => {
1193 StatementCached::StructConstruct(StatementStructConstructCached::new(stmt, ctx))
1194 }
1195 Statement::StructDestructure(stmt) => {
1196 StatementCached::StructDestructure(StatementStructDestructureCached::new(stmt, ctx))
1197 }
1198 Statement::EnumConstruct(stmt) => {
1199 StatementCached::EnumConstruct(StatementEnumConstructCached::new(stmt, ctx))
1200 }
1201 Statement::Snapshot(stmt) => {
1202 StatementCached::Snapshot(StatementSnapshotCached::new(stmt, ctx))
1203 }
1204 Statement::Desnap(stmt) => {
1205 StatementCached::Desnap(StatementDesnapCached::new(stmt, ctx))
1206 }
1207 }
1208 }
1209 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> Statement {
1210 match self {
1211 StatementCached::Const(stmt) => Statement::Const(stmt.embed(ctx)),
1212 StatementCached::Call(stmt) => Statement::Call(stmt.embed(ctx)),
1213 StatementCached::StructConstruct(stmt) => Statement::StructConstruct(stmt.embed(ctx)),
1214 StatementCached::StructDestructure(stmt) => {
1215 Statement::StructDestructure(stmt.embed(ctx))
1216 }
1217 StatementCached::EnumConstruct(stmt) => Statement::EnumConstruct(stmt.embed(ctx)),
1218 StatementCached::Snapshot(stmt) => Statement::Snapshot(stmt.embed(ctx)),
1219 StatementCached::Desnap(stmt) => Statement::Desnap(stmt.embed(ctx)),
1220 }
1221 }
1222}
1223
1224#[derive(Serialize, Deserialize)]
1225struct StatementConstCached {
1226 value: ConstValueCached,
1228 output: usize,
1230}
1231impl StatementConstCached {
1232 fn new(stmt: StatementConst, ctx: &mut CacheSavingContext<'_>) -> Self {
1233 Self {
1234 value: ConstValueCached::new(stmt.value, &mut ctx.semantic_ctx),
1235 output: stmt.output.index(),
1236 }
1237 }
1238 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> StatementConst {
1239 StatementConst {
1240 value: self.value.embed(&mut ctx.semantic_ctx),
1241 output: ctx.lowered_variables_id[self.output],
1242 }
1243 }
1244}
1245
1246#[derive(Serialize, Deserialize, Clone)]
1247enum ConstValueCached {
1248 Int(BigInt, TypeIdCached),
1249 Struct(Vec<ConstValueCached>, TypeIdCached),
1250 Enum(ConcreteVariantCached, Box<ConstValueCached>),
1251 NonZero(Box<ConstValueCached>),
1252 Boxed(Box<ConstValueCached>),
1253 Generic(GenericParamCached),
1254 ImplConstant(ImplConstantCached),
1255}
1256impl ConstValueCached {
1257 fn new(const_value_id: ConstValue, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
1258 match const_value_id {
1259 ConstValue::Int(value, ty) => ConstValueCached::Int(value, TypeIdCached::new(ty, ctx)),
1260 ConstValue::Struct(values, ty) => ConstValueCached::Struct(
1261 values.into_iter().map(|v| ConstValueCached::new(v, ctx)).collect(),
1262 TypeIdCached::new(ty, ctx),
1263 ),
1264 ConstValue::Enum(variant, value) => ConstValueCached::Enum(
1265 ConcreteVariantCached::new(variant, ctx),
1266 Box::new(ConstValueCached::new(*value, ctx)),
1267 ),
1268 ConstValue::NonZero(value) => {
1269 ConstValueCached::NonZero(Box::new(ConstValueCached::new(*value, ctx)))
1270 }
1271 ConstValue::Boxed(value) => {
1272 ConstValueCached::Boxed(Box::new(ConstValueCached::new(*value, ctx)))
1273 }
1274 ConstValue::Generic(generic_param) => {
1275 ConstValueCached::Generic(GenericParamCached::new(generic_param, &mut ctx.defs_ctx))
1276 }
1277 ConstValue::ImplConstant(impl_constant_id) => {
1278 ConstValueCached::ImplConstant(ImplConstantCached::new(impl_constant_id, ctx))
1279 }
1280 ConstValue::Var(_, _) | ConstValue::Missing(_) => {
1281 unreachable!(
1282 "Const {:#?} is not supported for caching",
1283 const_value_id.debug(ctx.db.elongate())
1284 )
1285 }
1286 }
1287 }
1288 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> ConstValue {
1289 match self {
1290 ConstValueCached::Int(value, ty) => ConstValue::Int(value, ty.embed(ctx)),
1291 ConstValueCached::Struct(values, ty) => ConstValue::Struct(
1292 values.into_iter().map(|v| v.embed(ctx)).collect(),
1293 ty.embed(ctx),
1294 ),
1295 ConstValueCached::Enum(variant, value) => {
1296 ConstValue::Enum(variant.embed(ctx), Box::new(value.embed(ctx)))
1297 }
1298 ConstValueCached::NonZero(value) => ConstValue::NonZero(Box::new(value.embed(ctx))),
1299 ConstValueCached::Boxed(value) => ConstValue::Boxed(Box::new(value.embed(ctx))),
1300 ConstValueCached::Generic(generic_param) => {
1301 ConstValue::Generic(generic_param.get_embedded(&ctx.defs_loading_data, ctx.db))
1302 }
1303 ConstValueCached::ImplConstant(impl_constant_id) => {
1304 ConstValue::ImplConstant(impl_constant_id.embed(ctx))
1305 }
1306 }
1307 }
1308}
1309
1310#[derive(Serialize, Deserialize, Clone)]
1311struct ImplConstantCached {
1312 impl_id: ImplIdCached,
1313 trait_constant: TraitConstantCached,
1314}
1315impl ImplConstantCached {
1316 fn new(impl_constant_id: ImplConstantId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
1317 Self {
1318 impl_id: ImplIdCached::new(impl_constant_id.impl_id(), ctx),
1319 trait_constant: TraitConstantCached::new(impl_constant_id.trait_constant_id(), ctx),
1320 }
1321 }
1322 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> ImplConstantId {
1323 ImplConstantId::new(self.impl_id.embed(ctx), self.trait_constant.embed(ctx), ctx.db)
1324 }
1325}
1326
1327#[derive(Serialize, Deserialize, Clone)]
1328struct TraitConstantCached {
1329 language_element: LanguageElementCached,
1330}
1331impl TraitConstantCached {
1332 fn new(trait_constant_id: TraitConstantId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
1333 Self { language_element: LanguageElementCached::new(trait_constant_id, &mut ctx.defs_ctx) }
1334 }
1335 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> TraitConstantId {
1336 let (module_id, stable_ptr) = self.language_element.get_embedded(&ctx.defs_loading_data);
1337 TraitConstantLongId(module_id, TraitItemConstantPtr(stable_ptr)).intern(ctx.db)
1338 }
1339}
1340
1341#[derive(Serialize, Deserialize)]
1342struct StatementCallCached {
1343 function: FunctionIdCached,
1345 inputs: Vec<VarUsageCached>,
1347 with_coupon: bool,
1350 outputs: Vec<usize>,
1352 location: LocationIdCached,
1353}
1354impl StatementCallCached {
1355 fn new(stmt: StatementCall, ctx: &mut CacheSavingContext<'_>) -> Self {
1356 Self {
1357 function: FunctionIdCached::new(stmt.function, ctx),
1358 inputs: stmt.inputs.iter().map(|var| VarUsageCached::new(*var, ctx)).collect(),
1359 with_coupon: stmt.with_coupon,
1360 outputs: stmt.outputs.iter().map(|var| var.index()).collect(),
1361 location: LocationIdCached::new(stmt.location, ctx),
1362 }
1363 }
1364 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> StatementCall {
1365 StatementCall {
1366 function: self.function.embed(ctx),
1367 inputs: self.inputs.into_iter().map(|var_id| var_id.embed(ctx)).collect(),
1368 with_coupon: self.with_coupon,
1369 outputs: self
1370 .outputs
1371 .into_iter()
1372 .map(|var_id| ctx.lowered_variables_id[var_id])
1373 .collect(),
1374 location: self.location.embed(ctx),
1375 }
1376 }
1377}
1378
1379#[derive(Serialize, Deserialize, Clone)]
1380enum FunctionCached {
1381 Semantic(SemanticFunctionIdCached),
1383 Generated(GeneratedFunctionCached),
1385}
1386impl FunctionCached {
1387 fn new(function: FunctionLongId, ctx: &mut CacheSavingContext<'_>) -> Self {
1388 match function {
1389 FunctionLongId::Semantic(id) => {
1390 FunctionCached::Semantic(SemanticFunctionIdCached::new(id, &mut ctx.semantic_ctx))
1391 }
1392 FunctionLongId::Generated(id) => {
1393 FunctionCached::Generated(GeneratedFunctionCached::new(id, ctx))
1394 }
1395 FunctionLongId::Specialized(_) => {
1396 unreachable!("Specialization of functions only occurs post concretization.")
1397 }
1398 }
1399 }
1400 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> FunctionId {
1401 match self {
1402 FunctionCached::Semantic(id) => {
1403 FunctionLongId::Semantic(id.embed(&mut ctx.semantic_ctx))
1404 }
1405 FunctionCached::Generated(id) => FunctionLongId::Generated(id.embed(ctx)),
1406 }
1407 .intern(ctx.db)
1408 }
1409}
1410
1411#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1412struct FunctionIdCached(usize);
1413impl FunctionIdCached {
1414 fn new(function_id: FunctionId, ctx: &mut CacheSavingContext<'_>) -> Self {
1415 if let Some(id) = ctx.function_ids.get(&function_id) {
1416 return *id;
1417 }
1418 let function = FunctionCached::new(function_id.lookup_intern(ctx.db), ctx);
1419 let id = FunctionIdCached(ctx.function_ids_lookup.len());
1420 ctx.function_ids_lookup.push(function);
1421 ctx.function_ids.insert(function_id, id);
1422 id
1423 }
1424 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> FunctionId {
1425 if let Some(function_id) = ctx.function_ids.get(&self) {
1426 return *function_id;
1427 }
1428
1429 let function = ctx.function_ids_lookup[self.0].clone();
1430 let function_id = function.embed(ctx);
1431 ctx.function_ids.insert(self, function_id);
1432 function_id
1433 }
1434}
1435
1436#[derive(Serialize, Deserialize, Clone)]
1437struct SemanticFunctionCached {
1438 generic_function: GenericFunctionCached,
1439
1440 generic_args: Vec<GenericArgumentCached>,
1441}
1442impl SemanticFunctionCached {
1443 fn new(
1444 function_id: semantic::FunctionLongId,
1445 ctx: &mut SemanticCacheSavingContext<'_>,
1446 ) -> Self {
1447 let function = function_id.function;
1448 Self {
1449 generic_function: GenericFunctionCached::new(function.generic_function, ctx),
1450 generic_args: function
1451 .generic_args
1452 .into_iter()
1453 .map(|arg| GenericArgumentCached::new(arg, ctx))
1454 .collect(),
1455 }
1456 }
1457 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> semantic::FunctionLongId {
1458 semantic::FunctionLongId {
1459 function: ConcreteFunction {
1460 generic_function: self.generic_function.embed(ctx),
1461 generic_args: self.generic_args.into_iter().map(|arg| arg.embed(ctx)).collect(),
1462 },
1463 }
1464 }
1465}
1466#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1467struct SemanticFunctionIdCached(usize);
1468impl SemanticFunctionIdCached {
1469 fn new(function_id: semantic::FunctionId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
1470 if let Some(id) = ctx.function_ids.get(&function_id) {
1471 return *id;
1472 }
1473 let function = SemanticFunctionCached::new(function_id.lookup_intern(ctx.db), ctx);
1474 let id = SemanticFunctionIdCached(ctx.function_ids_lookup.len());
1475 ctx.function_ids_lookup.push(function);
1476 ctx.function_ids.insert(function_id, id);
1477 id
1478 }
1479 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> semantic::FunctionId {
1480 if let Some(function_id) = ctx.function_ids.get(&self) {
1481 return *function_id;
1482 }
1483
1484 let function = ctx.function_ids_lookup[self.0].clone();
1485 let function_id = function.embed(ctx).intern(ctx.db);
1486 ctx.function_ids.insert(self, function_id);
1487 function_id
1488 }
1489}
1490
1491#[derive(Serialize, Deserialize, Clone)]
1492enum GenericFunctionCached {
1493 Free(LanguageElementCached),
1495 Extern(LanguageElementCached),
1497 Impl(ImplIdCached, LanguageElementCached),
1499}
1500impl GenericFunctionCached {
1501 fn new(generic_function: GenericFunctionId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
1502 match generic_function {
1503 GenericFunctionId::Free(id) => {
1504 GenericFunctionCached::Free(LanguageElementCached::new(id, &mut ctx.defs_ctx))
1505 }
1506 GenericFunctionId::Extern(id) => {
1507 GenericFunctionCached::Extern(LanguageElementCached::new(id, &mut ctx.defs_ctx))
1508 }
1509 GenericFunctionId::Impl(id) => GenericFunctionCached::Impl(
1510 ImplIdCached::new(id.impl_id, ctx),
1511 LanguageElementCached::new(id.function, &mut ctx.defs_ctx),
1512 ),
1513 }
1514 }
1515 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> GenericFunctionId {
1516 match self {
1517 GenericFunctionCached::Free(id) => {
1518 let (module_id, stable_ptr) = id.get_embedded(&ctx.defs_loading_data);
1519 let id =
1520 FreeFunctionLongId(module_id, FunctionWithBodyPtr(stable_ptr)).intern(ctx.db);
1521 GenericFunctionId::Free(id)
1522 }
1523 GenericFunctionCached::Extern(id) => {
1524 let (module_id, stable_ptr) = id.get_embedded(&ctx.defs_loading_data);
1525 let id = ExternFunctionLongId(module_id, ItemExternFunctionPtr(stable_ptr))
1526 .intern(ctx.db);
1527 GenericFunctionId::Extern(id)
1528 }
1529 GenericFunctionCached::Impl(id, name) => {
1530 let impl_id = id.embed(ctx);
1531 let (module_file_id, stable_ptr) = name.get_embedded(&ctx.defs_loading_data);
1532 let trait_function_id =
1533 TraitFunctionLongId(module_file_id, TraitItemFunctionPtr(stable_ptr))
1534 .intern(ctx.db);
1535
1536 GenericFunctionId::Impl(ImplGenericFunctionId {
1537 impl_id,
1538 function: trait_function_id,
1539 })
1540 }
1541 }
1542 }
1543}
1544
1545#[derive(Serialize, Deserialize, Clone)]
1546struct GeneratedFunctionCached {
1547 parent: SemanticConcreteFunctionWithBodyCached,
1548 key: GeneratedFunctionKeyCached,
1549}
1550impl GeneratedFunctionCached {
1551 fn new(function: GeneratedFunction, ctx: &mut CacheSavingContext<'_>) -> Self {
1552 Self {
1553 parent: SemanticConcreteFunctionWithBodyCached::new(
1554 function.parent,
1555 &mut ctx.semantic_ctx,
1556 ),
1557 key: GeneratedFunctionKeyCached::new(function.key, ctx),
1558 }
1559 }
1560 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> GeneratedFunction {
1561 GeneratedFunction {
1562 parent: self.parent.embed(&mut ctx.semantic_ctx),
1563 key: self.key.embed(ctx),
1564 }
1565 }
1566}
1567#[derive(Serialize, Deserialize, Clone)]
1568struct SemanticConcreteFunctionWithBodyCached {
1569 generic_function: GenericFunctionWithBodyCached,
1570 generic_args: Vec<GenericArgumentCached>,
1571}
1572impl SemanticConcreteFunctionWithBodyCached {
1573 fn new(
1574 function_id: semantic::ConcreteFunctionWithBodyId,
1575 ctx: &mut SemanticCacheSavingContext<'_>,
1576 ) -> Self {
1577 Self {
1578 generic_function: GenericFunctionWithBodyCached::new(
1579 function_id.generic_function(ctx.db),
1580 ctx,
1581 ),
1582 generic_args: function_id
1583 .lookup_intern(ctx.db)
1584 .generic_args
1585 .into_iter()
1586 .map(|arg| GenericArgumentCached::new(arg, ctx))
1587 .collect(),
1588 }
1589 }
1590 fn embed(
1591 self,
1592 ctx: &mut SemanticCacheLoadingContext<'_>,
1593 ) -> semantic::ConcreteFunctionWithBodyId {
1594 let generic_function = self.generic_function.embed(ctx);
1595 let generic_args = self.generic_args.into_iter().map(|arg| arg.embed(ctx)).collect();
1596 ConcreteFunctionWithBody { generic_function, generic_args }.intern(ctx.db)
1597 }
1598}
1599
1600#[derive(Serialize, Deserialize, Clone)]
1601enum GenericFunctionWithBodyCached {
1602 Free(LanguageElementCached),
1603 Impl(ConcreteImplCached, ImplFunctionBodyCached),
1604 Trait(ConcreteTraitCached, LanguageElementCached),
1605}
1606
1607impl GenericFunctionWithBodyCached {
1608 fn new(
1609 generic_function: GenericFunctionWithBodyId,
1610 ctx: &mut SemanticCacheSavingContext<'_>,
1611 ) -> Self {
1612 match generic_function {
1613 GenericFunctionWithBodyId::Free(id) => GenericFunctionWithBodyCached::Free(
1614 LanguageElementCached::new(id, &mut ctx.defs_ctx),
1615 ),
1616 GenericFunctionWithBodyId::Impl(id) => GenericFunctionWithBodyCached::Impl(
1617 ConcreteImplCached::new(id.concrete_impl_id, ctx),
1618 ImplFunctionBodyCached::new(id.function_body, ctx),
1619 ),
1620 GenericFunctionWithBodyId::Trait(id) => GenericFunctionWithBodyCached::Trait(
1621 ConcreteTraitCached::new(id.concrete_trait(ctx.db), ctx),
1622 LanguageElementCached::new(id.trait_function(ctx.db), &mut ctx.defs_ctx),
1623 ),
1624 }
1625 }
1626 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> GenericFunctionWithBodyId {
1627 match self {
1628 GenericFunctionWithBodyCached::Free(id) => {
1629 let (module_id, stable_ptr) = id.get_embedded(&ctx.defs_loading_data);
1630 let id =
1631 FreeFunctionLongId(module_id, FunctionWithBodyPtr(stable_ptr)).intern(ctx.db);
1632 GenericFunctionWithBodyId::Free(id)
1633 }
1634 GenericFunctionWithBodyCached::Impl(id, function_body) => {
1635 GenericFunctionWithBodyId::Impl(ImplGenericFunctionWithBodyId {
1637 concrete_impl_id: id.embed(ctx),
1638 function_body: function_body.embed(ctx),
1639 })
1640 }
1641 GenericFunctionWithBodyCached::Trait(id, name) => {
1642 let concrete_trait_id = id.embed(ctx);
1643 let (module_file_id, stable_ptr) = name.get_embedded(&ctx.defs_loading_data);
1644 let trait_function_id =
1645 TraitFunctionLongId(module_file_id, TraitItemFunctionPtr(stable_ptr))
1646 .intern(ctx.db);
1647
1648 GenericFunctionWithBodyId::Trait(
1649 ConcreteTraitGenericFunctionLongId::new(
1650 ctx.db,
1651 concrete_trait_id,
1652 trait_function_id,
1653 )
1654 .intern(ctx.db),
1655 )
1656 }
1657 }
1658 }
1659}
1660
1661#[derive(Serialize, Deserialize, Clone)]
1662enum ImplFunctionBodyCached {
1663 Impl(LanguageElementCached),
1665 Trait(LanguageElementCached),
1667}
1668impl ImplFunctionBodyCached {
1669 fn new(function_body: ImplFunctionBodyId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
1670 match function_body {
1671 ImplFunctionBodyId::Impl(id) => {
1672 ImplFunctionBodyCached::Impl(LanguageElementCached::new(id, &mut ctx.defs_ctx))
1673 }
1674 ImplFunctionBodyId::Trait(id) => {
1675 ImplFunctionBodyCached::Trait(LanguageElementCached::new(id, &mut ctx.defs_ctx))
1676 }
1677 }
1678 }
1679 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> ImplFunctionBodyId {
1680 match self {
1681 ImplFunctionBodyCached::Impl(id) => {
1682 let (module_file_id, stable_ptr) = id.get_embedded(&ctx.defs_loading_data);
1683 ImplFunctionBodyId::Impl(
1684 ImplFunctionLongId(module_file_id, FunctionWithBodyPtr(stable_ptr))
1685 .intern(ctx.db),
1686 )
1687 }
1688 ImplFunctionBodyCached::Trait(id) => {
1689 let (module_file_id, stable_ptr) = id.get_embedded(&ctx.defs_loading_data);
1690 ImplFunctionBodyId::Trait(
1691 TraitFunctionLongId(module_file_id, TraitItemFunctionPtr(stable_ptr))
1692 .intern(ctx.db),
1693 )
1694 }
1695 }
1696 }
1697}
1698
1699#[derive(Serialize, Deserialize, Clone, Hash, PartialEq, Eq)]
1700enum GeneratedFunctionKeyCached {
1701 Loop(SyntaxStablePtrIdCached),
1702 TraitFunc(LanguageElementCached, SyntaxStablePtrIdCached),
1703}
1704
1705impl GeneratedFunctionKeyCached {
1706 fn new(key: GeneratedFunctionKey, ctx: &mut CacheSavingContext<'_>) -> Self {
1707 match key {
1708 GeneratedFunctionKey::Loop(id) => GeneratedFunctionKeyCached::Loop(
1709 SyntaxStablePtrIdCached::new(id.untyped(), &mut ctx.semantic_ctx.defs_ctx),
1710 ),
1711 GeneratedFunctionKey::TraitFunc(id, stable_location) => {
1712 GeneratedFunctionKeyCached::TraitFunc(
1713 LanguageElementCached::new(id, &mut ctx.semantic_ctx.defs_ctx),
1714 SyntaxStablePtrIdCached::new(
1715 stable_location.stable_ptr(),
1716 &mut ctx.semantic_ctx.defs_ctx,
1717 ),
1718 )
1719 }
1720 }
1721 }
1722 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> GeneratedFunctionKey {
1723 match self {
1724 GeneratedFunctionKeyCached::Loop(id) => GeneratedFunctionKey::Loop(ExprPtr(
1725 id.get_embedded(&ctx.semantic_ctx.defs_loading_data),
1726 )),
1727 GeneratedFunctionKeyCached::TraitFunc(id, stable_location) => {
1728 let (module_file_id, stable_ptr) =
1729 id.get_embedded(&ctx.semantic_ctx.defs_loading_data);
1730 GeneratedFunctionKey::TraitFunc(
1731 TraitFunctionLongId(module_file_id, TraitItemFunctionPtr(stable_ptr))
1732 .intern(ctx.db),
1733 StableLocation::new(
1734 stable_location.get_embedded(&ctx.semantic_ctx.defs_loading_data),
1735 ),
1736 )
1737 }
1738 }
1739 }
1740}
1741
1742#[derive(Serialize, Deserialize)]
1743struct StatementStructConstructCached {
1744 inputs: Vec<VarUsageCached>,
1745 output: usize,
1747}
1748impl StatementStructConstructCached {
1749 fn new(stmt: StatementStructConstruct, _ctx: &mut CacheSavingContext<'_>) -> Self {
1750 Self {
1751 inputs: stmt.inputs.iter().map(|var| VarUsageCached::new(*var, _ctx)).collect(),
1752 output: stmt.output.index(),
1753 }
1754 }
1755 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> StatementStructConstruct {
1756 StatementStructConstruct {
1757 inputs: self.inputs.into_iter().map(|var_id| var_id.embed(ctx)).collect(),
1758 output: ctx.lowered_variables_id[self.output],
1759 }
1760 }
1761}
1762#[derive(Serialize, Deserialize)]
1763struct StatementStructDestructureCached {
1764 input: VarUsageCached,
1766 outputs: Vec<usize>,
1768}
1769impl StatementStructDestructureCached {
1770 fn new(stmt: StatementStructDestructure, _ctx: &mut CacheSavingContext<'_>) -> Self {
1771 Self {
1772 input: VarUsageCached::new(stmt.input, _ctx),
1773 outputs: stmt.outputs.iter().map(|var| var.index()).collect(),
1774 }
1775 }
1776 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> StatementStructDestructure {
1777 StatementStructDestructure {
1778 input: self.input.embed(ctx),
1779 outputs: self
1780 .outputs
1781 .into_iter()
1782 .map(|var_id| ctx.lowered_variables_id[var_id])
1783 .collect(),
1784 }
1785 }
1786}
1787
1788#[derive(Serialize, Deserialize)]
1789struct StatementEnumConstructCached {
1790 variant: ConcreteVariantCached,
1791 input: VarUsageCached,
1793 output: usize,
1795}
1796impl StatementEnumConstructCached {
1797 fn new(stmt: StatementEnumConstruct, ctx: &mut CacheSavingContext<'_>) -> Self {
1798 Self {
1799 variant: ConcreteVariantCached::new(stmt.variant, &mut ctx.semantic_ctx),
1800 input: VarUsageCached::new(stmt.input, ctx),
1801 output: stmt.output.index(),
1802 }
1803 }
1804 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> StatementEnumConstruct {
1805 StatementEnumConstruct {
1806 variant: self.variant.embed(&mut ctx.semantic_ctx),
1807 input: self.input.embed(ctx),
1808 output: ctx.lowered_variables_id[self.output],
1809 }
1810 }
1811}
1812
1813#[derive(Serialize, Deserialize)]
1814struct StatementSnapshotCached {
1815 input: VarUsageCached,
1816 outputs: [usize; 2],
1817}
1818impl StatementSnapshotCached {
1819 fn new(stmt: StatementSnapshot, _ctx: &mut CacheSavingContext<'_>) -> Self {
1820 Self {
1821 input: VarUsageCached::new(stmt.input, _ctx),
1822 outputs: stmt.outputs.map(|var| var.index()),
1823 }
1824 }
1825 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> StatementSnapshot {
1826 StatementSnapshot {
1827 input: self.input.embed(ctx),
1828 outputs: [
1829 ctx.lowered_variables_id[self.outputs[0]],
1830 ctx.lowered_variables_id[self.outputs[1]],
1831 ],
1832 }
1833 }
1834}
1835
1836#[derive(Serialize, Deserialize)]
1837struct StatementDesnapCached {
1838 input: VarUsageCached,
1839 output: usize,
1841}
1842impl StatementDesnapCached {
1843 fn new(stmt: StatementDesnap, ctx: &mut CacheSavingContext<'_>) -> Self {
1844 Self { input: VarUsageCached::new(stmt.input, ctx), output: stmt.output.index() }
1845 }
1846 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> StatementDesnap {
1847 StatementDesnap {
1848 input: self.input.embed(ctx),
1849 output: ctx.lowered_variables_id[self.output],
1850 }
1851 }
1852}
1853
1854#[derive(Serialize, Deserialize, Clone)]
1855enum GenericArgumentCached {
1856 Type(TypeIdCached),
1857 Value(ConstValueCached),
1858 Impl(ImplIdCached),
1859 NegImpl,
1860}
1861
1862impl GenericArgumentCached {
1863 fn new(
1864 generic_argument_id: semantic::GenericArgumentId,
1865 ctx: &mut SemanticCacheSavingContext<'_>,
1866 ) -> Self {
1867 match generic_argument_id {
1868 semantic::GenericArgumentId::Type(type_id) => {
1869 GenericArgumentCached::Type(TypeIdCached::new(type_id, ctx))
1870 }
1871 semantic::GenericArgumentId::Constant(const_value_id) => {
1872 GenericArgumentCached::Value(ConstValueCached::new(
1873 const_value_id.lookup_intern(ctx.db), ctx,
1875 ))
1876 }
1877 semantic::GenericArgumentId::Impl(impl_id) => {
1878 GenericArgumentCached::Impl(ImplIdCached::new(impl_id, ctx))
1879 }
1880 semantic::GenericArgumentId::NegImpl => GenericArgumentCached::NegImpl,
1881 }
1882 }
1883 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> semantic::GenericArgumentId {
1884 match self {
1885 GenericArgumentCached::Type(ty) => semantic::GenericArgumentId::Type(ty.embed(ctx)),
1886 GenericArgumentCached::Value(value) => {
1887 semantic::GenericArgumentId::Constant(value.embed(ctx).intern(ctx.db))
1888 }
1889 GenericArgumentCached::Impl(imp) => semantic::GenericArgumentId::Impl(imp.embed(ctx)),
1890 GenericArgumentCached::NegImpl => semantic::GenericArgumentId::NegImpl,
1891 }
1892 }
1893}
1894
1895#[derive(Serialize, Deserialize, Clone)]
1896enum TypeCached {
1897 Concrete(ConcreteTypeCached),
1898 Tuple(Vec<TypeIdCached>),
1901 Snapshot(Box<TypeIdCached>),
1902 GenericParameter(GenericParamCached),
1903 ImplType(ImplTypeCached),
1904 FixedSizeArray(TypeIdCached, ConstValueCached),
1905 ClosureType(ClosureTypeCached),
1906}
1907
1908impl TypeCached {
1909 fn new(type_id: TypeLongId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
1910 match type_id {
1911 semantic::TypeLongId::Concrete(concrete_type_id) => {
1912 TypeCached::Concrete(ConcreteTypeCached::new(concrete_type_id, ctx))
1913 }
1914 semantic::TypeLongId::Tuple(vec) => {
1915 TypeCached::Tuple(vec.into_iter().map(|ty| TypeIdCached::new(ty, ctx)).collect())
1916 }
1917 semantic::TypeLongId::Snapshot(type_id) => {
1918 TypeCached::Snapshot(Box::new(TypeIdCached::new(type_id, ctx)))
1919 }
1920 semantic::TypeLongId::GenericParameter(generic_param_id) => {
1921 TypeCached::GenericParameter(GenericParamCached::new(
1922 generic_param_id,
1923 &mut ctx.defs_ctx,
1924 ))
1925 }
1926 semantic::TypeLongId::ImplType(impl_type_id) => {
1927 TypeCached::ImplType(ImplTypeCached::new(impl_type_id, ctx))
1928 }
1929 semantic::TypeLongId::FixedSizeArray { type_id, size } => TypeCached::FixedSizeArray(
1930 TypeIdCached::new(type_id, ctx),
1931 ConstValueCached::new(size.lookup_intern(ctx.db), ctx),
1932 ),
1933 TypeLongId::Closure(closure_ty) => {
1934 TypeCached::ClosureType(ClosureTypeCached::new(closure_ty, ctx))
1935 }
1936 TypeLongId::Var(_) | TypeLongId::Missing(_) | TypeLongId::Coupon(_) => {
1937 unreachable!(
1938 "type {:?} is not supported for caching",
1939 type_id.debug(ctx.db.elongate())
1940 )
1941 }
1942 }
1943 }
1944 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> TypeLongId {
1945 match self {
1946 TypeCached::Concrete(concrete_type) => TypeLongId::Concrete(concrete_type.embed(ctx)),
1947 TypeCached::Tuple(vec) => {
1948 TypeLongId::Tuple(vec.into_iter().map(|ty| ty.embed(ctx)).collect())
1949 }
1950 TypeCached::Snapshot(type_id) => TypeLongId::Snapshot(type_id.embed(ctx)),
1951 TypeCached::GenericParameter(generic_param) => TypeLongId::GenericParameter(
1952 generic_param.get_embedded(&ctx.defs_loading_data, ctx.db),
1953 ),
1954 TypeCached::ImplType(impl_type) => TypeLongId::ImplType(impl_type.embed(ctx)),
1955 TypeCached::FixedSizeArray(type_id, size) => TypeLongId::FixedSizeArray {
1956 type_id: type_id.embed(ctx),
1957 size: size.embed(ctx).intern(ctx.db),
1958 },
1959 TypeCached::ClosureType(closure_ty) => TypeLongId::Closure(closure_ty.embed(ctx)),
1960 }
1961 }
1962}
1963
1964#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
1965struct TypeIdCached(usize);
1966
1967impl TypeIdCached {
1968 fn new(ty: TypeId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
1969 if let Some(id) = ctx.type_ids.get(&ty) {
1970 return *id;
1971 }
1972 let ty_long = TypeCached::new(ty.lookup_intern(ctx.db), ctx);
1973 let id = TypeIdCached(ctx.type_ids_lookup.len());
1974 ctx.type_ids_lookup.push(ty_long);
1975 ctx.type_ids.insert(ty, id);
1976 id
1977 }
1978 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> TypeId {
1979 if let Some(type_id) = ctx.type_ids.get(&self) {
1980 return *type_id;
1981 }
1982
1983 let ty = ctx.type_ids_lookup[self.0].clone();
1984 let ty = ty.embed(ctx).intern(ctx.db);
1985 ctx.type_ids.insert(self, ty);
1986 ty
1987 }
1988}
1989
1990#[derive(Serialize, Deserialize, Clone)]
1991enum ConcreteTypeCached {
1992 Struct(ConcreteStructCached),
1993 Enum(ConcreteEnumCached),
1994 Extern(ConcreteExternTypeCached),
1995}
1996
1997impl ConcreteTypeCached {
1998 fn new(
1999 concrete_type_id: semantic::ConcreteTypeId,
2000 ctx: &mut SemanticCacheSavingContext<'_>,
2001 ) -> Self {
2002 match concrete_type_id {
2003 semantic::ConcreteTypeId::Struct(id) => {
2004 ConcreteTypeCached::Struct(ConcreteStructCached::new(id, ctx))
2005 }
2006 semantic::ConcreteTypeId::Enum(id) => {
2007 ConcreteTypeCached::Enum(ConcreteEnumCached::new(id, ctx))
2008 }
2009 semantic::ConcreteTypeId::Extern(id) => {
2010 ConcreteTypeCached::Extern(ConcreteExternTypeCached::new(id, ctx))
2011 }
2012 }
2013 }
2014 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> semantic::ConcreteTypeId {
2015 match self {
2016 ConcreteTypeCached::Struct(s) => semantic::ConcreteTypeId::Struct(s.embed(ctx)),
2017 ConcreteTypeCached::Enum(e) => semantic::ConcreteTypeId::Enum(e.embed(ctx)),
2018 ConcreteTypeCached::Extern(e) => semantic::ConcreteTypeId::Extern(e.embed(ctx)),
2019 }
2020 }
2021}
2022
2023#[derive(Serialize, Deserialize, Clone)]
2024struct ImplTypeCached {
2025 impl_id: ImplIdCached,
2026 trait_type: TraitTypeCached,
2027}
2028impl ImplTypeCached {
2029 fn new(impl_type_id: ImplTypeId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
2030 Self {
2031 impl_id: ImplIdCached::new(impl_type_id.impl_id(), ctx),
2032 trait_type: TraitTypeCached::new(impl_type_id.ty(), ctx),
2033 }
2034 }
2035 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> ImplTypeId {
2036 let impl_id = self.impl_id.embed(ctx);
2037 let ty = self.trait_type.embed(ctx);
2038 ImplTypeId::new(impl_id, ty, ctx.db)
2039 }
2040}
2041#[derive(Serialize, Deserialize, Clone)]
2042struct ClosureTypeCached {
2043 param_tys: Vec<TypeIdCached>,
2044 ret_ty: TypeIdCached,
2045 captured_types: Vec<TypeIdCached>,
2046 parent_function: SemanticFunctionIdCached,
2047 wrapper_location: SyntaxStablePtrIdCached,
2048}
2049
2050impl ClosureTypeCached {
2051 fn new(closure_type_id: ClosureTypeLongId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
2052 Self {
2053 param_tys: closure_type_id
2054 .param_tys
2055 .iter()
2056 .map(|ty| TypeIdCached::new(*ty, ctx))
2057 .collect(),
2058 ret_ty: TypeIdCached::new(closure_type_id.ret_ty, ctx),
2059 captured_types: closure_type_id
2060 .captured_types
2061 .iter()
2062 .map(|ty| TypeIdCached::new(*ty, ctx))
2063 .collect(),
2064 parent_function: SemanticFunctionIdCached::new(
2065 closure_type_id.parent_function.unwrap(),
2066 ctx,
2067 ),
2068 wrapper_location: SyntaxStablePtrIdCached::new(
2069 closure_type_id.wrapper_location.stable_ptr(),
2070 &mut ctx.defs_ctx,
2071 ),
2072 }
2073 }
2074 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> ClosureTypeLongId {
2075 ClosureTypeLongId {
2076 param_tys: self.param_tys.into_iter().map(|ty| ty.embed(ctx)).collect(),
2077 ret_ty: self.ret_ty.embed(ctx),
2078 captured_types: self.captured_types.into_iter().map(|ty| ty.embed(ctx)).collect(),
2079 parent_function: Ok(self.parent_function.embed(ctx)),
2080 wrapper_location: StableLocation::new(
2081 self.wrapper_location.get_embedded(&ctx.defs_loading_data),
2082 ),
2083 }
2084 }
2085}
2086
2087#[derive(Serialize, Deserialize, Clone, Hash, PartialEq, Eq)]
2088struct TraitTypeCached {
2089 language_element: LanguageElementCached,
2090}
2091impl TraitTypeCached {
2092 fn new(trait_type_id: TraitTypeId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
2093 Self { language_element: LanguageElementCached::new(trait_type_id, &mut ctx.defs_ctx) }
2094 }
2095 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> TraitTypeId {
2096 let (module_file_id, stable_ptr) =
2097 self.language_element.get_embedded(&ctx.defs_loading_data);
2098 TraitTypeLongId(module_file_id, TraitItemTypePtr(stable_ptr)).intern(ctx.db)
2099 }
2100}
2101
2102#[derive(Serialize, Deserialize, Clone)]
2103enum ImplCached {
2104 Concrete(ConcreteImplCached),
2105 GenericParameter(GenericParamCached),
2106 ImplImpl(ImplImplCached),
2107 GeneratedImpl(GeneratedImplCached),
2108 SelfImpl(ConcreteTraitCached),
2109}
2110impl ImplCached {
2111 fn new(impl_id: ImplLongId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
2112 match impl_id {
2113 ImplLongId::Concrete(concrete_impl) => {
2114 ImplCached::Concrete(ConcreteImplCached::new(concrete_impl, ctx))
2115 }
2116 ImplLongId::GenericParameter(generic_param_id) => ImplCached::GenericParameter(
2117 GenericParamCached::new(generic_param_id, &mut ctx.defs_ctx),
2118 ),
2119 ImplLongId::GeneratedImpl(generated_impl) => {
2120 ImplCached::GeneratedImpl(GeneratedImplCached::new(generated_impl, ctx))
2121 }
2122 ImplLongId::ImplImpl(impl_impl) => {
2123 ImplCached::ImplImpl(ImplImplCached::new(impl_impl, ctx))
2124 }
2125 ImplLongId::SelfImpl(concrete_trait) => {
2126 ImplCached::SelfImpl(ConcreteTraitCached::new(concrete_trait, ctx))
2127 }
2128 ImplLongId::ImplVar(_) => {
2129 unreachable!(
2130 "impl {:?} is not supported for caching",
2131 impl_id.debug(ctx.db.elongate())
2132 )
2133 }
2134 }
2135 }
2136 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> ImplLongId {
2137 match self {
2138 ImplCached::Concrete(concrete_impl) => ImplLongId::Concrete(concrete_impl.embed(ctx)),
2139 ImplCached::ImplImpl(impl_impl) => ImplLongId::ImplImpl(impl_impl.embed(ctx)),
2140 ImplCached::GenericParameter(generic_param) => ImplLongId::GenericParameter(
2141 generic_param.get_embedded(&ctx.defs_loading_data, ctx.db),
2142 ),
2143 ImplCached::GeneratedImpl(generated_impl) => {
2144 ImplLongId::GeneratedImpl(generated_impl.embed(ctx))
2145 }
2146 ImplCached::SelfImpl(concrete_trait) => ImplLongId::SelfImpl(concrete_trait.embed(ctx)),
2147 }
2148 }
2149}
2150#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
2151struct ImplIdCached(usize);
2152
2153impl ImplIdCached {
2154 fn new(impl_id: ImplId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
2155 if let Some(id) = ctx.impl_ids.get(&impl_id) {
2156 return *id;
2157 }
2158 let imp = ImplCached::new(impl_id.lookup_intern(ctx.db), ctx);
2159 let id = ImplIdCached(ctx.impl_ids_lookup.len());
2160 ctx.impl_ids_lookup.push(imp);
2161 ctx.impl_ids.insert(impl_id, id);
2162 id
2163 }
2164 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> ImplId {
2165 if let Some(impl_id) = ctx.impl_ids.get(&self) {
2166 return *impl_id;
2167 }
2168
2169 let imp = ctx.impl_ids_lookup[self.0].clone();
2170 let imp = imp.embed(ctx).intern(ctx.db);
2171 ctx.impl_ids.insert(self, imp);
2172 imp
2173 }
2174}
2175
2176#[derive(Serialize, Deserialize, Clone)]
2177struct ConcreteImplCached {
2178 impl_def_id: ImplDefIdCached,
2179 generic_args: Vec<GenericArgumentCached>,
2180}
2181impl ConcreteImplCached {
2182 fn new(
2183 concrete_impl: semantic::ConcreteImplId,
2184 ctx: &mut SemanticCacheSavingContext<'_>,
2185 ) -> Self {
2186 let long_id = concrete_impl.lookup_intern(ctx.db);
2187 Self {
2188 impl_def_id: ImplDefIdCached::new(long_id.impl_def_id, &mut ctx.defs_ctx),
2189 generic_args: long_id
2190 .generic_args
2191 .into_iter()
2192 .map(|arg| GenericArgumentCached::new(arg, ctx))
2193 .collect(),
2194 }
2195 }
2196 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> semantic::ConcreteImplId {
2197 let impl_def_id = self.impl_def_id.get_embedded(&ctx.defs_loading_data);
2198 let long_id = ConcreteImplLongId {
2199 impl_def_id,
2200 generic_args: self.generic_args.into_iter().map(|arg| arg.embed(ctx)).collect(),
2201 };
2202 long_id.intern(ctx.db)
2203 }
2204}
2205
2206#[derive(Serialize, Deserialize, Clone)]
2207struct ImplImplCached {
2208 impl_id: ImplIdCached,
2209 trait_impl_id: TraitImplCached,
2210}
2211impl ImplImplCached {
2212 fn new(impl_impl_id: ImplImplId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
2213 Self {
2214 impl_id: ImplIdCached::new(impl_impl_id.impl_id(), ctx),
2215 trait_impl_id: TraitImplCached::new(impl_impl_id.trait_impl_id(), ctx),
2216 }
2217 }
2218 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> ImplImplId {
2219 let impl_id = self.impl_id.embed(ctx);
2220 let trait_impl_id = self.trait_impl_id.embed(ctx);
2221 ImplImplId::new(impl_id, trait_impl_id, ctx.db)
2222 }
2223}
2224
2225#[derive(Serialize, Deserialize, Clone)]
2226struct TraitImplCached {
2227 language_element: LanguageElementCached,
2228}
2229impl TraitImplCached {
2230 fn new(trait_impl_id: TraitImplId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
2231 Self { language_element: LanguageElementCached::new(trait_impl_id, &mut ctx.defs_ctx) }
2232 }
2233 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> TraitImplId {
2234 let (module_file_id, stable_ptr) =
2235 self.language_element.get_embedded(&ctx.defs_loading_data);
2236 TraitImplLongId(module_file_id, TraitItemImplPtr(stable_ptr)).intern(ctx.db)
2237 }
2238}
2239
2240#[derive(Serialize, Deserialize, Clone)]
2241struct GeneratedImplCached {
2242 pub concrete_trait: ConcreteTraitCached,
2243 pub generic_params: Vec<SemanticGenericParamCached>,
2246 pub impl_items: OrderedHashMap<TraitTypeCached, TypeIdCached>,
2247}
2248impl GeneratedImplCached {
2249 fn new(generated_impl: GeneratedImplId, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
2250 let generated_impl = generated_impl.lookup_intern(ctx.db);
2251 Self {
2252 concrete_trait: ConcreteTraitCached::new(generated_impl.concrete_trait, ctx),
2253 generic_params: generated_impl
2254 .generic_params
2255 .into_iter()
2256 .map(|param| SemanticGenericParamCached::new(param, ctx))
2257 .collect(),
2258 impl_items: generated_impl
2259 .impl_items
2260 .0
2261 .into_iter()
2262 .map(|(k, v)| (TraitTypeCached::new(k, ctx), TypeIdCached::new(v, ctx)))
2263 .collect(),
2264 }
2265 }
2266 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> GeneratedImplId {
2267 GeneratedImplLongId {
2268 concrete_trait: self.concrete_trait.embed(ctx),
2269 generic_params: self.generic_params.into_iter().map(|param| param.embed(ctx)).collect(),
2270 impl_items: GeneratedImplItems(
2271 self.impl_items.into_iter().map(|(k, v)| (k.embed(ctx), v.embed(ctx))).collect(),
2272 ),
2273 }
2274 .intern(ctx.db)
2275 }
2276}
2277
2278#[derive(Serialize, Deserialize, Clone)]
2279enum SemanticGenericParamCached {
2280 Type(GenericParamTypeCached),
2281 Const(GenericParamConstCached),
2282 Impl(GenericParamImplCached),
2283 NegImpl(GenericParamImplCached),
2284}
2285impl SemanticGenericParamCached {
2286 fn new(generic_param_id: GenericParam, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
2287 match generic_param_id {
2288 GenericParam::Type(generic_param) => {
2289 SemanticGenericParamCached::Type(GenericParamTypeCached::new(generic_param, ctx))
2290 }
2291 GenericParam::Const(generic_param) => {
2292 SemanticGenericParamCached::Const(GenericParamConstCached::new(generic_param, ctx))
2293 }
2294 GenericParam::Impl(generic_param) => {
2295 SemanticGenericParamCached::Impl(GenericParamImplCached::new(generic_param, ctx))
2296 }
2297 GenericParam::NegImpl(generic_param) => {
2298 SemanticGenericParamCached::NegImpl(GenericParamImplCached::new(generic_param, ctx))
2299 }
2300 }
2301 }
2302 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> GenericParam {
2303 match self {
2304 SemanticGenericParamCached::Type(generic_param) => {
2305 GenericParam::Type(generic_param.embed(ctx))
2306 }
2307 SemanticGenericParamCached::Const(generic_param) => {
2308 GenericParam::Const(generic_param.embed(ctx))
2309 }
2310 SemanticGenericParamCached::Impl(generic_param) => {
2311 GenericParam::Impl(generic_param.embed(ctx))
2312 }
2313 SemanticGenericParamCached::NegImpl(generic_param) => {
2314 GenericParam::NegImpl(generic_param.embed(ctx))
2315 }
2316 }
2317 }
2318}
2319
2320#[derive(Serialize, Deserialize, Clone)]
2321struct GenericParamTypeCached {
2322 id: GenericParamCached,
2323}
2324
2325impl GenericParamTypeCached {
2326 fn new(generic_param: GenericParamType, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
2327 Self { id: GenericParamCached::new(generic_param.id, &mut ctx.defs_ctx) }
2328 }
2329 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> GenericParamType {
2330 GenericParamType { id: self.id.get_embedded(&ctx.defs_loading_data, ctx.db) }
2331 }
2332}
2333
2334#[derive(Serialize, Deserialize, Clone)]
2335struct GenericParamConstCached {
2336 id: GenericParamCached,
2337 ty: TypeIdCached,
2338}
2339
2340impl GenericParamConstCached {
2341 fn new(generic_param: GenericParamConst, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
2342 Self {
2343 id: GenericParamCached::new(generic_param.id, &mut ctx.defs_ctx),
2344 ty: TypeIdCached::new(generic_param.ty, ctx),
2345 }
2346 }
2347 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> GenericParamConst {
2348 GenericParamConst {
2349 id: self.id.get_embedded(&ctx.defs_loading_data, ctx.db),
2350 ty: self.ty.embed(ctx),
2351 }
2352 }
2353}
2354
2355#[derive(Serialize, Deserialize, Clone)]
2356struct GenericParamImplCached {
2357 id: GenericParamCached,
2358 concrete_trait: ConcreteTraitCached,
2359 type_constraints: OrderedHashMap<TraitTypeCached, TypeIdCached>,
2360}
2361
2362impl GenericParamImplCached {
2363 fn new(generic_param: GenericParamImpl, ctx: &mut SemanticCacheSavingContext<'_>) -> Self {
2364 Self {
2365 id: GenericParamCached::new(generic_param.id, &mut ctx.defs_ctx),
2366 concrete_trait: ConcreteTraitCached::new(generic_param.concrete_trait.unwrap(), ctx),
2367
2368 type_constraints: generic_param
2369 .type_constraints
2370 .into_iter()
2371 .map(|(k, v)| (TraitTypeCached::new(k, ctx), TypeIdCached::new(v, ctx)))
2372 .collect(),
2373 }
2374 }
2375 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> GenericParamImpl {
2376 GenericParamImpl {
2377 id: self.id.get_embedded(&ctx.defs_loading_data, ctx.db),
2378 concrete_trait: Ok(self.concrete_trait.embed(ctx)),
2379 type_constraints: self
2380 .type_constraints
2381 .into_iter()
2382 .map(|(k, v)| (k.embed(ctx), v.embed(ctx)))
2383 .collect(),
2384 }
2385 }
2386}
2387
2388#[derive(Serialize, Deserialize, Clone)]
2389struct ConcreteVariantCached {
2390 concrete_enum_id: ConcreteEnumCached,
2391 id: LanguageElementCached,
2392 ty: TypeIdCached,
2393 idx: usize,
2395}
2396impl ConcreteVariantCached {
2397 fn new(
2398 concrete_variant: semantic::ConcreteVariant,
2399 ctx: &mut SemanticCacheSavingContext<'_>,
2400 ) -> Self {
2401 Self {
2402 concrete_enum_id: ConcreteEnumCached::new(concrete_variant.concrete_enum_id, ctx),
2403 id: LanguageElementCached::new(concrete_variant.id, &mut ctx.defs_ctx),
2404 ty: TypeIdCached::new(concrete_variant.ty, ctx),
2405 idx: concrete_variant.idx,
2406 }
2407 }
2408 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> semantic::ConcreteVariant {
2409 let concrete_enum_id = self.concrete_enum_id.embed(ctx);
2410 let ty = self.ty.embed(ctx);
2411 let (module_file_id, stable_ptr) = self.id.get_embedded(&ctx.defs_loading_data);
2412
2413 let id = VariantLongId(module_file_id, VariantPtr(stable_ptr)).intern(ctx.db);
2414 semantic::ConcreteVariant { concrete_enum_id, id, ty, idx: self.idx }
2415 }
2416}
2417
2418#[derive(Serialize, Deserialize, Clone)]
2419struct ConcreteEnumCached {
2420 enum_id: LanguageElementCached,
2421 generic_args: Vec<GenericArgumentCached>,
2422}
2423
2424impl ConcreteEnumCached {
2425 fn new(
2426 concrete_enum: semantic::ConcreteEnumId,
2427 ctx: &mut SemanticCacheSavingContext<'_>,
2428 ) -> Self {
2429 let long_id = concrete_enum.lookup_intern(ctx.db);
2430 Self {
2431 enum_id: LanguageElementCached::new(long_id.enum_id, &mut ctx.defs_ctx),
2432 generic_args: long_id
2433 .generic_args
2434 .into_iter()
2435 .map(|arg| GenericArgumentCached::new(arg, ctx))
2436 .collect(),
2437 }
2438 }
2439 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> semantic::ConcreteEnumId {
2440 let (module_file_id, stable_ptr) = self.enum_id.get_embedded(&ctx.defs_loading_data);
2441
2442 let long_id = ConcreteEnumLongId {
2443 enum_id: EnumLongId(module_file_id, ItemEnumPtr(stable_ptr)).intern(ctx.db),
2444 generic_args: self.generic_args.into_iter().map(|arg| arg.embed(ctx)).collect(),
2445 };
2446 long_id.intern(ctx.db)
2447 }
2448}
2449
2450#[derive(Serialize, Deserialize, Clone)]
2451struct ConcreteStructCached {
2452 struct_id: LanguageElementCached,
2453 generic_args: Vec<GenericArgumentCached>,
2454}
2455impl ConcreteStructCached {
2456 fn new(
2457 concrete_struct: semantic::ConcreteStructId,
2458 ctx: &mut SemanticCacheSavingContext<'_>,
2459 ) -> Self {
2460 let long_id = concrete_struct.lookup_intern(ctx.db);
2461 Self {
2462 struct_id: LanguageElementCached::new(long_id.struct_id, &mut ctx.defs_ctx),
2463 generic_args: long_id
2464 .generic_args
2465 .into_iter()
2466 .map(|arg| GenericArgumentCached::new(arg, ctx))
2467 .collect(),
2468 }
2469 }
2470 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> semantic::ConcreteStructId {
2471 let (module_file_id, stable_ptr) = self.struct_id.get_embedded(&ctx.defs_loading_data);
2472
2473 let long_id = ConcreteStructLongId {
2474 struct_id: StructLongId(module_file_id, ItemStructPtr(stable_ptr)).intern(ctx.db),
2475 generic_args: self.generic_args.into_iter().map(|arg| arg.embed(ctx)).collect(),
2476 };
2477 long_id.intern(ctx.db)
2478 }
2479}
2480
2481#[derive(Serialize, Deserialize, Clone)]
2482struct ConcreteExternTypeCached {
2483 language_element: LanguageElementCached,
2484 generic_args: Vec<GenericArgumentCached>,
2485}
2486impl ConcreteExternTypeCached {
2487 fn new(
2488 concrete_extern_type: semantic::ConcreteExternTypeId,
2489 ctx: &mut SemanticCacheSavingContext<'_>,
2490 ) -> Self {
2491 let long_id = concrete_extern_type.lookup_intern(ctx.db);
2492 Self {
2493 language_element: LanguageElementCached::new(long_id.extern_type_id, &mut ctx.defs_ctx),
2494 generic_args: long_id
2495 .generic_args
2496 .into_iter()
2497 .map(|arg| GenericArgumentCached::new(arg, ctx))
2498 .collect(),
2499 }
2500 }
2501 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> semantic::ConcreteExternTypeId {
2502 let (module_file_id, stable_ptr) =
2503 self.language_element.get_embedded(&ctx.defs_loading_data);
2504
2505 let long_id = ConcreteExternTypeLongId {
2506 extern_type_id: ExternTypeLongId(module_file_id, ItemExternTypePtr(stable_ptr))
2507 .intern(ctx.db),
2508 generic_args: self.generic_args.into_iter().map(|arg| arg.embed(ctx)).collect(),
2509 };
2510 long_id.intern(ctx.db)
2511 }
2512}
2513
2514#[derive(Serialize, Deserialize, Clone)]
2515struct ConcreteTraitCached {
2516 trait_id: LanguageElementCached,
2517 generic_args: Vec<GenericArgumentCached>,
2518}
2519
2520impl ConcreteTraitCached {
2521 fn new(
2522 concrete_trait: semantic::ConcreteTraitId,
2523 ctx: &mut SemanticCacheSavingContext<'_>,
2524 ) -> Self {
2525 let long_id = concrete_trait.lookup_intern(ctx.db);
2526 Self {
2527 trait_id: LanguageElementCached::new(long_id.trait_id, &mut ctx.defs_ctx),
2528 generic_args: long_id
2529 .generic_args
2530 .into_iter()
2531 .map(|arg| GenericArgumentCached::new(arg, ctx))
2532 .collect(),
2533 }
2534 }
2535 fn embed(self, ctx: &mut SemanticCacheLoadingContext<'_>) -> semantic::ConcreteTraitId {
2536 let (module_file_id, stable_ptr) = self.trait_id.get_embedded(&ctx.defs_loading_data);
2537
2538 let long_id = ConcreteTraitLongId {
2539 trait_id: TraitLongId(module_file_id, ItemTraitPtr(stable_ptr)).intern(ctx.db),
2540 generic_args: self.generic_args.into_iter().map(|arg| arg.embed(ctx)).collect(),
2541 };
2542 long_id.intern(ctx.db)
2543 }
2544}
2545
2546#[derive(Serialize, Deserialize, Clone)]
2547struct LocationCached {
2548 stable_location: SyntaxStablePtrIdCached,
2550 inline_locations: Vec<SyntaxStablePtrIdCached>,
2552}
2553impl LocationCached {
2554 fn new(location: Location, ctx: &mut CacheSavingContext<'_>) -> Self {
2555 Self {
2556 stable_location: SyntaxStablePtrIdCached::new(
2557 location.stable_location.stable_ptr(),
2558 &mut ctx.semantic_ctx.defs_ctx,
2559 ),
2560 inline_locations: location
2561 .inline_locations
2562 .iter()
2563 .map(|loc| {
2564 SyntaxStablePtrIdCached::new(loc.stable_ptr(), &mut ctx.semantic_ctx.defs_ctx)
2565 })
2566 .collect(),
2567 }
2568 }
2569 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> Location {
2570 Location {
2571 stable_location: StableLocation::new(
2572 self.stable_location.get_embedded(&ctx.semantic_ctx.defs_loading_data),
2573 ),
2574 inline_locations: self
2575 .inline_locations
2576 .into_iter()
2577 .map(|loc| {
2578 StableLocation::new(loc.get_embedded(&ctx.semantic_ctx.defs_loading_data))
2579 })
2580 .collect(),
2581 notes: Default::default(),
2582 }
2583 }
2584}
2585
2586#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
2587struct LocationIdCached(usize);
2588
2589impl LocationIdCached {
2590 fn new(location_id: LocationId, ctx: &mut CacheSavingContext<'_>) -> Self {
2591 if let Some(id) = ctx.location_ids.get(&location_id) {
2592 return *id;
2593 }
2594 let location = LocationCached::new(location_id.lookup_intern(ctx.db), ctx);
2595 let id = LocationIdCached(ctx.location_ids_lookup.len());
2596 ctx.location_ids_lookup.push(location);
2597 ctx.location_ids.insert(location_id, id);
2598 id
2599 }
2600 fn embed(self, ctx: &mut CacheLoadingContext<'_>) -> LocationId {
2601 if let Some(location_id) = ctx.location_ids.get(&self) {
2602 return *location_id;
2603 }
2604 let location = ctx.location_ids_lookup[self.0].clone();
2605 let location = location.embed(ctx).intern(ctx.db);
2606 ctx.location_ids.insert(self, location);
2607 location
2608 }
2609}