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