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