1use std::hash::{Hash, Hasher};
2use std::ops::{Deref, DerefMut};
3use std::path::PathBuf;
4use std::sync::Arc;
5
6use cairo_lang_diagnostics::{DiagnosticNote, Severity};
7use cairo_lang_filesystem::db::FilesGroup;
8use cairo_lang_filesystem::flag::{Flag, FlagsGroup};
9use cairo_lang_filesystem::ids::{
10 CodeMapping, CrateId, CrateLongId, FileId, FileKind, FileLongId, SmolStrId, SpanInFile,
11 VirtualFile,
12};
13use cairo_lang_filesystem::span::{TextSpan, TextWidth};
14use cairo_lang_syntax::node::ast::{
15 FunctionWithBodyPtr, GenericParamPtr, ItemConstantPtr, ItemEnumPtr, ItemExternFunctionPtr,
16 ItemExternTypePtr, ItemImplAliasPtr, ItemImplPtr, ItemInlineMacroPtr, ItemMacroDeclarationPtr,
17 ItemModulePtr, ItemStructPtr, ItemTraitPtr, ItemTypeAliasPtr, UsePathLeafPtr, UsePathStarPtr,
18};
19use cairo_lang_syntax::node::green::{GreenNode, GreenNodeDetails};
20use cairo_lang_syntax::node::ids::{GreenId, SyntaxStablePtrId};
21use cairo_lang_syntax::node::kind::SyntaxKind;
22use cairo_lang_syntax::node::{SyntaxNode, SyntaxNodeId, TypedSyntaxNode, ast};
23use cairo_lang_utils::Intern;
24use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
25use salsa::Database;
26use serde::{Deserialize, Serialize};
27
28use crate::db::{
29 ModuleData, ModuleDataCacheAndLoadingData, ModuleFilesData, ModuleNamedItemsData,
30 ModuleTypesData, ModuleUnnamedItemsData,
31};
32use crate::ids::{
33 ConstantId, ConstantLongId, EnumId, EnumLongId, ExternFunctionId, ExternFunctionLongId,
34 ExternTypeId, ExternTypeLongId, FreeFunctionId, FreeFunctionLongId, GenericParamId,
35 GenericParamLongId, GlobalUseId, GlobalUseLongId, ImplAliasId, ImplAliasLongId, ImplDefId,
36 ImplDefLongId, LanguageElementId, MacroCallId, MacroCallLongId, MacroDeclarationId,
37 MacroDeclarationLongId, ModuleId, ModuleItemId, ModuleTypeAliasId, ModuleTypeAliasLongId,
38 PluginGeneratedFileId, PluginGeneratedFileLongId, StructId, StructLongId, SubmoduleId,
39 SubmoduleLongId, TraitId, TraitLongId, UseId, UseLongId,
40};
41use crate::plugin::{DynGeneratedFileAuxData, PluginDiagnostic};
42
43#[derive(Serialize, Deserialize)]
45pub struct CachedCrateMetadata {
46 pub settings: Option<u64>,
48 pub compiler_version: String,
50 pub global_flags: OrderedHashMap<String, Flag>,
52}
53
54impl CachedCrateMetadata {
55 pub fn new(crate_id: CrateId<'_>, db: &dyn Database) -> Self {
57 let settings = db.crate_config(crate_id).map(|config| &config.settings).map(|v| {
58 let mut hasher = xxhash_rust::xxh3::Xxh3::default();
59 v.hash(&mut hasher);
60 hasher.finish()
61 });
62 let compiler_version = env!("CARGO_PKG_VERSION").to_string();
63 let global_flags =
64 db.flags().iter().map(|(flag_id, flag)| (flag_id.long(db).0.clone(), *flag)).collect();
65 Self { settings, compiler_version, global_flags }
66 }
67}
68
69fn validate_metadata(crate_id: CrateId<'_>, metadata: &CachedCrateMetadata, db: &dyn Database) {
71 let current_metadata = CachedCrateMetadata::new(crate_id, db);
72
73 if current_metadata.compiler_version != metadata.compiler_version {
74 panic!("Cached crate was compiled with a different compiler version.");
75 }
76 if current_metadata.settings != metadata.settings {
77 panic!("Cached crate was compiled with different settings.");
78 }
79
80 if !current_metadata.global_flags.eq_unordered(&metadata.global_flags) {
81 panic!("Cached crate was compiled with different global flags.");
82 }
83}
84
85type DefCache<'db> = (CachedCrateMetadata, CrateDefCache<'db>, DefCacheLookups);
86
87pub fn load_cached_crate_modules<'db>(
89 db: &'db dyn Database,
90 crate_id: CrateId<'db>,
91) -> Option<ModuleDataCacheAndLoadingData<'db>> {
92 let blob_id = db.crate_config(crate_id)?.cache_file?;
93 let Some(content) = db.blob_content(blob_id) else {
94 return Default::default();
95 };
96
97 let size = usize::from_be_bytes(content[..8].try_into().unwrap());
98
99 let content = &content[8..size + 8];
100
101 let (metadata, module_data, defs_lookups): DefCache<'_> = postcard::from_bytes(content)
102 .unwrap_or_else(|e| {
103 panic!(
104 "failed to deserialize modules cache for crate `{}`: {e}",
105 crate_id.long(db).name().long(db),
106 )
107 });
108
109 validate_metadata(crate_id, &metadata, db);
110
111 let mut ctx = DefCacheLoadingContext::new(db, defs_lookups, crate_id);
112 Some((
113 module_data
114 .0
115 .into_iter()
116 .map(|(module_id, module_data)| {
117 let module_id = module_id.embed(&mut ctx);
118
119 let module_data = module_data.embed(&mut ctx);
120 (module_id, module_data)
121 })
122 .collect::<OrderedHashMap<_, _>>()
123 .into(),
124 ctx.data.into(),
125 ))
126}
127
128#[derive(Serialize, Deserialize)]
129pub struct CrateDefCache<'db>(Vec<(ModuleIdCached, ModuleDataCached<'db>)>);
130
131impl<'db> CrateDefCache<'db> {
132 pub fn new(modules: Vec<(ModuleIdCached, ModuleDataCached<'db>)>) -> Self {
133 Self(modules)
134 }
135}
136
137struct DefCacheLoadingContext<'db> {
139 db: &'db dyn Database,
141
142 data: DefCacheLoadingData<'db>,
144}
145
146impl<'db> DefCacheLoadingContext<'db> {
147 pub fn new(
148 db: &'db dyn Database,
149 lookups: DefCacheLookups,
150 self_crate_id: CrateId<'db>,
151 ) -> Self {
152 let mut res = Self { db, data: DefCacheLoadingData::new(lookups, self_crate_id) };
153 res.embed_lookups();
154 res
155 }
156 fn embed_lookups(&mut self) {
157 for id in 0..self.lookups.green_ids_lookup.len() {
158 let id = GreenIdCached(id);
159 let embed = id.embed(self);
160 self.reverse_green_ids.insert(embed, id);
161 }
162 for id in 0..self.lookups.crate_ids_lookup.len() {
163 CrateIdCached::Other(id).embed(self);
164 }
165 for id in 0..self.lookups.file_ids_lookup.len() {
166 FileIdCached(id).embed(self);
167 }
168
169 for id in 0..self.lookups.syntax_node_lookup.len() {
170 SyntaxNodeCached(id).embed(self);
171 }
172
173 for id in 0..self.lookups.submodule_ids_lookup.len() {
174 SubmoduleIdCached(id).embed(self);
175 }
176 for id in 0..self.lookups.constant_ids_lookup.len() {
177 ConstantIdCached(id).embed(self);
178 }
179 for id in 0..self.lookups.use_ids_lookup.len() {
180 UseIdCached(id).embed(self);
181 }
182 for id in 0..self.lookups.free_function_ids_lookup.len() {
183 FreeFunctionIdCached(id).embed(self);
184 }
185 for id in 0..self.lookups.struct_ids_lookup.len() {
186 StructIdCached(id).embed(self);
187 }
188 for id in 0..self.lookups.enum_ids_lookup.len() {
189 EnumIdCached(id).embed(self);
190 }
191 for id in 0..self.lookups.type_alias_ids_lookup.len() {
192 ModuleTypeAliasIdCached(id).embed(self);
193 }
194 for id in 0..self.lookups.impl_alias_ids_lookup.len() {
195 ImplAliasIdCached(id).embed(self);
196 }
197 for id in 0..self.lookups.trait_ids_lookup.len() {
198 TraitIdCached(id).embed(self);
199 }
200 for id in 0..self.lookups.impl_def_ids_lookup.len() {
201 ImplDefIdCached(id).embed(self);
202 }
203 for id in 0..self.lookups.extern_type_ids_lookup.len() {
204 ExternTypeIdCached(id).embed(self);
205 }
206 for id in 0..self.lookups.extern_function_ids_lookup.len() {
207 ExternFunctionIdCached(id).embed(self);
208 }
209 for id in 0..self.lookups.global_use_ids_lookup.len() {
210 GlobalUseIdCached(id).embed(self);
211 }
212 }
213}
214
215impl<'db> Deref for DefCacheLoadingContext<'db> {
216 type Target = DefCacheLoadingData<'db>;
217
218 fn deref(&self) -> &Self::Target {
219 &self.data
220 }
221}
222impl DerefMut for DefCacheLoadingContext<'_> {
223 fn deref_mut(&mut self) -> &mut Self::Target {
224 &mut self.data
225 }
226}
227
228#[derive(PartialEq, Eq, salsa::Update)]
230pub struct DefCacheLoadingData<'db> {
231 green_ids: OrderedHashMap<GreenIdCached, GreenId<'db>>,
232 reverse_green_ids: OrderedHashMap<GreenId<'db>, GreenIdCached>,
233 crate_ids: OrderedHashMap<CrateIdCached, CrateId<'db>>,
234 reverse_syntax_node_lookup: OrderedHashMap<SyntaxNodeIdCached, SyntaxNodeCached>,
235 syntax_nodes: OrderedHashMap<SyntaxNodeCached, SyntaxNode<'db>>,
236 submodule_ids: OrderedHashMap<SubmoduleIdCached, SubmoduleId<'db>>,
237 constant_ids: OrderedHashMap<ConstantIdCached, ConstantId<'db>>,
238 use_ids: OrderedHashMap<UseIdCached, UseId<'db>>,
239 free_function_ids: OrderedHashMap<FreeFunctionIdCached, FreeFunctionId<'db>>,
240 struct_ids: OrderedHashMap<StructIdCached, StructId<'db>>,
241 enum_ids: OrderedHashMap<EnumIdCached, EnumId<'db>>,
242 type_alias_ids: OrderedHashMap<ModuleTypeAliasIdCached, ModuleTypeAliasId<'db>>,
243 impl_alias_ids: OrderedHashMap<ImplAliasIdCached, ImplAliasId<'db>>,
244 trait_ids: OrderedHashMap<TraitIdCached, TraitId<'db>>,
245 impl_def_ids: OrderedHashMap<ImplDefIdCached, ImplDefId<'db>>,
246 extern_type_ids: OrderedHashMap<ExternTypeIdCached, ExternTypeId<'db>>,
247 extern_function_ids: OrderedHashMap<ExternFunctionIdCached, ExternFunctionId<'db>>,
248 macro_declaration_ids: OrderedHashMap<MacroDeclarationIdCached, MacroDeclarationId<'db>>,
249 macro_call_ids: OrderedHashMap<MacroCallIdCached, MacroCallId<'db>>,
250 global_use_ids: OrderedHashMap<GlobalUseIdCached, GlobalUseId<'db>>,
251
252 file_ids: OrderedHashMap<FileIdCached, FileId<'db>>,
253 self_crate_id: CrateId<'db>,
254 lookups: DefCacheLookups,
255}
256
257impl<'db> DefCacheLoadingData<'db> {
258 fn new(lookups: DefCacheLookups, self_crate_id: CrateId<'db>) -> Self {
259 Self {
260 green_ids: OrderedHashMap::default(),
261 reverse_green_ids: OrderedHashMap::default(),
262 reverse_syntax_node_lookup: lookups
263 .syntax_node_lookup
264 .iter()
265 .enumerate()
266 .map(|(index, syntax_node)| (syntax_node.clone(), SyntaxNodeCached(index)))
267 .collect(),
268 syntax_nodes: OrderedHashMap::default(),
269 crate_ids: OrderedHashMap::default(),
270 submodule_ids: OrderedHashMap::default(),
271 constant_ids: OrderedHashMap::default(),
272 use_ids: OrderedHashMap::default(),
273 free_function_ids: OrderedHashMap::default(),
274 struct_ids: OrderedHashMap::default(),
275 enum_ids: OrderedHashMap::default(),
276 type_alias_ids: OrderedHashMap::default(),
277 impl_alias_ids: OrderedHashMap::default(),
278 trait_ids: OrderedHashMap::default(),
279 impl_def_ids: OrderedHashMap::default(),
280 extern_type_ids: OrderedHashMap::default(),
281 extern_function_ids: OrderedHashMap::default(),
282 macro_declaration_ids: OrderedHashMap::default(),
283 macro_call_ids: OrderedHashMap::default(),
284 global_use_ids: OrderedHashMap::default(),
285
286 file_ids: OrderedHashMap::default(),
287 self_crate_id,
288 lookups,
289 }
290 }
291}
292
293impl<'db> std::fmt::Debug for DefCacheLoadingData<'db> {
294 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
295 f.debug_struct("DefCacheLoadingData").finish()
296 }
297}
298
299impl<'db> Deref for DefCacheLoadingData<'db> {
300 type Target = DefCacheLookups;
301
302 fn deref(&self) -> &Self::Target {
303 &self.lookups
304 }
305}
306impl<'db> DerefMut for DefCacheLoadingData<'db> {
307 fn deref_mut(&mut self) -> &mut Self::Target {
308 &mut self.lookups
309 }
310}
311
312pub struct DefCacheSavingContext<'db> {
314 db: &'db dyn Database,
315 data: DefCacheSavingData<'db>,
316 self_crate_id: CrateId<'db>,
317}
318impl<'db> Deref for DefCacheSavingContext<'db> {
319 type Target = DefCacheSavingData<'db>;
320
321 fn deref(&self) -> &Self::Target {
322 &self.data
323 }
324}
325impl DerefMut for DefCacheSavingContext<'_> {
326 fn deref_mut(&mut self) -> &mut Self::Target {
327 &mut self.data
328 }
329}
330impl<'db> DefCacheSavingContext<'db> {
331 pub fn new(db: &'db dyn Database, self_crate_id: CrateId<'db>) -> Self {
332 Self { db, data: DefCacheSavingData::default(), self_crate_id }
333 }
334}
335
336#[derive(Default)]
338pub struct DefCacheSavingData<'db> {
339 green_ids: OrderedHashMap<GreenId<'db>, GreenIdCached>,
340 crate_ids: OrderedHashMap<CrateId<'db>, CrateIdCached>,
341 submodule_ids: OrderedHashMap<SubmoduleId<'db>, SubmoduleIdCached>,
342 constant_ids: OrderedHashMap<ConstantId<'db>, ConstantIdCached>,
343 use_ids: OrderedHashMap<UseId<'db>, UseIdCached>,
344 free_function_ids: OrderedHashMap<FreeFunctionId<'db>, FreeFunctionIdCached>,
345 struct_ids: OrderedHashMap<StructId<'db>, StructIdCached>,
346 enum_ids: OrderedHashMap<EnumId<'db>, EnumIdCached>,
347 type_alias_ids: OrderedHashMap<ModuleTypeAliasId<'db>, ModuleTypeAliasIdCached>,
348 impl_alias_ids: OrderedHashMap<ImplAliasId<'db>, ImplAliasIdCached>,
349 trait_ids: OrderedHashMap<TraitId<'db>, TraitIdCached>,
350 impl_def_ids: OrderedHashMap<ImplDefId<'db>, ImplDefIdCached>,
351 extern_type_ids: OrderedHashMap<ExternTypeId<'db>, ExternTypeIdCached>,
352 extern_function_ids: OrderedHashMap<ExternFunctionId<'db>, ExternFunctionIdCached>,
353 global_use_ids: OrderedHashMap<GlobalUseId<'db>, GlobalUseIdCached>,
354 macro_declaration_ids: OrderedHashMap<MacroDeclarationId<'db>, MacroDeclarationIdCached>,
355 macro_call_ids: OrderedHashMap<MacroCallId<'db>, MacroCallIdCached>,
356
357 syntax_nodes: OrderedHashMap<SyntaxNode<'db>, SyntaxNodeCached>,
358 file_ids: OrderedHashMap<FileId<'db>, FileIdCached>,
359
360 pub lookups: DefCacheLookups,
361}
362
363impl<'db> Deref for DefCacheSavingData<'db> {
364 type Target = DefCacheLookups;
365
366 fn deref(&self) -> &Self::Target {
367 &self.lookups
368 }
369}
370impl<'db> DerefMut for DefCacheSavingData<'db> {
371 fn deref_mut(&mut self) -> &mut Self::Target {
372 &mut self.lookups
373 }
374}
375
376#[derive(Serialize, Deserialize)]
377pub struct ModuleDataCached<'db> {
378 items: Vec<ModuleItemIdCached>,
379
380 constants: OrderedHashMap<ConstantIdCached, TypeSyntaxNodeCached<'db, ast::ItemConstant<'db>>>,
381 submodules: OrderedHashMap<SubmoduleIdCached, TypeSyntaxNodeCached<'db, ast::ItemModule<'db>>>,
382 uses: OrderedHashMap<UseIdCached, TypeSyntaxNodeCached<'db, ast::UsePathLeaf<'db>>>,
383 free_functions:
384 OrderedHashMap<FreeFunctionIdCached, TypeSyntaxNodeCached<'db, ast::FunctionWithBody<'db>>>,
385 structs: OrderedHashMap<StructIdCached, TypeSyntaxNodeCached<'db, ast::ItemStruct<'db>>>,
386 enums: OrderedHashMap<EnumIdCached, TypeSyntaxNodeCached<'db, ast::ItemEnum<'db>>>,
387 type_aliases:
388 OrderedHashMap<ModuleTypeAliasIdCached, TypeSyntaxNodeCached<'db, ast::ItemTypeAlias<'db>>>,
389 impl_aliases:
390 OrderedHashMap<ImplAliasIdCached, TypeSyntaxNodeCached<'db, ast::ItemImplAlias<'db>>>,
391 traits: OrderedHashMap<TraitIdCached, TypeSyntaxNodeCached<'db, ast::ItemTrait<'db>>>,
392 impls: OrderedHashMap<ImplDefIdCached, TypeSyntaxNodeCached<'db, ast::ItemImpl<'db>>>,
393 extern_types:
394 OrderedHashMap<ExternTypeIdCached, TypeSyntaxNodeCached<'db, ast::ItemExternType<'db>>>,
395 extern_functions: OrderedHashMap<
396 ExternFunctionIdCached,
397 TypeSyntaxNodeCached<'db, ast::ItemExternFunction<'db>>,
398 >,
399 macro_declarations: OrderedHashMap<
400 MacroDeclarationIdCached,
401 TypeSyntaxNodeCached<'db, ast::ItemMacroDeclaration<'db>>,
402 >,
403 global_uses:
404 OrderedHashMap<GlobalUseIdCached, TypeSyntaxNodeCached<'db, ast::UsePathStar<'db>>>,
405 macro_calls:
406 OrderedHashMap<MacroCallIdCached, TypeSyntaxNodeCached<'db, ast::ItemInlineMacro<'db>>>,
407
408 files: Vec<FileIdCached>,
409
410 generated_file_aux_data: OrderedHashMap<FileIdCached, Option<DynGeneratedFileAuxData>>,
411 plugin_diagnostics: Vec<(ModuleIdCached, PluginDiagnosticCached)>,
412 diagnostics_notes: PluginFileDiagnosticNotesCached,
413}
414impl<'db> ModuleDataCached<'db> {
415 pub fn new(
416 db: &'db dyn Database,
417 module_data: ModuleData<'db>,
418 ctx: &mut DefCacheSavingContext<'db>,
419 ) -> Self {
420 Self {
421 items: module_data
422 .items(db)
423 .iter()
424 .map(|id| ModuleItemIdCached::new(*id, ctx))
425 .collect(),
426 constants: module_data
427 .constants(db)
428 .iter()
429 .map(|(id, node)| {
430 (ConstantIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
431 })
432 .collect(),
433
434 submodules: module_data
435 .submodules(db)
436 .iter()
437 .map(|(id, node)| {
438 (SubmoduleIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
439 })
440 .collect(),
441
442 uses: module_data
443 .uses(db)
444 .iter()
445 .map(|(id, node)| {
446 (UseIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
447 })
448 .collect(),
449 free_functions: module_data
450 .free_functions(db)
451 .iter()
452 .map(|(id, node)| {
453 (
454 FreeFunctionIdCached::new(*id, ctx),
455 TypeSyntaxNodeCached::new(node.clone(), ctx),
456 )
457 })
458 .collect(),
459 structs: module_data
460 .structs(db)
461 .iter()
462 .map(|(id, node)| {
463 (StructIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
464 })
465 .collect(),
466 enums: module_data
467 .enums(db)
468 .iter()
469 .map(|(id, node)| {
470 (EnumIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
471 })
472 .collect(),
473 type_aliases: module_data
474 .type_aliases(db)
475 .iter()
476 .map(|(id, node)| {
477 (
478 ModuleTypeAliasIdCached::new(*id, ctx),
479 TypeSyntaxNodeCached::new(node.clone(), ctx),
480 )
481 })
482 .collect(),
483 impl_aliases: module_data
484 .impl_aliases(db)
485 .iter()
486 .map(|(id, node)| {
487 (ImplAliasIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
488 })
489 .collect(),
490 traits: module_data
491 .traits(db)
492 .iter()
493 .map(|(id, node)| {
494 (TraitIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
495 })
496 .collect(),
497 impls: module_data
498 .impls(db)
499 .iter()
500 .map(|(id, node)| {
501 (ImplDefIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
502 })
503 .collect(),
504 extern_types: module_data
505 .extern_types(db)
506 .iter()
507 .map(|(id, node)| {
508 (
509 ExternTypeIdCached::new(*id, ctx),
510 TypeSyntaxNodeCached::new(node.clone(), ctx),
511 )
512 })
513 .collect(),
514 extern_functions: module_data
515 .extern_functions(db)
516 .iter()
517 .map(|(id, node)| {
518 (
519 ExternFunctionIdCached::new(*id, ctx),
520 TypeSyntaxNodeCached::new(node.clone(), ctx),
521 )
522 })
523 .collect(),
524
525 macro_declarations: module_data
526 .macro_declarations(db)
527 .iter()
528 .map(|(id, node)| {
529 (
530 MacroDeclarationIdCached::new(*id, ctx),
531 TypeSyntaxNodeCached::new(node.clone(), ctx),
532 )
533 })
534 .collect(),
535 global_uses: module_data
536 .global_uses(db)
537 .iter()
538 .map(|(id, node)| {
539 (GlobalUseIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
540 })
541 .collect(),
542 macro_calls: module_data
543 .macro_calls(db)
544 .iter()
545 .map(|(id, node)| {
546 (MacroCallIdCached::new(*id, ctx), TypeSyntaxNodeCached::new(node.clone(), ctx))
547 })
548 .collect(),
549 files: module_data.files(db).iter().map(|id| FileIdCached::new(*id, ctx)).collect(),
550 generated_file_aux_data: module_data
551 .generated_file_aux_data(db)
552 .iter()
553 .map(|(file, aux_data)| (FileIdCached::new(*file, ctx), aux_data.clone()))
554 .collect(),
555
556 plugin_diagnostics: module_data
557 .plugin_diagnostics(db)
558 .iter()
559 .map(|(file_id, diagnostic)| {
560 (
561 ModuleIdCached::new(*file_id, ctx),
562 PluginDiagnosticCached::new(diagnostic, ctx),
563 )
564 })
565 .collect(),
566 diagnostics_notes: module_data
567 .diagnostics_notes(db)
568 .iter()
569 .map(|(file_id, note)| {
570 (FileIdCached::new(*file_id, ctx), DiagnosticNoteCached::new(note.clone(), ctx))
571 })
572 .collect(),
573 }
574 }
575 fn embed(self, ctx: &mut DefCacheLoadingContext<'db>) -> ModuleData<'db> {
576 ModuleData::new(
577 ctx.db,
578 self.items.iter().map(|id| id.embed(ctx)).collect(),
579 ModuleTypesData::new(
580 ctx.db,
581 self.structs.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
582 self.enums.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
583 self.type_aliases
584 .iter()
585 .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
586 .collect(),
587 self.extern_types
588 .iter()
589 .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
590 .collect(),
591 ),
592 ModuleNamedItemsData::new(
593 ctx.db,
594 self.constants.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
595 self.submodules.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
596 self.uses.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
597 self.free_functions
598 .iter()
599 .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
600 .collect(),
601 self.impl_aliases
602 .iter()
603 .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
604 .collect(),
605 self.traits.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
606 self.impls.iter().map(|(id, node)| (id.embed(ctx), node.embed(ctx))).collect(),
607 self.extern_functions
608 .iter()
609 .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
610 .collect(),
611 self.macro_declarations
612 .iter()
613 .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
614 .collect(),
615 ),
616 ModuleUnnamedItemsData::new(
617 ctx.db,
618 self.global_uses
619 .iter()
620 .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
621 .collect(),
622 self.macro_calls
623 .iter()
624 .map(|(id, node)| (id.embed(ctx), node.embed(ctx)))
625 .collect(),
626 ),
627 ModuleFilesData::new(
628 ctx.db,
629 self.files.iter().map(|id| id.embed(ctx)).collect(),
630 self.generated_file_aux_data
631 .into_iter()
632 .map(|(file, aux_data)| (file.embed(ctx), aux_data))
633 .collect(),
634 self.plugin_diagnostics
635 .into_iter()
636 .map(|(file_id, diagnostic)| (file_id.embed(ctx), diagnostic.embed(ctx)))
637 .collect(),
638 self.diagnostics_notes
639 .into_iter()
640 .map(|(file_id, note)| (file_id.embed(ctx), note.embed(ctx)))
641 .collect(),
642 ),
643 )
644 }
645}
646
647#[derive(Serialize, Deserialize, Default, PartialEq, Eq, salsa::Update)]
649pub struct DefCacheLookups {
650 green_ids_lookup: Vec<GreenNodeCached>,
651 crate_ids_lookup: Vec<CrateCached>,
652 submodule_ids_lookup: Vec<SubmoduleCached>,
653 constant_ids_lookup: Vec<ConstantCached>,
654 use_ids_lookup: Vec<UseCached>,
655 free_function_ids_lookup: Vec<FreeFunctionCached>,
656 struct_ids_lookup: Vec<StructCached>,
657 enum_ids_lookup: Vec<EnumCached>,
658 type_alias_ids_lookup: Vec<ModuleTypeAliasCached>,
659 impl_alias_ids_lookup: Vec<ImplAliasCached>,
660 trait_ids_lookup: Vec<TraitCached>,
661 impl_def_ids_lookup: Vec<ImplDefCached>,
662 extern_type_ids_lookup: Vec<ExternTypeCached>,
663 extern_function_ids_lookup: Vec<ExternFunctionCached>,
664 global_use_ids_lookup: Vec<GlobalUseCached>,
665 macro_declaration_ids_lookup: Vec<MacroDeclarationCached>,
666 macro_call_ids_lookup: Vec<MacroCallCached>,
667
668 syntax_node_lookup: Vec<SyntaxNodeIdCached>,
669 file_ids_lookup: Vec<FileCached>,
670}
671
672#[derive(Serialize, Deserialize, Clone)]
673struct TypeSyntaxNodeCached<'db, T: TypedSyntaxNode<'db>> {
674 syntax_node: SyntaxNodeCached,
675 _marker: std::marker::PhantomData<&'db T>,
676}
677impl<'db, T: TypedSyntaxNode<'db>> TypeSyntaxNodeCached<'db, T> {
678 fn new(syntax_node: T, ctx: &mut DefCacheSavingContext<'db>) -> Self {
679 Self {
680 syntax_node: SyntaxNodeCached::new(syntax_node.as_syntax_node(), ctx),
681 _marker: std::marker::PhantomData,
682 }
683 }
684 fn embed(&self, ctx: &mut DefCacheLoadingContext<'db>) -> T {
685 T::from_syntax_node(ctx.db, self.syntax_node.embed(ctx))
686 }
687}
688
689#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
690pub struct GenericParamCached {
691 language_element: LanguageElementCached,
692}
693impl GenericParamCached {
694 pub fn new<'db>(
695 generic_param_id: GenericParamId<'db>,
696 ctx: &mut DefCacheSavingContext<'db>,
697 ) -> Self {
698 Self { language_element: LanguageElementCached::new(generic_param_id, ctx) }
699 }
700
701 pub fn get_embedded<'db>(
702 self,
703 data: &Arc<DefCacheLoadingData<'db>>,
704 db: &'db dyn Database,
705 ) -> GenericParamId<'db> {
706 let (module_id, stable_ptr) = self.language_element.get_embedded(data);
707 GenericParamLongId(module_id, GenericParamPtr(stable_ptr)).intern(db)
708 }
709}
710
711#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq)]
712pub enum ModuleIdCached {
713 CrateRoot(CrateIdCached),
714 Submodule(SubmoduleIdCached),
715 MacroCall { id: MacroCallIdCached, generated_file_id: FileIdCached, is_expose: bool },
716}
717impl ModuleIdCached {
718 pub fn new<'db>(module_id: ModuleId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
719 match module_id {
720 ModuleId::CrateRoot(crate_id) => {
721 ModuleIdCached::CrateRoot(CrateIdCached::new(crate_id, ctx))
722 }
723 ModuleId::Submodule(submodule_id) => {
724 ModuleIdCached::Submodule(SubmoduleIdCached::new(submodule_id, ctx))
725 }
726 ModuleId::MacroCall { id, generated_file_id, is_expose } => ModuleIdCached::MacroCall {
727 id: MacroCallIdCached::new(id, ctx),
728 generated_file_id: FileIdCached::new(generated_file_id, ctx),
729 is_expose,
730 },
731 }
732 }
733 fn embed<'db>(&self, ctx: &mut DefCacheLoadingContext<'db>) -> ModuleId<'db> {
734 match self {
735 ModuleIdCached::CrateRoot(crate_id) => ModuleId::CrateRoot(crate_id.embed(ctx)),
736 ModuleIdCached::Submodule(submodule_id) => ModuleId::Submodule(submodule_id.embed(ctx)),
737 ModuleIdCached::MacroCall { id, generated_file_id, is_expose } => ModuleId::MacroCall {
738 id: id.embed(ctx),
739 generated_file_id: generated_file_id.embed(ctx),
740 is_expose: *is_expose,
741 },
742 }
743 }
744 pub fn get_embedded<'db>(self, data: &Arc<DefCacheLoadingData<'db>>) -> ModuleId<'db> {
745 match self {
746 ModuleIdCached::CrateRoot(crate_id) => ModuleId::CrateRoot(crate_id.get_embedded(data)),
747 ModuleIdCached::Submodule(submodule_id) => {
748 ModuleId::Submodule(submodule_id.get_embedded(data))
749 }
750 ModuleIdCached::MacroCall { id, generated_file_id, is_expose } => ModuleId::MacroCall {
751 id: id.get_embedded(data),
752 generated_file_id: generated_file_id.get_embedded(data),
753 is_expose,
754 },
755 }
756 }
757}
758
759#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
760enum CrateCached {
761 Real { name: String, discriminator: Option<String> },
762 Virtual { name: String, file_id: FileIdCached, settings: String },
763}
764impl CrateCached {
765 fn new<'db>(crate_id: CrateLongId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
766 match crate_id {
767 CrateLongId::Real { name, discriminator } => {
768 CrateCached::Real { name: name.to_string(ctx.db), discriminator }
769 }
770 CrateLongId::Virtual { name, file_id, settings, cache_file: _ } => {
771 CrateCached::Virtual {
772 name: name.to_string(ctx.db),
773 file_id: FileIdCached::new(file_id, ctx),
774 settings,
775 }
776 }
777 }
778 }
779 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> CrateLongId<'db> {
780 match self {
781 CrateCached::Real { name, discriminator } => {
782 CrateLongId::Real { name: SmolStrId::from(ctx.db, name), discriminator }
783 }
784 CrateCached::Virtual { name, file_id, settings } => {
785 CrateLongId::Virtual {
786 name: SmolStrId::from(ctx.db, name),
787 file_id: file_id.embed(ctx),
788 settings,
789 cache_file: None, }
791 }
792 }
793 }
794}
795#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
796pub enum CrateIdCached {
797 SelfCrate,
798 Other(usize),
799}
800impl CrateIdCached {
801 fn new<'db>(crate_id: CrateId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
802 if crate_id == ctx.self_crate_id {
803 return CrateIdCached::SelfCrate;
804 }
805 if let Some(id) = ctx.crate_ids.get(&crate_id) {
806 return *id;
807 }
808 let crate_long_id = CrateCached::new(crate_id.long(ctx.db).clone(), ctx);
809 let id = CrateIdCached::Other(ctx.crate_ids_lookup.len());
810 ctx.crate_ids_lookup.push(crate_long_id);
811 ctx.crate_ids.insert(crate_id, id);
812 id
813 }
814 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> CrateId<'db> {
815 let CrateIdCached::Other(id) = self else {
816 return ctx.self_crate_id;
817 };
818
819 if let Some(crate_id) = ctx.crate_ids.get(&self) {
820 return *crate_id;
821 }
822 let crate_long_id = ctx.crate_ids_lookup[id].clone();
823 let crate_id = crate_long_id.embed(ctx).intern(ctx.db);
824 ctx.data.crate_ids.insert(self, crate_id);
825 crate_id
826 }
827 fn get_embedded<'db>(self, data: &Arc<DefCacheLoadingData<'db>>) -> CrateId<'db> {
828 let CrateIdCached::Other(_) = self else {
829 return data.self_crate_id;
830 };
831 data.crate_ids[&self]
832 }
833}
834
835#[derive(Serialize, Deserialize, Copy, Clone)]
836pub enum ModuleItemIdCached {
837 Constant(ConstantIdCached),
838 Submodule(SubmoduleIdCached),
839 Use(UseIdCached),
840 FreeFunction(FreeFunctionIdCached),
841 Struct(StructIdCached),
842 Enum(EnumIdCached),
843 TypeAlias(ModuleTypeAliasIdCached),
844 ImplAlias(ImplAliasIdCached),
845 Trait(TraitIdCached),
846 Impl(ImplDefIdCached),
847 ExternType(ExternTypeIdCached),
848 ExternFunction(ExternFunctionIdCached),
849 MacroDeclaration(MacroDeclarationIdCached),
850}
851
852impl ModuleItemIdCached {
853 pub fn new<'db>(
854 module_item_id: ModuleItemId<'db>,
855 ctx: &mut DefCacheSavingContext<'db>,
856 ) -> Self {
857 match module_item_id {
858 ModuleItemId::Constant(constant_id) => {
859 ModuleItemIdCached::Constant(ConstantIdCached::new(constant_id, ctx))
860 }
861 ModuleItemId::Submodule(submodule_id) => {
862 ModuleItemIdCached::Submodule(SubmoduleIdCached::new(submodule_id, ctx))
863 }
864 ModuleItemId::Use(use_id) => ModuleItemIdCached::Use(UseIdCached::new(use_id, ctx)),
865 ModuleItemId::FreeFunction(free_function_id) => {
866 ModuleItemIdCached::FreeFunction(FreeFunctionIdCached::new(free_function_id, ctx))
867 }
868 ModuleItemId::Struct(struct_id) => {
869 ModuleItemIdCached::Struct(StructIdCached::new(struct_id, ctx))
870 }
871 ModuleItemId::Enum(enum_id) => {
872 ModuleItemIdCached::Enum(EnumIdCached::new(enum_id, ctx))
873 }
874 ModuleItemId::TypeAlias(type_alias_id) => {
875 ModuleItemIdCached::TypeAlias(ModuleTypeAliasIdCached::new(type_alias_id, ctx))
876 }
877 ModuleItemId::ImplAlias(impl_alias_id) => {
878 ModuleItemIdCached::ImplAlias(ImplAliasIdCached::new(impl_alias_id, ctx))
879 }
880 ModuleItemId::Trait(trait_id) => {
881 ModuleItemIdCached::Trait(TraitIdCached::new(trait_id, ctx))
882 }
883 ModuleItemId::Impl(impl_def_id) => {
884 ModuleItemIdCached::Impl(ImplDefIdCached::new(impl_def_id, ctx))
885 }
886 ModuleItemId::ExternType(extern_type_id) => {
887 ModuleItemIdCached::ExternType(ExternTypeIdCached::new(extern_type_id, ctx))
888 }
889 ModuleItemId::ExternFunction(extern_function_id) => ModuleItemIdCached::ExternFunction(
890 ExternFunctionIdCached::new(extern_function_id, ctx),
891 ),
892 ModuleItemId::MacroDeclaration(macro_declaration_id) => {
893 ModuleItemIdCached::MacroDeclaration(MacroDeclarationIdCached::new(
894 macro_declaration_id,
895 ctx,
896 ))
897 }
898 }
899 }
900 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> ModuleItemId<'db> {
901 match self {
902 ModuleItemIdCached::Constant(constant_id) => {
903 ModuleItemId::Constant(constant_id.embed(ctx))
904 }
905 ModuleItemIdCached::Submodule(submodule_id) => {
906 ModuleItemId::Submodule(submodule_id.embed(ctx))
907 }
908 ModuleItemIdCached::Use(use_id) => ModuleItemId::Use(use_id.embed(ctx)),
909 ModuleItemIdCached::FreeFunction(free_function_id) => {
910 ModuleItemId::FreeFunction(free_function_id.embed(ctx))
911 }
912 ModuleItemIdCached::Struct(struct_id) => ModuleItemId::Struct(struct_id.embed(ctx)),
913 ModuleItemIdCached::Enum(enum_id) => ModuleItemId::Enum(enum_id.embed(ctx)),
914 ModuleItemIdCached::TypeAlias(type_alias_id) => {
915 ModuleItemId::TypeAlias(type_alias_id.embed(ctx))
916 }
917 ModuleItemIdCached::ImplAlias(impl_alias_id) => {
918 ModuleItemId::ImplAlias(impl_alias_id.embed(ctx))
919 }
920 ModuleItemIdCached::Trait(trait_id) => ModuleItemId::Trait(trait_id.embed(ctx)),
921 ModuleItemIdCached::Impl(impl_def_id) => ModuleItemId::Impl(impl_def_id.embed(ctx)),
922 ModuleItemIdCached::ExternType(extern_type_id) => {
923 ModuleItemId::ExternType(extern_type_id.embed(ctx))
924 }
925 ModuleItemIdCached::ExternFunction(extern_function_id) => {
926 ModuleItemId::ExternFunction(extern_function_id.embed(ctx))
927 }
928 ModuleItemIdCached::MacroDeclaration(macro_declaration_id) => {
929 ModuleItemId::MacroDeclaration(macro_declaration_id.embed(ctx))
930 }
931 }
932 }
933 pub fn get_embedded<'db>(&self, data: &Arc<DefCacheLoadingData<'db>>) -> ModuleItemId<'db> {
934 match self {
935 ModuleItemIdCached::Constant(id) => ModuleItemId::Constant(id.get_embedded(data)),
936 ModuleItemIdCached::Submodule(id) => ModuleItemId::Submodule(id.get_embedded(data)),
937 ModuleItemIdCached::Use(id) => ModuleItemId::Use(id.get_embedded(data)),
938 ModuleItemIdCached::FreeFunction(id) => {
939 ModuleItemId::FreeFunction(id.get_embedded(data))
940 }
941 ModuleItemIdCached::Struct(id) => ModuleItemId::Struct(id.get_embedded(data)),
942 ModuleItemIdCached::Enum(id) => ModuleItemId::Enum(id.get_embedded(data)),
943 ModuleItemIdCached::TypeAlias(id) => ModuleItemId::TypeAlias(id.get_embedded(data)),
944 ModuleItemIdCached::ImplAlias(id) => ModuleItemId::ImplAlias(id.get_embedded(data)),
945 ModuleItemIdCached::Trait(id) => ModuleItemId::Trait(id.get_embedded(data)),
946 ModuleItemIdCached::Impl(id) => ModuleItemId::Impl(id.get_embedded(data)),
947 ModuleItemIdCached::ExternType(id) => ModuleItemId::ExternType(id.get_embedded(data)),
948 ModuleItemIdCached::ExternFunction(id) => {
949 ModuleItemId::ExternFunction(id.get_embedded(data))
950 }
951 ModuleItemIdCached::MacroDeclaration(id) => {
952 ModuleItemId::MacroDeclaration(id.get_embedded(data))
953 }
954 }
955 }
956}
957
958#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
959struct ConstantCached {
960 language_element: LanguageElementCached,
961}
962impl ConstantCached {
963 fn new<'db>(constant_id: ConstantId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
964 Self { language_element: LanguageElementCached::new(constant_id, ctx) }
965 }
966 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> ConstantLongId<'db> {
967 let (module_id, stable_ptr) = self.language_element.embed(ctx);
968
969 ConstantLongId(module_id, ItemConstantPtr(stable_ptr))
970 }
971}
972
973#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
974pub struct ConstantIdCached(usize);
975
976impl ConstantIdCached {
977 fn new<'db>(id: ConstantId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
978 if let Some(cached_id) = ctx.constant_ids.get(&id) {
979 return *cached_id;
980 }
981 let cached = ConstantCached::new(id, ctx);
982 let cached_id = ConstantIdCached(ctx.constant_ids_lookup.len());
983 ctx.constant_ids_lookup.push(cached);
984 ctx.constant_ids.insert(id, cached_id);
985 cached_id
986 }
987 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> ConstantId<'db> {
988 if let Some(id) = ctx.constant_ids.get(&self) {
989 return *id;
990 }
991 let cached = ctx.constant_ids_lookup[self.0].clone();
992 let id = cached.embed(ctx).intern(ctx.db);
993 ctx.constant_ids.insert(self, id);
994 id
995 }
996 pub fn get_embedded<'db>(self, data: &Arc<DefCacheLoadingData<'db>>) -> ConstantId<'db> {
997 data.constant_ids[&self]
998 }
999}
1000
1001#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1002struct SubmoduleCached {
1003 language_element: LanguageElementCached,
1004}
1005impl SubmoduleCached {
1006 fn new<'db>(submodule_id: SubmoduleId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1007 Self { language_element: LanguageElementCached::new(submodule_id, ctx) }
1008 }
1009 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> SubmoduleLongId<'db> {
1010 let (module_id, stable_ptr) = self.language_element.embed(ctx);
1011
1012 SubmoduleLongId(module_id, ItemModulePtr(stable_ptr))
1013 }
1014}
1015
1016#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1017pub struct SubmoduleIdCached(usize);
1018
1019impl SubmoduleIdCached {
1020 fn new<'db>(id: SubmoduleId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1021 if let Some(cached_id) = ctx.submodule_ids.get(&id) {
1022 return *cached_id;
1023 }
1024 let cached = SubmoduleCached::new(id, ctx);
1025 let cached_id = SubmoduleIdCached(ctx.submodule_ids_lookup.len());
1026 ctx.submodule_ids_lookup.push(cached);
1027 ctx.submodule_ids.insert(id, cached_id);
1028 cached_id
1029 }
1030 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> SubmoduleId<'db> {
1031 if let Some(id) = ctx.submodule_ids.get(&self) {
1032 return *id;
1033 }
1034 let cached = ctx.submodule_ids_lookup[self.0].clone();
1035 let id = cached.embed(ctx).intern(ctx.db);
1036 ctx.submodule_ids.insert(self, id);
1037 id
1038 }
1039 fn get_embedded<'db>(self, data: &Arc<DefCacheLoadingData<'db>>) -> SubmoduleId<'db> {
1040 data.submodule_ids[&self]
1041 }
1042}
1043
1044#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1045struct UseCached {
1046 language_element: LanguageElementCached,
1047}
1048impl UseCached {
1049 fn new<'db>(use_id: UseId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1050 Self { language_element: LanguageElementCached::new(use_id, ctx) }
1051 }
1052 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> UseLongId<'db> {
1053 let (module_id, stable_ptr) = self.language_element.embed(ctx);
1054
1055 UseLongId(module_id, UsePathLeafPtr(stable_ptr))
1056 }
1057}
1058
1059#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1060pub struct UseIdCached(usize);
1061
1062impl UseIdCached {
1063 fn new<'db>(id: UseId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1064 if let Some(cached_id) = ctx.use_ids.get(&id) {
1065 return *cached_id;
1066 }
1067 let cached = UseCached::new(id, ctx);
1068 let cached_id = UseIdCached(ctx.use_ids_lookup.len());
1069 ctx.use_ids_lookup.push(cached);
1070 ctx.use_ids.insert(id, cached_id);
1071 cached_id
1072 }
1073 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> UseId<'db> {
1074 if let Some(id) = ctx.use_ids.get(&self) {
1075 return *id;
1076 }
1077 let cached = ctx.use_ids_lookup[self.0].clone();
1078 let id = cached.embed(ctx).intern(ctx.db);
1079 ctx.use_ids.insert(self, id);
1080 id
1081 }
1082 pub fn get_embedded<'db>(self, data: &Arc<DefCacheLoadingData<'db>>) -> UseId<'db> {
1083 data.use_ids[&self]
1084 }
1085}
1086
1087#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1088struct FreeFunctionCached {
1089 language_element: LanguageElementCached,
1090}
1091impl FreeFunctionCached {
1092 fn new<'db>(
1093 free_function_id: FreeFunctionId<'db>,
1094 ctx: &mut DefCacheSavingContext<'db>,
1095 ) -> Self {
1096 Self { language_element: LanguageElementCached::new(free_function_id, ctx) }
1097 }
1098 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> FreeFunctionLongId<'db> {
1099 let (module_id, stable_ptr) = self.language_element.embed(ctx);
1100
1101 FreeFunctionLongId(module_id, FunctionWithBodyPtr(stable_ptr))
1102 }
1103}
1104
1105#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1106pub struct FreeFunctionIdCached(usize);
1107
1108impl FreeFunctionIdCached {
1109 fn new<'db>(id: FreeFunctionId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1110 if let Some(cached_id) = ctx.free_function_ids.get(&id) {
1111 return *cached_id;
1112 }
1113 let cached = FreeFunctionCached::new(id, ctx);
1114 let cached_id = FreeFunctionIdCached(ctx.free_function_ids_lookup.len());
1115 ctx.free_function_ids_lookup.push(cached);
1116 ctx.free_function_ids.insert(id, cached_id);
1117 cached_id
1118 }
1119 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> FreeFunctionId<'db> {
1120 if let Some(id) = ctx.free_function_ids.get(&self) {
1121 return *id;
1122 }
1123 let cached = ctx.free_function_ids_lookup[self.0].clone();
1124 let id = cached.embed(ctx).intern(ctx.db);
1125 ctx.free_function_ids.insert(self, id);
1126 id
1127 }
1128 pub fn get_embedded<'db>(self, data: &Arc<DefCacheLoadingData<'db>>) -> FreeFunctionId<'db> {
1129 data.free_function_ids[&self]
1130 }
1131}
1132
1133#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1134struct StructCached {
1135 language_element: LanguageElementCached,
1136}
1137impl StructCached {
1138 fn new<'db>(struct_id: StructId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1139 Self { language_element: LanguageElementCached::new(struct_id, ctx) }
1140 }
1141 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> StructLongId<'db> {
1142 let (module_id, stable_ptr) = self.language_element.embed(ctx);
1143
1144 StructLongId(module_id, ItemStructPtr(stable_ptr))
1145 }
1146}
1147
1148#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1149pub struct StructIdCached(usize);
1150
1151impl StructIdCached {
1152 fn new<'db>(id: StructId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1153 if let Some(cached_id) = ctx.struct_ids.get(&id) {
1154 return *cached_id;
1155 }
1156 let cached = StructCached::new(id, ctx);
1157 let cached_id = StructIdCached(ctx.struct_ids_lookup.len());
1158 ctx.struct_ids_lookup.push(cached);
1159 ctx.struct_ids.insert(id, cached_id);
1160 cached_id
1161 }
1162 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> StructId<'db> {
1163 if let Some(id) = ctx.struct_ids.get(&self) {
1164 return *id;
1165 }
1166 let cached = ctx.struct_ids_lookup[self.0].clone();
1167 let id = cached.embed(ctx).intern(ctx.db);
1168 ctx.struct_ids.insert(self, id);
1169 id
1170 }
1171 pub fn get_embedded<'db>(self, data: &Arc<DefCacheLoadingData<'db>>) -> StructId<'db> {
1172 data.struct_ids[&self]
1173 }
1174}
1175
1176#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1177struct EnumCached {
1178 language_element: LanguageElementCached,
1179}
1180impl EnumCached {
1181 fn new<'db>(enum_id: EnumId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1182 Self { language_element: LanguageElementCached::new(enum_id, ctx) }
1183 }
1184 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> EnumLongId<'db> {
1185 let (module_id, stable_ptr) = self.language_element.embed(ctx);
1186
1187 EnumLongId(module_id, ItemEnumPtr(stable_ptr))
1188 }
1189}
1190
1191#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1192pub struct EnumIdCached(usize);
1193
1194impl EnumIdCached {
1195 fn new<'db>(id: EnumId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1196 if let Some(cached_id) = ctx.enum_ids.get(&id) {
1197 return *cached_id;
1198 }
1199 let cached = EnumCached::new(id, ctx);
1200 let cached_id = EnumIdCached(ctx.enum_ids_lookup.len());
1201 ctx.enum_ids_lookup.push(cached);
1202 ctx.enum_ids.insert(id, cached_id);
1203 cached_id
1204 }
1205 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> EnumId<'db> {
1206 if let Some(id) = ctx.enum_ids.get(&self) {
1207 return *id;
1208 }
1209 let cached = ctx.enum_ids_lookup[self.0].clone();
1210 let id = cached.embed(ctx).intern(ctx.db);
1211 ctx.enum_ids.insert(self, id);
1212 id
1213 }
1214 pub fn get_embedded<'db>(self, data: &Arc<DefCacheLoadingData<'db>>) -> EnumId<'db> {
1215 data.enum_ids[&self]
1216 }
1217}
1218
1219#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1220struct ModuleTypeAliasCached {
1221 language_element: LanguageElementCached,
1222}
1223impl ModuleTypeAliasCached {
1224 fn new<'db>(
1225 type_alias_id: ModuleTypeAliasId<'db>,
1226 ctx: &mut DefCacheSavingContext<'db>,
1227 ) -> Self {
1228 Self { language_element: LanguageElementCached::new(type_alias_id, ctx) }
1229 }
1230 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> ModuleTypeAliasLongId<'db> {
1231 let (module_id, stable_ptr) = self.language_element.embed(ctx);
1232
1233 ModuleTypeAliasLongId(module_id, ItemTypeAliasPtr(stable_ptr))
1234 }
1235}
1236
1237#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1238pub struct ModuleTypeAliasIdCached(usize);
1239
1240impl ModuleTypeAliasIdCached {
1241 fn new<'db>(id: ModuleTypeAliasId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1242 if let Some(cached_id) = ctx.type_alias_ids.get(&id) {
1243 return *cached_id;
1244 }
1245 let cached = ModuleTypeAliasCached::new(id, ctx);
1246 let cached_id = ModuleTypeAliasIdCached(ctx.type_alias_ids_lookup.len());
1247 ctx.type_alias_ids_lookup.push(cached);
1248 ctx.type_alias_ids.insert(id, cached_id);
1249 cached_id
1250 }
1251 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> ModuleTypeAliasId<'db> {
1252 if let Some(id) = ctx.type_alias_ids.get(&self) {
1253 return *id;
1254 }
1255 let cached = ctx.type_alias_ids_lookup[self.0].clone();
1256 let id = cached.embed(ctx).intern(ctx.db);
1257 ctx.type_alias_ids.insert(self, id);
1258 id
1259 }
1260 pub fn get_embedded<'db>(self, data: &Arc<DefCacheLoadingData<'db>>) -> ModuleTypeAliasId<'db> {
1261 data.type_alias_ids[&self]
1262 }
1263}
1264
1265#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1266struct ImplAliasCached {
1267 language_element: LanguageElementCached,
1268}
1269impl ImplAliasCached {
1270 fn new<'db>(impl_alias_id: ImplAliasId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1271 Self { language_element: LanguageElementCached::new(impl_alias_id, ctx) }
1272 }
1273 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> ImplAliasLongId<'db> {
1274 let (module_id, stable_ptr) = self.language_element.embed(ctx);
1275
1276 ImplAliasLongId(module_id, ItemImplAliasPtr(stable_ptr))
1277 }
1278}
1279
1280#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1281pub struct ImplAliasIdCached(usize);
1282
1283impl ImplAliasIdCached {
1284 pub fn new<'db>(id: ImplAliasId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1285 if let Some(cached_id) = ctx.impl_alias_ids.get(&id) {
1286 return *cached_id;
1287 }
1288 let cached = ImplAliasCached::new(id, ctx);
1289 let cached_id = ImplAliasIdCached(ctx.impl_alias_ids_lookup.len());
1290 ctx.impl_alias_ids_lookup.push(cached);
1291 ctx.impl_alias_ids.insert(id, cached_id);
1292 cached_id
1293 }
1294 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> ImplAliasId<'db> {
1295 if let Some(id) = ctx.impl_alias_ids.get(&self) {
1296 return *id;
1297 }
1298 let cached = ctx.impl_alias_ids_lookup[self.0].clone();
1299 let id = cached.embed(ctx).intern(ctx.db);
1300 ctx.impl_alias_ids.insert(self, id);
1301 id
1302 }
1303 pub fn get_embedded<'db>(self, data: &Arc<DefCacheLoadingData<'db>>) -> ImplAliasId<'db> {
1304 data.impl_alias_ids[&self]
1305 }
1306}
1307
1308#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1309struct TraitCached {
1310 language_element: LanguageElementCached,
1311}
1312impl TraitCached {
1313 fn new<'db>(trait_id: TraitId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1314 Self { language_element: LanguageElementCached::new(trait_id, ctx) }
1315 }
1316 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> TraitLongId<'db> {
1317 let (module_id, stable_ptr) = self.language_element.embed(ctx);
1318
1319 TraitLongId(module_id, ItemTraitPtr(stable_ptr))
1320 }
1321}
1322
1323#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1324pub struct TraitIdCached(usize);
1325
1326impl TraitIdCached {
1327 fn new<'db>(id: TraitId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1328 if let Some(cached_id) = ctx.trait_ids.get(&id) {
1329 return *cached_id;
1330 }
1331 let cached = TraitCached::new(id, ctx);
1332 let cached_id = TraitIdCached(ctx.trait_ids_lookup.len());
1333 ctx.trait_ids_lookup.push(cached);
1334 ctx.trait_ids.insert(id, cached_id);
1335 cached_id
1336 }
1337 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> TraitId<'db> {
1338 if let Some(id) = ctx.trait_ids.get(&self) {
1339 return *id;
1340 }
1341 let cached = ctx.trait_ids_lookup[self.0].clone();
1342 let id = cached.embed(ctx).intern(ctx.db);
1343 ctx.trait_ids.insert(self, id);
1344 id
1345 }
1346 pub fn get_embedded<'db>(self, data: &Arc<DefCacheLoadingData<'db>>) -> TraitId<'db> {
1347 data.trait_ids[&self]
1348 }
1349}
1350
1351#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1352struct ImplDefCached {
1353 language_element: LanguageElementCached,
1354}
1355impl ImplDefCached {
1356 fn new<'db>(impl_def_id: ImplDefId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1357 Self { language_element: LanguageElementCached::new(impl_def_id, ctx) }
1358 }
1359 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> ImplDefLongId<'db> {
1360 let (module_id, stable_ptr) = self.language_element.embed(ctx);
1361
1362 ImplDefLongId(module_id, ItemImplPtr(stable_ptr))
1363 }
1364}
1365
1366#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1367pub struct ImplDefIdCached(usize);
1368
1369impl ImplDefIdCached {
1370 pub fn new<'db>(id: ImplDefId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1371 if let Some(cached_id) = ctx.impl_def_ids.get(&id) {
1372 return *cached_id;
1373 }
1374 let cached = ImplDefCached::new(id, ctx);
1375 let cached_id = ImplDefIdCached(ctx.impl_def_ids_lookup.len());
1376 ctx.impl_def_ids_lookup.push(cached);
1377 ctx.impl_def_ids.insert(id, cached_id);
1378 cached_id
1379 }
1380
1381 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> ImplDefId<'db> {
1382 if let Some(id) = ctx.impl_def_ids.get(&self) {
1383 return *id;
1384 }
1385 let cached = ctx.impl_def_ids_lookup[self.0].clone();
1386 let id = cached.embed(ctx).intern(ctx.db);
1387 ctx.impl_def_ids.insert(self, id);
1388 id
1389 }
1390
1391 pub fn get_embedded<'db>(self, data: &Arc<DefCacheLoadingData<'db>>) -> ImplDefId<'db> {
1392 data.impl_def_ids[&self]
1393 }
1394}
1395
1396#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1397struct ExternTypeCached {
1398 language_element: LanguageElementCached,
1399}
1400impl ExternTypeCached {
1401 fn new<'db>(extern_type_id: ExternTypeId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1402 Self { language_element: LanguageElementCached::new(extern_type_id, ctx) }
1403 }
1404 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> ExternTypeLongId<'db> {
1405 let (module_id, stable_ptr) = self.language_element.embed(ctx);
1406
1407 ExternTypeLongId(module_id, ItemExternTypePtr(stable_ptr))
1408 }
1409}
1410
1411#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1412pub struct ExternTypeIdCached(usize);
1413
1414impl ExternTypeIdCached {
1415 fn new<'db>(id: ExternTypeId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1416 if let Some(cached_id) = ctx.extern_type_ids.get(&id) {
1417 return *cached_id;
1418 }
1419 let cached = ExternTypeCached::new(id, ctx);
1420 let cached_id = ExternTypeIdCached(ctx.extern_type_ids_lookup.len());
1421 ctx.extern_type_ids_lookup.push(cached);
1422 ctx.extern_type_ids.insert(id, cached_id);
1423 cached_id
1424 }
1425 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> ExternTypeId<'db> {
1426 if let Some(id) = ctx.extern_type_ids.get(&self) {
1427 return *id;
1428 }
1429 let cached = ctx.extern_type_ids_lookup[self.0].clone();
1430 let id = cached.embed(ctx).intern(ctx.db);
1431 ctx.extern_type_ids.insert(self, id);
1432 id
1433 }
1434 pub fn get_embedded<'db>(self, data: &Arc<DefCacheLoadingData<'db>>) -> ExternTypeId<'db> {
1435 data.extern_type_ids[&self]
1436 }
1437}
1438
1439#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1440struct ExternFunctionCached {
1441 language_element: LanguageElementCached,
1442}
1443impl ExternFunctionCached {
1444 fn new<'db>(
1445 extern_function_id: ExternFunctionId<'db>,
1446 ctx: &mut DefCacheSavingContext<'db>,
1447 ) -> Self {
1448 Self { language_element: LanguageElementCached::new(extern_function_id, ctx) }
1449 }
1450 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> ExternFunctionLongId<'db> {
1451 let (module_id, stable_ptr) = self.language_element.embed(ctx);
1452
1453 ExternFunctionLongId(module_id, ItemExternFunctionPtr(stable_ptr))
1454 }
1455}
1456
1457#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1458pub struct ExternFunctionIdCached(usize);
1459
1460impl ExternFunctionIdCached {
1461 fn new<'db>(id: ExternFunctionId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1462 if let Some(cached_id) = ctx.extern_function_ids.get(&id) {
1463 return *cached_id;
1464 }
1465 let cached = ExternFunctionCached::new(id, ctx);
1466 let cached_id = ExternFunctionIdCached(ctx.extern_function_ids_lookup.len());
1467 ctx.extern_function_ids_lookup.push(cached);
1468 ctx.extern_function_ids.insert(id, cached_id);
1469 cached_id
1470 }
1471 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> ExternFunctionId<'db> {
1472 if let Some(id) = ctx.extern_function_ids.get(&self) {
1473 return *id;
1474 }
1475 let cached = ctx.extern_function_ids_lookup[self.0].clone();
1476 let id = cached.embed(ctx).intern(ctx.db);
1477 ctx.extern_function_ids.insert(self, id);
1478 id
1479 }
1480 pub fn get_embedded<'db>(self, data: &Arc<DefCacheLoadingData<'db>>) -> ExternFunctionId<'db> {
1481 data.extern_function_ids[&self]
1482 }
1483}
1484#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1485struct MacroDeclarationCached {
1486 language_element: LanguageElementCached,
1487}
1488
1489impl MacroDeclarationCached {
1490 fn new<'db>(
1491 macro_declaration_id: MacroDeclarationId<'db>,
1492 ctx: &mut DefCacheSavingContext<'db>,
1493 ) -> Self {
1494 Self { language_element: LanguageElementCached::new(macro_declaration_id, ctx) }
1495 }
1496 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> MacroDeclarationLongId<'db> {
1497 let (module_id, stable_ptr) = self.language_element.embed(ctx);
1498
1499 MacroDeclarationLongId(module_id, ItemMacroDeclarationPtr(stable_ptr))
1500 }
1501}
1502
1503#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1504pub struct MacroDeclarationIdCached(usize);
1505
1506impl MacroDeclarationIdCached {
1507 fn new<'db>(id: MacroDeclarationId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1508 if let Some(cached_id) = ctx.macro_declaration_ids.get(&id) {
1509 return *cached_id;
1510 }
1511 let cached = MacroDeclarationCached::new(id, ctx);
1512 let cached_id = MacroDeclarationIdCached(ctx.macro_declaration_ids_lookup.len());
1513 ctx.macro_declaration_ids_lookup.push(cached);
1514 ctx.macro_declaration_ids.insert(id, cached_id);
1515 cached_id
1516 }
1517 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> MacroDeclarationId<'db> {
1518 if let Some(id) = ctx.macro_declaration_ids.get(&self) {
1519 return *id;
1520 }
1521 let cached = ctx.macro_declaration_ids_lookup[self.0].clone();
1522 let id = cached.embed(ctx).intern(ctx.db);
1523 ctx.macro_declaration_ids.insert(self, id);
1524 id
1525 }
1526 pub fn get_embedded<'db>(
1527 self,
1528 data: &Arc<DefCacheLoadingData<'db>>,
1529 ) -> MacroDeclarationId<'db> {
1530 data.macro_declaration_ids[&self]
1531 }
1532}
1533
1534#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1535struct MacroCallCached {
1536 language_element: LanguageElementCached,
1537}
1538impl MacroCallCached {
1539 fn new<'db>(macro_call: MacroCallId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1540 Self { language_element: LanguageElementCached::new(macro_call, ctx) }
1541 }
1542
1543 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> MacroCallLongId<'db> {
1544 let (module_id, stable_ptr) = self.language_element.embed(ctx);
1545 MacroCallLongId(module_id, ItemInlineMacroPtr(stable_ptr))
1546 }
1547}
1548
1549#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1550pub struct MacroCallIdCached(usize);
1551impl MacroCallIdCached {
1552 fn new<'db>(id: MacroCallId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1553 if let Some(cached_id) = ctx.macro_call_ids.get(&id) {
1554 return *cached_id;
1555 }
1556 let cached = MacroCallCached::new(id, ctx);
1557 let id_cached = MacroCallIdCached(ctx.macro_call_ids_lookup.len());
1558 ctx.macro_call_ids_lookup.push(cached);
1559 ctx.macro_call_ids.insert(id, id_cached);
1560 id_cached
1561 }
1562 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> MacroCallId<'db> {
1563 if let Some(id) = ctx.macro_call_ids.get(&self) {
1564 return *id;
1565 }
1566 let cached = ctx.macro_call_ids_lookup[self.0].clone();
1567 let id = cached.embed(ctx).intern(ctx.db);
1568 ctx.macro_call_ids.insert(self, id);
1569 id
1570 }
1571 fn get_embedded<'db>(&self, data: &Arc<DefCacheLoadingData<'db>>) -> MacroCallId<'db> {
1572 data.macro_call_ids[self]
1573 }
1574}
1575
1576#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1577struct GlobalUseCached {
1578 language_element: LanguageElementCached,
1579}
1580impl GlobalUseCached {
1581 fn new<'db>(global_use_id: GlobalUseId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1582 Self { language_element: LanguageElementCached::new(global_use_id, ctx) }
1583 }
1584 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> GlobalUseLongId<'db> {
1585 let (module_id, stable_ptr) = self.language_element.embed(ctx);
1586
1587 GlobalUseLongId(module_id, UsePathStarPtr(stable_ptr))
1588 }
1589}
1590
1591#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash, salsa::Update)]
1592pub struct GlobalUseIdCached(usize);
1593
1594impl GlobalUseIdCached {
1595 pub fn new<'db>(id: GlobalUseId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1596 if let Some(cached_id) = ctx.global_use_ids.get(&id) {
1597 return *cached_id;
1598 }
1599 let cached = GlobalUseCached::new(id, ctx);
1600 let cached_id = GlobalUseIdCached(ctx.global_use_ids_lookup.len());
1601 ctx.global_use_ids_lookup.push(cached);
1602 ctx.global_use_ids.insert(id, cached_id);
1603 cached_id
1604 }
1605 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> GlobalUseId<'db> {
1606 if let Some(id) = ctx.global_use_ids.get(&self) {
1607 return *id;
1608 }
1609 let cached = ctx.global_use_ids_lookup[self.0].clone();
1610 let id = cached.embed(ctx).intern(ctx.db);
1611 ctx.global_use_ids.insert(self, id);
1612 id
1613 }
1614 pub fn get_embedded<'db>(&self, data: &Arc<DefCacheLoadingData<'db>>) -> GlobalUseId<'db> {
1615 data.global_use_ids[self]
1616 }
1617}
1618
1619#[derive(Serialize, Deserialize, Clone, Copy, Hash, Eq, PartialEq, salsa::Update, Debug)]
1620struct SyntaxNodeCached(usize);
1621
1622#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
1623enum SyntaxNodeIdCached {
1624 Root(FileIdCached, GreenIdCached),
1625 Child {
1626 parent: SyntaxNodeCached,
1627 kind: SyntaxKind,
1628 key_fields: Vec<GreenIdCached>,
1629 index: usize,
1630 },
1631}
1632
1633impl SyntaxNodeIdCached {
1634 fn new<'db>(
1635 ctx: &mut DefCacheSavingContext<'db>,
1636 id: &SyntaxNodeId<'db>,
1637 syntax_node: SyntaxNode<'db>,
1638 ) -> Self {
1639 match id {
1640 SyntaxNodeId::Root(file_id) => {
1641 let green = syntax_node.green_node(ctx.db).clone().intern(ctx.db);
1642 Self::Root(FileIdCached::new(*file_id, ctx), GreenIdCached::new(green, ctx))
1643 }
1644 SyntaxNodeId::Child { parent, key_fields, index } => Self::Child {
1645 parent: SyntaxNodeCached::new(*parent, ctx),
1646 kind: syntax_node.kind(ctx.db),
1647 key_fields: key_fields.into_iter().map(|id| GreenIdCached::new(*id, ctx)).collect(),
1648 index: *index,
1649 },
1650 }
1651 }
1652
1653 fn from_raw(
1654 ctx: &mut DefCacheLoadingContext<'_>,
1655 parent: SyntaxNodeCached,
1656 kind: SyntaxKind,
1657 index: usize,
1658 key_fields: &[GreenId<'_>],
1659 ) -> Option<Self> {
1660 let mut cached_key_fields = Vec::with_capacity(key_fields.len());
1661 for id in key_fields {
1662 let Some(cached_id) = ctx.reverse_green_ids.get(id) else {
1663 return None;
1665 };
1666 cached_key_fields.push(*cached_id);
1667 }
1668 Some(Self::Child { parent, kind, key_fields: cached_key_fields, index })
1669 }
1670}
1671
1672impl SyntaxNodeCached {
1673 fn new<'db>(syntax_node: SyntaxNode<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1674 if let Some(res) = ctx.syntax_nodes.get(&syntax_node) {
1675 return *res;
1676 }
1677 let db = ctx.db;
1678 let green = syntax_node.green_node(db);
1680 GreenIdCached::new(green.clone().intern(db), ctx);
1681
1682 let id = SyntaxNodeIdCached::new(ctx, syntax_node.raw_id(db), syntax_node);
1683 let cached_node = SyntaxNodeCached(ctx.syntax_node_lookup.len());
1684 ctx.syntax_node_lookup.push(id);
1685 ctx.syntax_nodes.insert(syntax_node, cached_node);
1686 cached_node
1687 }
1688 fn embed<'db>(&self, ctx: &mut DefCacheLoadingContext<'db>) -> SyntaxNode<'db> {
1689 if let Some(node) = ctx.syntax_nodes.get(self) {
1690 return *node;
1691 }
1692 let id_cached = ctx.syntax_node_lookup[self.0].clone();
1693 match &id_cached {
1694 SyntaxNodeIdCached::Root(file_id, green_id) => {
1695 let fid = file_id.embed(ctx);
1696 let green = green_id.embed(ctx);
1697 let syntax = cairo_lang_syntax::node::SyntaxNode::new_root(ctx.db, fid, green);
1698 ctx.syntax_nodes.insert(*self, syntax);
1699 }
1700 SyntaxNodeIdCached::Child { parent, .. } => {
1701 let parent_node = parent.embed(ctx);
1702 let children = parent_node.get_children(ctx.db);
1703 for child in children {
1705 let SyntaxNodeId::Child { index, key_fields, .. } = child.raw_id(ctx.db) else {
1706 panic!("Unexpected SyntaxNodeId type root when creating child");
1707 };
1708 let kind = child.kind(ctx.db);
1709 let Some(child_id) =
1710 SyntaxNodeIdCached::from_raw(ctx, *parent, kind, *index, key_fields)
1711 else {
1712 continue;
1713 };
1714 let Some(&child_cached) = ctx.reverse_syntax_node_lookup.get(&child_id) else {
1716 continue;
1717 };
1718 ctx.syntax_nodes.insert(child_cached, *child);
1719 }
1720 }
1721 };
1722 *ctx.syntax_nodes
1723 .get(self)
1724 .unwrap_or_else(|| panic!("Failed to find syntax node {:?} after embedding", self.0))
1725 }
1726 fn get_embedded<'db>(&self, data: &Arc<DefCacheLoadingData<'db>>) -> SyntaxNode<'db> {
1727 data.syntax_nodes[self]
1728 }
1729}
1730
1731#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq)]
1732pub struct LanguageElementCached {
1733 module_id: ModuleIdCached,
1734 stable_ptr: SyntaxStablePtrIdCached,
1735}
1736impl LanguageElementCached {
1737 pub fn new<'db, T: LanguageElementId<'db> + 'db>(
1738 language_element: T,
1739 ctx: &mut DefCacheSavingContext<'db>,
1740 ) -> Self {
1741 Self {
1742 module_id: ModuleIdCached::new(language_element.parent_module(ctx.db), ctx),
1743 stable_ptr: SyntaxStablePtrIdCached::new(
1744 language_element.untyped_stable_ptr(ctx.db),
1745 ctx,
1746 ),
1747 }
1748 }
1749 fn embed<'db>(
1750 self,
1751 ctx: &mut DefCacheLoadingContext<'db>,
1752 ) -> (ModuleId<'db>, SyntaxStablePtrId<'db>) {
1753 let module_id = self.module_id.embed(ctx);
1754 let stable_ptr = self.stable_ptr.embed(ctx);
1755 (module_id, stable_ptr)
1756 }
1757 pub fn get_embedded<'db>(
1758 self,
1759 data: &Arc<DefCacheLoadingData<'db>>,
1760 ) -> (ModuleId<'db>, SyntaxStablePtrId<'db>) {
1761 let module_id = self.module_id.get_embedded(data);
1762 let stable_ptr = self.stable_ptr.get_embedded(data);
1763 (module_id, stable_ptr)
1764 }
1765}
1766
1767#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1768enum GreenNodeDetailsCached {
1769 Token(String),
1770 Node { children: Vec<GreenIdCached>, width: TextWidth },
1771}
1772
1773impl GreenNodeDetailsCached {
1774 fn new<'db>(
1775 green_node_details: &GreenNodeDetails<'db>,
1776 ctx: &mut DefCacheSavingContext<'db>,
1777 ) -> GreenNodeDetailsCached {
1778 match green_node_details {
1779 GreenNodeDetails::Token(token) => {
1780 GreenNodeDetailsCached::Token(token.long(ctx.db).to_string())
1781 }
1782 GreenNodeDetails::Node { children, width } => GreenNodeDetailsCached::Node {
1783 children: children.iter().map(|child| GreenIdCached::new(*child, ctx)).collect(),
1784 width: *width,
1785 },
1786 }
1787 }
1788 fn embed<'db>(&self, ctx: &mut DefCacheLoadingContext<'db>) -> GreenNodeDetails<'db> {
1789 match self {
1790 GreenNodeDetailsCached::Token(token) => {
1791 GreenNodeDetails::Token(SmolStrId::from(ctx.db, token))
1792 }
1793 GreenNodeDetailsCached::Node { children, width } => GreenNodeDetails::Node {
1794 children: children.iter().map(|child| child.embed(ctx)).collect(),
1795 width: *width,
1796 },
1797 }
1798 }
1799}
1800
1801#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1802struct GreenNodeCached {
1803 kind: SyntaxKind,
1804 details: GreenNodeDetailsCached,
1805}
1806impl GreenNodeCached {
1807 fn new<'db>(green_node: &GreenNode<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1808 Self {
1809 kind: green_node.kind,
1810 details: GreenNodeDetailsCached::new(&green_node.details, ctx),
1811 }
1812 }
1813 fn embed<'db>(&self, ctx: &mut DefCacheLoadingContext<'db>) -> GreenNode<'db> {
1814 GreenNode { kind: self.kind, details: self.details.embed(ctx) }
1815 }
1816}
1817
1818#[derive(Serialize, Deserialize, Clone, Copy, Eq, Hash, PartialEq, salsa::Update, Debug)]
1819struct GreenIdCached(usize);
1820
1821impl GreenIdCached {
1822 fn new<'db>(id: GreenId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1823 if let Some(cached_id) = ctx.green_ids.get(&id) {
1824 return *cached_id;
1825 }
1826 let cached = GreenNodeCached::new(id.long(ctx.db), ctx);
1827 let cached_id = GreenIdCached(ctx.green_ids_lookup.len());
1828 ctx.green_ids_lookup.push(cached);
1829 ctx.green_ids.insert(id, cached_id);
1830 cached_id
1831 }
1832 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> GreenId<'db> {
1833 if let Some(id) = ctx.green_ids.get(&self) {
1834 return *id;
1835 }
1836 let cached = ctx.green_ids_lookup[self.0].clone();
1837 let id = cached.embed(ctx).intern(ctx.db);
1838 ctx.green_ids.insert(self, id);
1839 id
1840 }
1841}
1842#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1843enum FileCached {
1844 OnDisk(PathBuf),
1845 Virtual(VirtualFileCached),
1846 External(PluginGeneratedFileCached),
1847}
1848
1849impl FileCached {
1850 fn new<'db>(file: &FileLongId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1851 match file {
1852 FileLongId::OnDisk(path) => FileCached::OnDisk(path.clone()),
1853 FileLongId::Virtual(virtual_file) => {
1854 FileCached::Virtual(VirtualFileCached::new(virtual_file, ctx))
1855 }
1856 FileLongId::External(external_file) => {
1857 FileCached::External(PluginGeneratedFileCached::new(
1858 PluginGeneratedFileId::from_intern_id(*external_file),
1859 ctx,
1860 ))
1861 }
1862 }
1863 }
1864 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> FileLongId<'db> {
1865 match self {
1866 FileCached::OnDisk(path) => FileLongId::OnDisk(path),
1867 FileCached::Virtual(virtual_file) => FileLongId::Virtual(virtual_file.embed(ctx)),
1868 FileCached::External(external_file) => {
1869 FileLongId::External(external_file.embed(ctx).as_intern_id())
1870 }
1871 }
1872 }
1873}
1874
1875#[derive(Serialize, Deserialize, Clone, Copy, Eq, Hash, PartialEq, salsa::Update, Debug)]
1876pub struct FileIdCached(usize);
1877impl FileIdCached {
1878 fn new<'db>(id: FileId<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1879 if let Some(cached_id) = ctx.file_ids.get(&id) {
1880 return *cached_id;
1881 }
1882 let cached = FileCached::new(id.long(ctx.db), ctx);
1883 let cached_id = FileIdCached(ctx.file_ids_lookup.len());
1884 ctx.file_ids_lookup.push(cached);
1885 ctx.file_ids.insert(id, cached_id);
1886 cached_id
1887 }
1888 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> FileId<'db> {
1889 if let Some(id) = ctx.file_ids.get(&self) {
1890 return *id;
1891 }
1892 let cached = ctx.file_ids_lookup[self.0].clone();
1893 let id = cached.embed(ctx).intern(ctx.db);
1894 ctx.file_ids.insert(self, id);
1895 id
1896 }
1897 fn get_embedded<'db>(&self, data: &Arc<DefCacheLoadingData<'db>>) -> FileId<'db> {
1898 data.file_ids[self]
1899 }
1900}
1901
1902#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1903struct VirtualFileCached {
1904 parent: Option<SpanInFileCached>,
1905 name: String,
1906 content: String,
1907 code_mappings: Vec<CodeMapping>,
1908 kind: FileKind,
1909 original_item_removed: bool,
1910}
1911
1912impl VirtualFileCached {
1913 fn new<'db>(virtual_file: &VirtualFile<'db>, ctx: &mut DefCacheSavingContext<'db>) -> Self {
1914 Self {
1915 parent: virtual_file.parent.map(|parent| SpanInFileCached::new(&parent, ctx)),
1916 name: virtual_file.name.to_string(ctx.db),
1917 content: virtual_file.content.to_string(ctx.db),
1918 code_mappings: virtual_file.code_mappings.to_vec(),
1919 kind: virtual_file.kind,
1920 original_item_removed: virtual_file.original_item_removed,
1921 }
1922 }
1923 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> VirtualFile<'db> {
1924 VirtualFile {
1925 parent: self.parent.map(|parent| parent.embed(ctx)),
1926 name: SmolStrId::from(ctx.db, self.name),
1927 content: SmolStrId::from(ctx.db, self.content),
1928 code_mappings: self.code_mappings.into(),
1929 kind: self.kind,
1930 original_item_removed: self.original_item_removed,
1931 }
1932 }
1933}
1934
1935#[derive(Serialize, Deserialize, Clone, Copy, Eq, Hash, PartialEq, salsa::Update)]
1936pub struct SyntaxStablePtrIdCached(SyntaxNodeCached);
1937
1938impl SyntaxStablePtrIdCached {
1939 pub fn new<'db>(
1940 stable_ptr: SyntaxStablePtrId<'db>,
1941 ctx: &mut DefCacheSavingContext<'db>,
1942 ) -> Self {
1943 Self(SyntaxNodeCached::new(stable_ptr.0, ctx))
1944 }
1945
1946 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> SyntaxStablePtrId<'db> {
1947 SyntaxStablePtrId(self.0.embed(ctx))
1948 }
1949
1950 pub fn get_embedded<'db>(
1951 &self,
1952 data: &Arc<DefCacheLoadingData<'db>>,
1953 ) -> SyntaxStablePtrId<'db> {
1954 SyntaxStablePtrId(self.0.get_embedded(data))
1955 }
1956}
1957
1958#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
1959struct PluginGeneratedFileCached {
1960 module_id: ModuleIdCached,
1961 stable_ptr: SyntaxStablePtrIdCached,
1962 name: String,
1963}
1964
1965impl PluginGeneratedFileCached {
1966 fn new<'db>(
1967 plugin_generated_file: PluginGeneratedFileId<'db>,
1968 ctx: &mut DefCacheSavingContext<'db>,
1969 ) -> Self {
1970 let long_id = plugin_generated_file.long(ctx.db);
1971 Self {
1972 module_id: ModuleIdCached::new(long_id.module_id, ctx),
1973 stable_ptr: SyntaxStablePtrIdCached::new(long_id.stable_ptr, ctx),
1974 name: long_id.name.clone(),
1975 }
1976 }
1977 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> PluginGeneratedFileId<'db> {
1978 let module_id = self.module_id.embed(ctx);
1979 let stable_ptr = self.stable_ptr.embed(ctx);
1980 let long_id = PluginGeneratedFileLongId { module_id, stable_ptr, name: self.name };
1981 long_id.intern(ctx.db)
1982 }
1983}
1984
1985#[derive(Serialize, Deserialize, Clone)]
1986enum SeverityCached {
1987 Error,
1988 Warning,
1989}
1990
1991#[derive(Serialize, Deserialize, Clone)]
1992struct PluginDiagnosticCached {
1993 stable_ptr: SyntaxStablePtrIdCached,
1994 message: String,
1995 severity: SeverityCached,
1996 inner_span: Option<(TextWidth, TextWidth)>,
1997}
1998
1999impl PluginDiagnosticCached {
2000 fn new<'db>(
2001 diagnostic: &PluginDiagnostic<'db>,
2002 ctx: &mut DefCacheSavingContext<'db>,
2003 ) -> PluginDiagnosticCached {
2004 PluginDiagnosticCached {
2005 stable_ptr: SyntaxStablePtrIdCached::new(diagnostic.stable_ptr, ctx),
2006 message: diagnostic.message.clone(),
2007 severity: match diagnostic.severity {
2008 Severity::Error => SeverityCached::Error,
2009 Severity::Warning => SeverityCached::Warning,
2010 },
2011 inner_span: diagnostic.inner_span,
2012 }
2013 }
2014 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> PluginDiagnostic<'db> {
2015 PluginDiagnostic {
2016 stable_ptr: self.stable_ptr.embed(ctx),
2017 message: self.message,
2018 severity: match self.severity {
2019 SeverityCached::Error => Severity::Error,
2020 SeverityCached::Warning => Severity::Warning,
2021 },
2022 inner_span: self.inner_span,
2023 error_code: None,
2024 }
2025 }
2026}
2027
2028type PluginFileDiagnosticNotesCached = OrderedHashMap<FileIdCached, DiagnosticNoteCached>;
2029
2030#[derive(Serialize, Deserialize, Clone)]
2031struct DiagnosticNoteCached {
2032 text: String,
2033 location: Option<SpanInFileCached>,
2034}
2035
2036impl DiagnosticNoteCached {
2037 fn new<'db>(
2038 note: DiagnosticNote<'db>,
2039 ctx: &mut DefCacheSavingContext<'db>,
2040 ) -> DiagnosticNoteCached {
2041 DiagnosticNoteCached {
2042 text: note.text.clone(),
2043 location: note.location.map(|location| SpanInFileCached::new(&location, ctx)),
2044 }
2045 }
2046 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> DiagnosticNote<'db> {
2047 DiagnosticNote {
2048 text: self.text,
2049 location: self.location.map(|location| location.embed(ctx)),
2050 }
2051 }
2052}
2053
2054#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
2055struct SpanInFileCached {
2056 file_id: FileIdCached,
2057 span: TextSpan,
2058}
2059
2060impl SpanInFileCached {
2061 fn new<'db>(
2062 location: &SpanInFile<'db>,
2063 ctx: &mut DefCacheSavingContext<'db>,
2064 ) -> SpanInFileCached {
2065 SpanInFileCached { file_id: FileIdCached::new(location.file_id, ctx), span: location.span }
2066 }
2067 fn embed<'db>(self, ctx: &mut DefCacheLoadingContext<'db>) -> SpanInFile<'db> {
2068 SpanInFile { file_id: self.file_id.embed(ctx), span: self.span }
2069 }
2070}