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