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