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