1use std::hash::{Hash, Hasher};
25use std::sync::Arc;
26
27use cairo_lang_debug::debug::DebugWithDb;
28use cairo_lang_diagnostics::Maybe;
29pub use cairo_lang_filesystem::ids::UnstableSalsaId;
30use cairo_lang_filesystem::ids::{CrateId, FileId, SmolStrId};
31use cairo_lang_proc_macros::HeapSize;
32use cairo_lang_syntax::node::ast::TerminalIdentifierGreen;
33use cairo_lang_syntax::node::helpers::{GetIdentifier, HasName, NameGreen};
34use cairo_lang_syntax::node::ids::SyntaxStablePtrId;
35use cairo_lang_syntax::node::kind::SyntaxKind;
36use cairo_lang_syntax::node::{Terminal, TypedStablePtr, TypedSyntaxNode, ast};
37use cairo_lang_utils::{Intern, OptionFrom, define_short_id, require};
38use salsa::Database;
39
40use crate::db::ModuleData;
41use crate::diagnostic_utils::StableLocation;
42use crate::plugin::{InlineMacroExprPlugin, MacroPlugin};
43
44pub trait LanguageElementId<'db> {
46 fn parent_module(&self, db: &'db dyn Database) -> ModuleId<'db>;
47 fn untyped_stable_ptr(&self, db: &'db dyn Database) -> SyntaxStablePtrId<'db>;
48
49 fn stable_location(&self, db: &'db dyn Database) -> StableLocation<'db>;
50
51 fn module_data(&self, db: &'db dyn Database) -> Maybe<ModuleData<'db>> {
52 self.parent_module(db).module_data(db)
53 }
54}
55
56pub trait NamedLanguageElementLongId<'db> {
57 fn name(&self, db: &'db dyn Database) -> SmolStrId<'db>;
58 fn name_identifier(&'db self, db: &'db dyn Database) -> ast::TerminalIdentifier<'db>;
59}
60pub trait NamedLanguageElementId<'db>: LanguageElementId<'db> {
61 fn name(&self, db: &'db dyn Database) -> SmolStrId<'db>;
62 fn name_identifier(&'db self, db: &'db dyn Database) -> ast::TerminalIdentifier<'db>;
63}
64pub trait TopLevelLanguageElementId<'db>: NamedLanguageElementId<'db> {
65 fn path_segments(&self, db: &'db dyn Database) -> Vec<SmolStrId<'db>> {
67 let mut segments = self.parent_module(db).path_segments(db);
68 segments.push(self.name(db));
69 segments
70 }
71
72 fn full_path(&self, db: &'db dyn Database) -> String {
73 self.path_segments(db).iter().map(|s| s.long(db).as_str()).collect::<Vec<_>>().join("::")
74 }
75}
76
77macro_rules! define_top_level_language_element_id {
85 ($short_id:ident, $long_id:ident, $ast_ty:ty) => {
86 define_named_language_element_id!($short_id, $long_id, $ast_ty);
87 impl<'db> TopLevelLanguageElementId<'db> for $short_id<'db> {}
88 };
89}
90
91macro_rules! define_named_language_element_id {
98 ($short_id:ident, $long_id:ident, $ast_ty:ty) => {
99 define_language_element_id_basic!($short_id, $long_id, $ast_ty);
100 impl<'db> cairo_lang_debug::DebugWithDb<'db> for $long_id<'db> {
101 type Db = dyn Database;
102
103 fn fmt(
104 &self,
105 f: &mut std::fmt::Formatter<'_>,
106 db: &'db dyn Database,
107 ) -> std::fmt::Result {
108 write!(f, "{}({})", stringify!($short_id), self.clone().intern(db).full_path(db))
109 }
110 }
111 impl<'db> NamedLanguageElementLongId<'db> for $long_id<'db> {
112 fn name(&self, db: &'db dyn Database) -> SmolStrId<'db> {
113 let terminal_green = self.1.name_green(db);
114 terminal_green.identifier(db)
115 }
116 fn name_identifier(&'db self, db: &'db dyn Database) -> ast::TerminalIdentifier<'db> {
117 let long = self.1.lookup(db);
118 long.name(db)
119 }
120 }
121 impl<'db> NamedLanguageElementId<'db> for $short_id<'db> {
122 fn name(&self, db: &'db dyn Database) -> SmolStrId<'db> {
123 self.long(db).name(db)
124 }
125 fn name_identifier(&'db self, db: &'db dyn Database) -> ast::TerminalIdentifier<'db> {
126 let x = self.long(db);
127 x.name_identifier(db)
128 }
129 }
130 };
131}
132
133macro_rules! define_language_element_id_basic {
139 ($short_id:ident, $long_id:ident, $ast_ty:ty) => {
140 #[derive(Clone, PartialEq, Eq, Hash, Debug, salsa::Update, HeapSize)]
141 pub struct $long_id<'db>(
142 pub ModuleId<'db>,
143 pub <$ast_ty as TypedSyntaxNode<'db>>::StablePtr,
144 );
145 define_short_id!($short_id, $long_id<'db>);
146 impl<'db> $short_id<'db> {
147 pub fn stable_ptr(
148 &self,
149 db: &'db dyn Database,
150 ) -> <$ast_ty as TypedSyntaxNode<'db>>::StablePtr {
151 self.long(db).1
152 }
153 }
154 impl<'db> LanguageElementId<'db> for $short_id<'db> {
155 fn parent_module(&self, db: &'db dyn Database) -> ModuleId<'db> {
156 self.long(db).0
157 }
158 fn untyped_stable_ptr(&self, db: &'db dyn Database) -> SyntaxStablePtrId<'db> {
159 let stable_ptr = self.stable_ptr(db);
160 stable_ptr.untyped()
161 }
162 fn stable_location(&self, db: &'db dyn Database) -> StableLocation<'db> {
163 let $long_id(_module_id, stable_ptr) = self.long(db);
164 StableLocation::new(stable_ptr.untyped())
165 }
166 }
167 };
168}
169
170macro_rules! define_language_element_id_as_enum {
172 (
173 #[toplevel]
174 $(#[doc = $doc:expr])*
175 pub enum $enum_name:ident<$lifetime:lifetime> {
176 $($variant:ident ($variant_ty:ty),)*
177 }
178 ) => {
179 toplevel_enum! {
180 pub enum $enum_name<$lifetime> {
181 $($variant($variant_ty),)*
182 }
183 }
184 define_language_element_id_as_enum! {
185 $(#[doc = $doc])*
186 pub enum $enum_name<$lifetime> {
187 $($variant($variant_ty),)*
188 }
189 }
190 };
191 (
192 $(#[doc = $doc:expr])*
193 pub enum $enum_name:ident<$lifetime:lifetime> {
194 $($variant:ident ($variant_ty:ty),)*
195 }
196 ) => {
197 $(#[doc = $doc])*
198 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HeapSize, salsa::Update)]
199 pub enum $enum_name<$lifetime> {
200 $($variant($variant_ty),)*
201 }
202 impl<'db> cairo_lang_debug::DebugWithDb<'db> for $enum_name<'_> {
203 type Db = dyn Database;
204
205 fn fmt(
206 &self,
207 f: &mut std::fmt::Formatter<'_>,
208 db: &'db dyn Database,
209 ) -> std::fmt::Result {
210 match self {
211 $(
212 $enum_name::$variant(id) => id.fmt(f, db),
213 )*
214 }
215 }
216 }
217 impl<'db> LanguageElementId<'db> for $enum_name<'db> {
218 fn parent_module(&self, db: &'db dyn Database) -> ModuleId<'db> {
219 match self {
220 $(
221 $enum_name::$variant(id) => id.parent_module(db),
222 )*
223 }
224 }
225 fn untyped_stable_ptr(&self, db: &'db dyn Database) -> SyntaxStablePtrId<'db> {
226 match self {
227 $(
228 $enum_name::$variant(id) => id.untyped_stable_ptr(db),
229 )*
230 }
231 }
232 fn stable_location(&self, db: &'db dyn Database) -> StableLocation<'db> {
233 match self {
234 $(
235 $enum_name::$variant(id) => id.stable_location(db),
236 )*
237 }
238 }
239
240 }
241
242 $(
244 impl<$lifetime> OptionFrom<$enum_name<$lifetime>> for $variant_ty {
245 fn option_from(other: $enum_name<$lifetime>) -> Option<Self> {
246 #[allow(irrefutable_let_patterns)]
247 if let $enum_name::$variant(id) = other {
248 Some(id)
249 } else {
250 None
251 }
252 }
253 }
254 )*
255 };
256}
257
258macro_rules! toplevel_enum {
259 (
260 pub enum $enum_name:ident<$lifetime:lifetime> {
261 $($variant:ident ($variant_ty:ty),)*
262 }
263 ) => {
264 impl<'db> NamedLanguageElementId<'db> for $enum_name<'db> {
265 fn name(&self, db: &'db dyn Database) -> SmolStrId<'db> {
266 match self {
267 $(
268 $enum_name::$variant(id) => id.name(db),
269 )*
270 }
271 }
272 fn name_identifier(&'db self, db: &'db dyn Database) -> ast::TerminalIdentifier<'db> {
273 match self {
274 $(
275 $enum_name::$variant(id) => id.name_identifier(db),
276 )*
277 }
278 }
279 }
280 impl<'db> TopLevelLanguageElementId<'db> for $enum_name<'db> {
281 fn path_segments(&self, db: &'db dyn Database) -> Vec<SmolStrId<'db>> {
282 match self {
283 $(
284 $enum_name::$variant(id) => id.path_segments(db),
285 )*
286 }
287 }
288 }
289 }
290}
291
292#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, salsa::Update, HeapSize)]
295pub enum ModuleId<'db> {
296 CrateRoot(CrateId<'db>),
297 Submodule(SubmoduleId<'db>),
298 MacroCall {
301 id: MacroCallId<'db>,
303 generated_file_id: FileId<'db>,
305 is_expose: bool,
307 },
308}
309impl<'db> ModuleId<'db> {
310 pub fn path_segments(&self, db: &'db dyn Database) -> Vec<SmolStrId<'db>> {
312 match self {
313 ModuleId::CrateRoot(id) => vec![id.long(db).name()],
314 ModuleId::Submodule(id) => {
315 let mut segments = id.parent_module(db).path_segments(db);
316 segments.push(id.name(db));
317 segments
318 }
319 ModuleId::MacroCall { id, .. } => {
320 let mut segments = id.parent_module(db).path_segments(db);
321 segments.push(self.name(db));
322 segments
323 }
324 }
325 }
326
327 pub fn full_path(&self, db: &'db dyn Database) -> String {
328 self.path_segments(db).iter().map(|s| s.long(db).as_str()).collect::<Vec<_>>().join("::")
329 }
330 pub fn name(&self, db: &'db dyn Database) -> SmolStrId<'db> {
331 match self {
332 ModuleId::CrateRoot(id) => id.long(db).name(),
333 ModuleId::Submodule(id) => id.name(db),
334 ModuleId::MacroCall { id, .. } => {
335 id.stable_ptr(db).lookup(db).as_syntax_node().get_text_without_trivia(db)
336 }
337 }
338 }
339 pub fn owning_crate(&self, db: &'db dyn Database) -> CrateId<'db> {
340 match self {
341 ModuleId::CrateRoot(crate_id) => *crate_id,
342 ModuleId::Submodule(submodule) => {
343 let parent: ModuleId<'db> = submodule.parent_module(db);
344 parent.owning_crate(db)
345 }
346 ModuleId::MacroCall { id, .. } => id.parent_module(db).owning_crate(db),
347 }
348 }
349 pub fn module_data(&self, db: &'db dyn Database) -> Maybe<ModuleData<'db>> {
350 crate::db::module_data(db, *self)
351 }
352}
353impl<'db> DebugWithDb<'db> for ModuleId<'db> {
354 type Db = dyn Database;
355
356 fn fmt(&self, f: &mut std::fmt::Formatter<'_>, db: &'db dyn Database) -> std::fmt::Result {
357 write!(f, "ModuleId({})", self.full_path(db))
358 }
359}
360
361#[derive(Clone, Debug, Hash, PartialEq, Eq, HeapSize)]
363pub struct PluginGeneratedFileLongId<'db> {
364 pub module_id: ModuleId<'db>,
366 pub stable_ptr: SyntaxStablePtrId<'db>,
368 pub name: String,
370}
371define_short_id!(PluginGeneratedFileId, PluginGeneratedFileLongId<'db>);
372
373#[derive(Clone, Debug, HeapSize)]
375pub struct MacroPluginLongId(pub Arc<dyn MacroPlugin>);
376
377impl MacroPlugin for MacroPluginLongId {
378 fn generate_code<'db>(
379 &self,
380 db: &'db dyn Database,
381 item_ast: ast::ModuleItem<'db>,
382 metadata: &crate::plugin::MacroPluginMetadata<'_>,
383 ) -> crate::plugin::PluginResult<'db> {
384 self.0.generate_code(db, item_ast, metadata)
385 }
386
387 fn declared_attributes<'db>(&self, db: &'db dyn Database) -> Vec<SmolStrId<'db>> {
388 self.0.declared_attributes(db)
389 }
390
391 fn declared_derives<'db>(&self, db: &'db dyn Database) -> Vec<SmolStrId<'db>> {
392 self.0.declared_derives(db)
393 }
394
395 fn executable_attributes<'db>(&self, db: &'db dyn Database) -> Vec<SmolStrId<'db>> {
396 self.0.executable_attributes(db)
397 }
398
399 fn phantom_type_attributes<'db>(&self, db: &'db dyn Database) -> Vec<SmolStrId<'db>> {
400 self.0.phantom_type_attributes(db)
401 }
402
403 fn plugin_type_id(&self) -> std::any::TypeId {
404 self.0.plugin_type_id()
407 }
408}
409
410impl PartialEq for MacroPluginLongId {
413 fn eq(&self, other: &Self) -> bool {
414 Arc::ptr_eq(&self.0, &other.0)
415 }
416}
417
418impl Eq for MacroPluginLongId {}
419
420impl Hash for MacroPluginLongId {
421 fn hash<H: Hasher>(&self, state: &mut H) {
422 Arc::as_ptr(&self.0).hash(state)
423 }
424}
425
426define_short_id!(MacroPluginId, MacroPluginLongId);
427
428#[derive(Clone, Debug, HeapSize)]
430pub struct InlineMacroExprPluginLongId(pub Arc<dyn InlineMacroExprPlugin>);
431
432impl InlineMacroExprPlugin for InlineMacroExprPluginLongId {
433 fn generate_code<'db>(
434 &self,
435 db: &'db dyn Database,
436 item_ast: &ast::ExprInlineMacro<'db>,
437 metadata: &crate::plugin::MacroPluginMetadata<'_>,
438 ) -> crate::plugin::InlinePluginResult<'db> {
439 self.0.generate_code(db, item_ast, metadata)
440 }
441
442 fn documentation(&self) -> Option<String> {
443 self.0.documentation()
444 }
445
446 fn plugin_type_id(&self) -> std::any::TypeId {
447 self.0.plugin_type_id()
450 }
451}
452
453impl PartialEq for InlineMacroExprPluginLongId {
456 fn eq(&self, other: &Self) -> bool {
457 Arc::ptr_eq(&self.0, &other.0)
458 }
459}
460
461impl Eq for InlineMacroExprPluginLongId {}
462
463impl Hash for InlineMacroExprPluginLongId {
464 fn hash<H: Hasher>(&self, state: &mut H) {
465 Arc::as_ptr(&self.0).hash(state)
466 }
467}
468
469define_short_id!(InlineMacroExprPluginId, InlineMacroExprPluginLongId);
470
471define_language_element_id_as_enum! {
472 #[toplevel]
473 pub enum ModuleItemId<'db> {
475 Constant(ConstantId<'db>),
476 Submodule(SubmoduleId<'db>),
477 Use(UseId<'db>),
478 FreeFunction(FreeFunctionId<'db>),
479 Struct(StructId<'db>),
480 Enum(EnumId<'db>),
481 TypeAlias(ModuleTypeAliasId<'db>),
482 ImplAlias(ImplAliasId<'db>),
483 Trait(TraitId<'db>),
484 Impl(ImplDefId<'db>),
485 ExternType(ExternTypeId<'db>),
486 ExternFunction(ExternFunctionId<'db>),
487 MacroDeclaration(MacroDeclarationId<'db>),
488 }
489}
490
491#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, salsa::Update)]
494pub enum ImportableId<'db> {
495 Constant(ConstantId<'db>),
496 Submodule(SubmoduleId<'db>),
497 Crate(CrateId<'db>),
498 FreeFunction(FreeFunctionId<'db>),
499 Struct(StructId<'db>),
500 Enum(EnumId<'db>),
501 Variant(VariantId<'db>),
502 TypeAlias(ModuleTypeAliasId<'db>),
503 ImplAlias(ImplAliasId<'db>),
504 Trait(TraitId<'db>),
505 Impl(ImplDefId<'db>),
506 ExternType(ExternTypeId<'db>),
507 ExternFunction(ExternFunctionId<'db>),
508 MacroDeclaration(MacroDeclarationId<'db>),
509}
510
511define_top_level_language_element_id!(SubmoduleId, SubmoduleLongId, ast::ItemModule<'db>);
512impl<'db> UnstableSalsaId for SubmoduleId<'db> {
513 fn get_internal_id(&self) -> salsa::Id {
514 self.0
515 }
516}
517
518define_top_level_language_element_id!(ConstantId, ConstantLongId, ast::ItemConstant<'db>);
519define_language_element_id_basic!(GlobalUseId, GlobalUseLongId, ast::UsePathStar<'db>);
520define_top_level_language_element_id!(UseId, UseLongId, ast::UsePathLeaf<'db>);
521define_top_level_language_element_id!(
522 FreeFunctionId,
523 FreeFunctionLongId,
524 ast::FunctionWithBody<'db>
525);
526
527define_top_level_language_element_id!(
528 MacroDeclarationId,
529 MacroDeclarationLongId,
530 ast::ItemMacroDeclaration<'db>
531);
532
533define_language_element_id_basic!(MacroCallId, MacroCallLongId, ast::ItemInlineMacro<'db>);
534
535impl<'db> UnstableSalsaId for MacroCallId<'db> {
536 fn get_internal_id(&self) -> salsa::Id {
537 self.0
538 }
539}
540
541impl<'db> UnstableSalsaId for FreeFunctionId<'db> {
542 fn get_internal_id(&self) -> salsa::Id {
543 self.0
544 }
545}
546
547define_top_level_language_element_id!(ImplDefId, ImplDefLongId, ast::ItemImpl<'db>);
549impl<'db> UnstableSalsaId for ImplDefId<'db> {
550 fn get_internal_id(&self) -> salsa::Id {
551 self.0
552 }
553}
554
555define_named_language_element_id!(ImplTypeDefId, ImplTypeDefLongId, ast::ItemTypeAlias<'db>);
557impl<'db> ImplTypeDefId<'db> {
558 pub fn impl_def_id(&self, db: &'db dyn Database) -> ImplDefId<'db> {
559 let ImplTypeDefLongId(module_id, ptr) = self.long(db).clone();
560
561 let impl_ptr = ast::ItemImplPtr(ptr.untyped().nth_parent(db, 3));
563 ImplDefLongId(module_id, impl_ptr).intern(db)
564 }
565}
566impl<'db> TopLevelLanguageElementId<'db> for ImplTypeDefId<'db> {
567 fn path_segments(&self, db: &'db dyn Database) -> Vec<SmolStrId<'db>> {
568 let mut segments = self.impl_def_id(db).path_segments(db);
569 segments.push(self.name(db));
570 segments
571 }
572}
573
574define_named_language_element_id!(ImplConstantDefId, ImplConstantDefLongId, ast::ItemConstant<'db>);
576impl<'db> ImplConstantDefId<'db> {
577 pub fn impl_def_id(&self, db: &'db dyn Database) -> ImplDefId<'db> {
578 let ImplConstantDefLongId(module_id, ptr) = self.long(db).clone();
579
580 let impl_ptr = ast::ItemImplPtr(ptr.untyped().nth_parent(db, 3));
582 ImplDefLongId(module_id, impl_ptr).intern(db)
583 }
584}
585impl<'db> TopLevelLanguageElementId<'db> for ImplConstantDefId<'db> {
586 fn path_segments(&self, db: &'db dyn Database) -> Vec<SmolStrId<'db>> {
587 let mut segments = self.impl_def_id(db).path_segments(db);
588 segments.push(self.name(db));
589 segments
590 }
591}
592
593define_named_language_element_id!(ImplImplDefId, ImplImplDefLongId, ast::ItemImplAlias<'db>);
595impl<'db> ImplImplDefId<'db> {
596 pub fn impl_def_id(&self, db: &'db dyn Database) -> ImplDefId<'db> {
597 let ImplImplDefLongId(module_id, ptr) = self.long(db).clone();
598
599 let impl_ptr = ast::ItemImplPtr(ptr.untyped().nth_parent(db, 3));
601 ImplDefLongId(module_id, impl_ptr).intern(db)
602 }
603}
604impl<'db> TopLevelLanguageElementId<'db> for ImplImplDefId<'db> {
605 fn path_segments(&self, db: &'db dyn Database) -> Vec<SmolStrId<'db>> {
606 let mut segments = self.impl_def_id(db).path_segments(db);
607 segments.push(self.name(db));
608 segments
609 }
610}
611
612define_named_language_element_id!(ImplFunctionId, ImplFunctionLongId, ast::FunctionWithBody<'db>);
614impl<'db> ImplFunctionId<'db> {
615 pub fn impl_def_id(&self, db: &'db dyn Database) -> ImplDefId<'db> {
616 let ImplFunctionLongId(module_id, ptr) = self.long(db).clone();
617
618 let impl_ptr = ast::ItemImplPtr(ptr.untyped().nth_parent(db, 3));
620 ImplDefLongId(module_id, impl_ptr).intern(db)
621 }
622}
623impl<'db> UnstableSalsaId for ImplFunctionId<'db> {
624 fn get_internal_id(&self) -> salsa::Id {
625 self.0
626 }
627}
628impl<'db> TopLevelLanguageElementId<'db> for ImplFunctionId<'db> {
629 fn path_segments(&self, db: &'db dyn Database) -> Vec<SmolStrId<'db>> {
630 let mut segments = self.impl_def_id(db).path_segments(db);
631 segments.push(self.name(db));
632 segments
633 }
634}
635
636define_language_element_id_as_enum! {
637 #[toplevel]
638 pub enum FunctionWithBodyId<'db> {
640 Free(FreeFunctionId<'db>),
641 Impl(ImplFunctionId<'db>),
642 Trait(TraitFunctionId<'db>),
643 }
644}
645
646define_top_level_language_element_id!(
647 ExternFunctionId,
648 ExternFunctionLongId,
649 ast::ItemExternFunction<'db>
650);
651define_top_level_language_element_id!(StructId, StructLongId, ast::ItemStruct<'db>);
652define_top_level_language_element_id!(EnumId, EnumLongId, ast::ItemEnum<'db>);
653define_top_level_language_element_id!(
654 ModuleTypeAliasId,
655 ModuleTypeAliasLongId,
656 ast::ItemTypeAlias<'db>
657);
658define_top_level_language_element_id!(ImplAliasId, ImplAliasLongId, ast::ItemImplAlias<'db>);
659impl<'db> UnstableSalsaId for ImplAliasId<'db> {
660 fn get_internal_id(&self) -> salsa::Id {
661 self.0
662 }
663}
664define_top_level_language_element_id!(ExternTypeId, ExternTypeLongId, ast::ItemExternType<'db>);
665
666define_top_level_language_element_id!(TraitId, TraitLongId, ast::ItemTrait<'db>);
668
669define_named_language_element_id!(TraitTypeId, TraitTypeLongId, ast::TraitItemType<'db>);
671impl<'db> TraitTypeId<'db> {
672 pub fn trait_id(&self, db: &'db dyn Database) -> TraitId<'db> {
673 let TraitTypeLongId(module_id, ptr) = self.long(db).clone();
674 let trait_ptr = ast::ItemTraitPtr(ptr.untyped().nth_parent(db, 3));
676 TraitLongId(module_id, trait_ptr).intern(db)
677 }
678}
679impl<'db> TopLevelLanguageElementId<'db> for TraitTypeId<'db> {
680 fn path_segments(&self, db: &'db dyn Database) -> Vec<SmolStrId<'db>> {
681 let mut segments = self.trait_id(db).path_segments(db);
682 segments.push(self.name(db));
683 segments
684 }
685}
686impl<'db> UnstableSalsaId for TraitTypeId<'db> {
687 fn get_internal_id(&self) -> salsa::Id {
688 self.0
689 }
690}
691
692define_named_language_element_id!(
694 TraitConstantId,
695 TraitConstantLongId,
696 ast::TraitItemConstant<'db>
697);
698impl<'db> TraitConstantId<'db> {
699 pub fn trait_id(&self, db: &'db dyn Database) -> TraitId<'db> {
700 let TraitConstantLongId(module_id, ptr) = self.long(db).clone();
701 let trait_ptr = ast::ItemTraitPtr(ptr.untyped().nth_parent(db, 3));
703 TraitLongId(module_id, trait_ptr).intern(db)
704 }
705}
706impl<'db> TopLevelLanguageElementId<'db> for TraitConstantId<'db> {
707 fn path_segments(&self, db: &'db dyn Database) -> Vec<SmolStrId<'db>> {
708 let mut segments = self.trait_id(db).path_segments(db);
709 segments.push(self.name(db));
710 segments
711 }
712}
713
714define_named_language_element_id!(TraitImplId, TraitImplLongId, ast::TraitItemImpl<'db>);
716impl<'db> TraitImplId<'db> {
717 pub fn trait_id(&self, db: &'db dyn Database) -> TraitId<'db> {
718 let TraitImplLongId(module_id, ptr) = self.long(db).clone();
719 let trait_ptr = ast::ItemTraitPtr(ptr.untyped().nth_parent(db, 3));
721 TraitLongId(module_id, trait_ptr).intern(db)
722 }
723}
724impl<'db> TopLevelLanguageElementId<'db> for TraitImplId<'db> {
725 fn path_segments(&self, db: &'db dyn Database) -> Vec<SmolStrId<'db>> {
726 let mut segments = self.trait_id(db).path_segments(db);
727 segments.push(self.name(db));
728 segments
729 }
730}
731impl<'db> UnstableSalsaId for TraitImplId<'db> {
732 fn get_internal_id(&self) -> salsa::Id {
733 self.0
734 }
735}
736
737define_named_language_element_id!(
739 TraitFunctionId,
740 TraitFunctionLongId,
741 ast::TraitItemFunction<'db>
742);
743impl<'db> TraitFunctionId<'db> {
744 pub fn trait_id(&self, db: &'db dyn Database) -> TraitId<'db> {
745 let TraitFunctionLongId(module_id, ptr) = self.long(db).clone();
746 let trait_ptr = ast::ItemTraitPtr(ptr.untyped().nth_parent(db, 3));
748 TraitLongId(module_id, trait_ptr).intern(db)
749 }
750}
751impl<'db> TopLevelLanguageElementId<'db> for TraitFunctionId<'db> {
752 fn path_segments(&self, db: &'db dyn Database) -> Vec<SmolStrId<'db>> {
753 let mut segments = self.trait_id(db).path_segments(db);
754 segments.push(self.name(db));
755 segments
756 }
757}
758
759define_named_language_element_id!(MemberId, MemberLongId, ast::Member<'db>);
761impl<'db> MemberId<'db> {
762 pub fn struct_id(&self, db: &'db dyn Database) -> StructId<'db> {
763 let MemberLongId(module_id, ptr) = self.long(db).clone();
764 let struct_ptr = ast::ItemStructPtr(ptr.untyped().nth_parent(db, 2));
765 StructLongId(module_id, struct_ptr).intern(db)
766 }
767}
768
769impl<'db> TopLevelLanguageElementId<'db> for MemberId<'db> {
770 fn path_segments(&self, db: &'db dyn Database) -> Vec<SmolStrId<'db>> {
771 let mut segments = self.struct_id(db).path_segments(db);
772 segments.push(self.name(db));
773 segments
774 }
775}
776
777define_named_language_element_id!(VariantId, VariantLongId, ast::Variant<'db>);
779impl<'db> VariantId<'db> {
780 pub fn enum_id(&self, db: &'db dyn Database) -> EnumId<'db> {
781 let VariantLongId(module_id, ptr) = self.long(db).clone();
782 let struct_ptr = ast::ItemEnumPtr(ptr.untyped().nth_parent(db, 2));
783 EnumLongId(module_id, struct_ptr).intern(db)
784 }
785}
786
787impl<'db> TopLevelLanguageElementId<'db> for VariantId<'db> {
788 fn path_segments(&self, db: &'db dyn Database) -> Vec<SmolStrId<'db>> {
789 let mut segments = self.enum_id(db).path_segments(db);
790 segments.push(self.name(db));
791 segments
792 }
793}
794
795define_language_element_id_as_enum! {
796 pub enum VarId<'db> {
798 Param(ParamId<'db>),
799 Local(LocalVarId<'db>),
800 Item(StatementItemId<'db>),
801 }
803}
804
805define_top_level_language_element_id!(ParamId, ParamLongId, ast::Param<'db>);
807define_language_element_id_basic!(GenericParamId, GenericParamLongId, ast::GenericParam<'db>);
808impl<'db> GenericParamLongId<'db> {
809 pub fn name(&self, db: &'db dyn Database) -> Option<SmolStrId<'db>> {
810 let node = self.1.0.0;
811 assert!(!node.is_root());
812 let key_fields = node.key_fields(db);
813 let kind = node.kind(db);
814 require(!matches!(
815 kind,
816 SyntaxKind::GenericParamImplAnonymous | SyntaxKind::GenericParamNegativeImpl
817 ))?;
818
819 let name_green = TerminalIdentifierGreen(key_fields[0]);
820 Some(name_green.identifier(db))
821 }
822
823 pub fn debug_name(&self, db: &'db dyn Database) -> SmolStrId<'db> {
824 self.name(db).unwrap_or(SmolStrId::from(db, "_"))
825 }
826 pub fn kind(&self, db: &dyn Database) -> GenericKind {
827 let node = self.1.0.0;
828 assert!(!node.is_root());
829 let kind = node.kind(db);
830 match kind {
831 SyntaxKind::GenericParamType => GenericKind::Type,
832 SyntaxKind::GenericParamConst => GenericKind::Const,
833 SyntaxKind::GenericParamImplNamed | SyntaxKind::GenericParamImplAnonymous => {
834 GenericKind::Impl
835 }
836 SyntaxKind::GenericParamNegativeImpl => GenericKind::NegImpl,
837 _ => unreachable!(),
838 }
839 }
840 pub fn generic_item<'s, 'd: 's>(&'s self, db: &'d dyn Database) -> GenericItemId<'s> {
842 let item_ptr = self.1.0.nth_parent(db, 3);
843 GenericItemId::from_ptr(db, self.0, item_ptr)
844 }
845
846 pub fn has_type_constraints_syntax(&self, db: &dyn Database) -> bool {
848 let param = ast::GenericParamPtr(self.1.0).lookup(db);
849 match param {
850 ast::GenericParam::Type(_) => false,
851 ast::GenericParam::Const(_) => false,
852 ast::GenericParam::ImplNamed(imp) => {
853 matches!(
854 imp.type_constrains(db),
855 ast::OptionAssociatedItemConstraints::AssociatedItemConstraints(_)
856 )
857 }
858 ast::GenericParam::ImplAnonymous(imp) => {
859 matches!(
860 imp.type_constrains(db),
861 ast::OptionAssociatedItemConstraints::AssociatedItemConstraints(_)
862 )
863 }
864 ast::GenericParam::NegativeImpl(_) => false,
865 }
866 }
867}
868impl<'db> GenericParamId<'db> {
869 pub fn name(&self, db: &'db dyn Database) -> Option<SmolStrId<'db>> {
870 self.long(db).name(db)
871 }
872 pub fn debug_name(&self, db: &'db dyn Database) -> SmolStrId<'db> {
873 self.long(db).debug_name(db)
874 }
875 pub fn format(&self, db: &'db dyn Database) -> SmolStrId<'db> {
876 let long_ids = self.long(db);
877 let node = long_ids.1.0.0;
878 assert!(!node.is_root());
879 let key_fields = node.key_fields(db);
880 let kind = node.kind(db);
881
882 if matches!(
883 kind,
884 SyntaxKind::GenericParamImplAnonymous | SyntaxKind::GenericParamNegativeImpl
885 ) {
886 return self.stable_location(db).syntax_node(db).get_text_without_trivia(db);
888 }
889
890 let name_green = TerminalIdentifierGreen(key_fields[0]);
891 name_green.identifier(db)
892 }
893
894 pub fn kind(&self, db: &dyn Database) -> GenericKind {
895 self.long(db).kind(db)
896 }
897 pub fn generic_item(&self, db: &'db dyn Database) -> GenericItemId<'db> {
898 self.long(db).generic_item(db)
899 }
900}
901
902impl<'db> UnstableSalsaId for GenericParamId<'db> {
903 fn get_internal_id(&self) -> salsa::Id {
904 self.0
905 }
906}
907
908impl<'db> DebugWithDb<'db> for GenericParamLongId<'db> {
909 type Db = dyn Database;
910
911 fn fmt(&self, f: &mut std::fmt::Formatter<'_>, db: &'db dyn Database) -> std::fmt::Result {
912 write!(
913 f,
914 "GenericParam{}({}::{})",
915 self.kind(db),
916 self.generic_item(db).full_path(db),
917 self.debug_name(db).long(db)
918 )
919 }
920}
921
922define_language_element_id_as_enum! {
923 #[toplevel]
924 pub enum GenericModuleItemId<'db> {
926 FreeFunc(FreeFunctionId<'db>),
927 ExternFunc(ExternFunctionId<'db>),
928 TraitFunc(TraitFunctionId<'db>),
929 ImplFunc(ImplFunctionId<'db>),
930 Trait(TraitId<'db>),
931 Impl(ImplDefId<'db>),
932 Struct(StructId<'db>),
933 Enum(EnumId<'db>),
934 ExternType(ExternTypeId<'db>),
935 TypeAlias(ModuleTypeAliasId<'db>),
936 ImplAlias(ImplAliasId<'db>),
937 }
938}
939define_language_element_id_as_enum! {
940 #[toplevel]
941 pub enum GenericTraitItemId<'db> {
943 Type(TraitTypeId<'db>),
944 }
945}
946define_language_element_id_as_enum! {
947 #[toplevel]
948 pub enum GenericImplItemId<'db> {
950 Type(ImplTypeDefId<'db>),
951 }
952}
953
954define_language_element_id_as_enum! {
955 #[toplevel]
956 pub enum GenericItemId<'db> {
958 ModuleItem(GenericModuleItemId<'db>),
959 TraitItem(GenericTraitItemId<'db>),
960 ImplItem(GenericImplItemId<'db>),
961 }
962}
963impl<'db> GenericItemId<'db> {
964 pub fn from_ptr(
965 db: &'db dyn Database,
966 module_file: ModuleId<'db>,
967 stable_ptr: SyntaxStablePtrId<'db>,
968 ) -> Self {
969 let node = stable_ptr.0;
970 let parent0 = node.parent(db).expect("GenericItem should have a parent");
971 let kind = node.kind(db);
972 match kind {
973 SyntaxKind::FunctionDeclaration => {
974 let parent1 = parent0.parent(db).expect("FunctionDeclaration parent should exist");
975 let kind = parent0.kind(db);
976 match kind {
977 SyntaxKind::FunctionWithBody => {
978 let parent0_ptr = SyntaxStablePtrId(parent0);
981 match parent1.parent(db).map(|p| p.kind(db)) {
982 Some(SyntaxKind::SyntaxFile) | Some(SyntaxKind::ModuleBody) => {
984 GenericItemId::ModuleItem(GenericModuleItemId::FreeFunc(
985 FreeFunctionLongId(
986 module_file,
987 ast::FunctionWithBodyPtr(parent0_ptr),
988 )
989 .intern(db),
990 ))
991 }
992 Some(SyntaxKind::ImplBody) => {
993 GenericItemId::ModuleItem(GenericModuleItemId::ImplFunc(
994 ImplFunctionLongId(
995 module_file,
996 ast::FunctionWithBodyPtr(parent0_ptr),
997 )
998 .intern(db),
999 ))
1000 }
1001 _ => panic!(
1002 "Got bad syntax kind @ parent of {}. {:?}",
1003 parent1.kind(db),
1004 kind
1005 ),
1006 }
1007 }
1008 SyntaxKind::ItemExternFunction => {
1009 GenericItemId::ModuleItem(GenericModuleItemId::ExternFunc(
1010 ExternFunctionLongId(
1011 module_file,
1012 ast::ItemExternFunctionPtr(SyntaxStablePtrId(parent0)),
1013 )
1014 .intern(db),
1015 ))
1016 }
1017 SyntaxKind::TraitItemFunction => {
1018 GenericItemId::ModuleItem(GenericModuleItemId::TraitFunc(
1019 TraitFunctionLongId(
1020 module_file,
1021 ast::TraitItemFunctionPtr(SyntaxStablePtrId(parent0)),
1022 )
1023 .intern(db),
1024 ))
1025 }
1026 _ => panic!(),
1027 }
1028 }
1029 SyntaxKind::ItemImpl => GenericItemId::ModuleItem(GenericModuleItemId::Impl(
1030 ImplDefLongId(module_file, ast::ItemImplPtr(stable_ptr)).intern(db),
1031 )),
1032 SyntaxKind::ItemTrait => GenericItemId::ModuleItem(GenericModuleItemId::Trait(
1033 TraitLongId(module_file, ast::ItemTraitPtr(stable_ptr)).intern(db),
1034 )),
1035 SyntaxKind::ItemStruct => GenericItemId::ModuleItem(GenericModuleItemId::Struct(
1036 StructLongId(module_file, ast::ItemStructPtr(stable_ptr)).intern(db),
1037 )),
1038 SyntaxKind::ItemEnum => GenericItemId::ModuleItem(GenericModuleItemId::Enum(
1039 EnumLongId(module_file, ast::ItemEnumPtr(stable_ptr)).intern(db),
1040 )),
1041 SyntaxKind::ItemExternType => {
1042 GenericItemId::ModuleItem(GenericModuleItemId::ExternType(
1043 ExternTypeLongId(module_file, ast::ItemExternTypePtr(stable_ptr)).intern(db),
1044 ))
1045 }
1046 SyntaxKind::ItemTypeAlias => {
1047 match parent0.kind(db) {
1050 SyntaxKind::ModuleItemList => {
1051 GenericItemId::ModuleItem(GenericModuleItemId::TypeAlias(
1052 ModuleTypeAliasLongId(module_file, ast::ItemTypeAliasPtr(stable_ptr))
1053 .intern(db),
1054 ))
1055 }
1056 SyntaxKind::ImplItemList => GenericItemId::ImplItem(GenericImplItemId::Type(
1057 ImplTypeDefLongId(module_file, ast::ItemTypeAliasPtr(stable_ptr))
1058 .intern(db),
1059 )),
1060 _ => panic!(),
1061 }
1062 }
1063 SyntaxKind::ItemImplAlias => GenericItemId::ModuleItem(GenericModuleItemId::ImplAlias(
1064 ImplAliasLongId(module_file, ast::ItemImplAliasPtr(stable_ptr)).intern(db),
1065 )),
1066 SyntaxKind::TraitItemType => GenericItemId::TraitItem(GenericTraitItemId::Type(
1067 TraitTypeLongId(module_file, ast::TraitItemTypePtr(stable_ptr)).intern(db),
1068 )),
1069 _ => panic!(),
1070 }
1071 }
1072}
1073
1074#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, salsa::Update)]
1075pub enum GenericKind {
1076 Type,
1077 Const,
1078 Impl,
1079 NegImpl,
1080}
1081impl std::fmt::Display for GenericKind {
1082 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1083 match self {
1084 GenericKind::Type => write!(f, "Type"),
1085 GenericKind::Const => write!(f, "Const"),
1086 GenericKind::Impl => write!(f, "Impl"),
1087 GenericKind::NegImpl => write!(f, "-Impl"),
1088 }
1089 }
1090}
1091
1092define_language_element_id_basic!(LocalVarId, LocalVarLongId, ast::TerminalIdentifier<'db>);
1095impl<'db> DebugWithDb<'db> for LocalVarLongId<'db> {
1096 type Db = dyn Database;
1097
1098 fn fmt(&self, f: &mut std::fmt::Formatter<'_>, db: &'db dyn Database) -> std::fmt::Result {
1099 let LocalVarLongId(module_id, ptr) = self;
1100 let text = ptr.lookup(db).text(db).long(db);
1101 write!(f, "LocalVarId({}::{})", module_id.full_path(db), text)
1102 }
1103}
1104
1105define_top_level_language_element_id!(
1106 StatementConstId,
1107 StatementConstLongId,
1108 ast::ItemConstant<'db>
1109);
1110
1111define_top_level_language_element_id!(StatementUseId, StatementUseLongId, ast::UsePathLeaf<'db>);
1112
1113define_language_element_id_as_enum! {
1114 #[toplevel]
1115 pub enum FunctionTitleId<'db> {
1117 Free(FreeFunctionId<'db>),
1118 Extern(ExternFunctionId<'db>),
1119 Trait(TraitFunctionId<'db>),
1120 Impl(ImplFunctionId<'db>),
1121 }
1122}
1123impl<'db> FunctionTitleId<'db> {
1124 pub fn format(&self, db: &dyn Database) -> String {
1125 let function_name = match *self {
1126 FunctionTitleId::Free(_) | FunctionTitleId::Extern(_) => self.name(db).to_string(db),
1127 FunctionTitleId::Trait(id) => id.full_path(db),
1128 FunctionTitleId::Impl(id) => id.full_path(db),
1129 };
1130 format!("{}::{}", self.parent_module(db).full_path(db), function_name)
1131 }
1132}
1133
1134define_language_element_id_as_enum! {
1135 #[toplevel]
1136 pub enum GenericTypeId<'db> {
1138 Struct(StructId<'db>),
1139 Enum(EnumId<'db>),
1140 Extern(ExternTypeId<'db>),
1141 }
1143}
1144impl<'db> GenericTypeId<'db> {
1145 pub fn format(&self, db: &dyn Database) -> String {
1146 format!("{}::{}", self.parent_module(db).full_path(db), self.name(db).long(db))
1147 }
1148}
1149
1150impl<'db> OptionFrom<ModuleItemId<'db>> for GenericTypeId<'db> {
1152 fn option_from(item: ModuleItemId<'db>) -> Option<Self> {
1153 match item {
1154 ModuleItemId::Struct(id) => Some(GenericTypeId::Struct(id)),
1155 ModuleItemId::Enum(id) => Some(GenericTypeId::Enum(id)),
1156 ModuleItemId::ExternType(id) => Some(GenericTypeId::Extern(id)),
1157 ModuleItemId::Constant(_)
1158 | ModuleItemId::Submodule(_)
1159 | ModuleItemId::TypeAlias(_)
1160 | ModuleItemId::ImplAlias(_)
1161 | ModuleItemId::Use(_)
1162 | ModuleItemId::FreeFunction(_)
1163 | ModuleItemId::Trait(_)
1164 | ModuleItemId::Impl(_)
1165 | ModuleItemId::ExternFunction(_)
1166 | ModuleItemId::MacroDeclaration(_) => None,
1167 }
1168 }
1169}
1170
1171impl<'db> From<GenericItemId<'db>> for LookupItemId<'db> {
1173 fn from(item: GenericItemId<'db>) -> Self {
1174 match item {
1175 GenericItemId::ModuleItem(module_item) => match module_item {
1176 GenericModuleItemId::FreeFunc(id) => {
1177 LookupItemId::ModuleItem(ModuleItemId::FreeFunction(id))
1178 }
1179 GenericModuleItemId::ExternFunc(id) => {
1180 LookupItemId::ModuleItem(ModuleItemId::ExternFunction(id))
1181 }
1182 GenericModuleItemId::TraitFunc(id) => {
1183 LookupItemId::TraitItem(TraitItemId::Function(id))
1184 }
1185 GenericModuleItemId::ImplFunc(id) => {
1186 LookupItemId::ImplItem(ImplItemId::Function(id))
1187 }
1188 GenericModuleItemId::Trait(id) => LookupItemId::ModuleItem(ModuleItemId::Trait(id)),
1189 GenericModuleItemId::Impl(id) => LookupItemId::ModuleItem(ModuleItemId::Impl(id)),
1190 GenericModuleItemId::Struct(id) => {
1191 LookupItemId::ModuleItem(ModuleItemId::Struct(id))
1192 }
1193 GenericModuleItemId::Enum(id) => LookupItemId::ModuleItem(ModuleItemId::Enum(id)),
1194 GenericModuleItemId::ExternType(id) => {
1195 LookupItemId::ModuleItem(ModuleItemId::ExternType(id))
1196 }
1197 GenericModuleItemId::TypeAlias(id) => {
1198 LookupItemId::ModuleItem(ModuleItemId::TypeAlias(id))
1199 }
1200 GenericModuleItemId::ImplAlias(id) => {
1201 LookupItemId::ModuleItem(ModuleItemId::ImplAlias(id))
1202 }
1203 },
1204 GenericItemId::TraitItem(trait_item) => match trait_item {
1205 GenericTraitItemId::Type(id) => LookupItemId::TraitItem(TraitItemId::Type(id)),
1206 },
1207 GenericItemId::ImplItem(impl_item) => match impl_item {
1208 GenericImplItemId::Type(id) => LookupItemId::ImplItem(ImplItemId::Type(id)),
1209 },
1210 }
1211 }
1212}
1213
1214define_language_element_id_as_enum! {
1215 #[toplevel]
1216 pub enum StatementItemId<'db> {
1217 Constant(StatementConstId<'db>),
1218 Use(StatementUseId<'db>),
1219 }
1220}
1221
1222impl<'db> StatementItemId<'db> {
1223 pub fn name(&self, db: &'db dyn Database) -> SmolStrId<'db> {
1224 match self {
1225 StatementItemId::Constant(id) => id.name(db),
1226 StatementItemId::Use(id) => id.name(db),
1227 }
1228 }
1229 pub fn name_stable_ptr(&self, db: &'db dyn Database) -> SyntaxStablePtrId<'db> {
1230 match self {
1231 StatementItemId::Constant(id) => {
1232 let id: &StatementConstId<'db> = id;
1233 let item_id = id.long(db).1.lookup(db);
1234 item_id.name(db).stable_ptr(db).untyped()
1235 }
1236 StatementItemId::Use(id) => {
1237 let item_id = id.long(db).1.lookup(db);
1238 item_id.name_stable_ptr(db)
1239 }
1240 }
1241 }
1242}
1243
1244define_language_element_id_as_enum! {
1245 #[toplevel]
1246 pub enum TraitItemId<'db> {
1248 Function(TraitFunctionId<'db>),
1249 Type(TraitTypeId<'db>),
1250 Constant(TraitConstantId<'db>),
1251 Impl(TraitImplId<'db>),
1252 }
1253}
1254impl<'db> TraitItemId<'db> {
1255 pub fn name(&self, db: &'db dyn Database) -> SmolStrId<'db> {
1256 match self {
1257 TraitItemId::Function(id) => id.name(db),
1258 TraitItemId::Type(id) => id.name(db),
1259 TraitItemId::Constant(id) => id.name(db),
1260 TraitItemId::Impl(id) => id.name(db),
1261 }
1262 }
1263 pub fn trait_id(&self, db: &'db dyn Database) -> TraitId<'db> {
1264 match self {
1265 TraitItemId::Function(id) => id.trait_id(db),
1266 TraitItemId::Type(id) => id.trait_id(db),
1267 TraitItemId::Constant(id) => id.trait_id(db),
1268 TraitItemId::Impl(id) => id.trait_id(db),
1269 }
1270 }
1271}
1272
1273define_language_element_id_as_enum! {
1274 #[toplevel]
1275 pub enum ImplItemId<'db> {
1277 Function(ImplFunctionId<'db>),
1278 Type(ImplTypeDefId<'db>),
1279 Constant(ImplConstantDefId<'db>),
1280 Impl(ImplImplDefId<'db>),
1281 }
1282}
1283impl<'db> ImplItemId<'db> {
1284 pub fn name(&self, db: &'db dyn Database) -> SmolStrId<'db> {
1285 match self {
1286 ImplItemId::Function(id) => id.name(db),
1287 ImplItemId::Type(id) => id.name(db),
1288 ImplItemId::Constant(id) => id.name(db),
1289 ImplItemId::Impl(id) => id.name(db),
1290 }
1291 }
1292 pub fn impl_def_id(&self, db: &'db dyn Database) -> ImplDefId<'db> {
1293 match self {
1294 ImplItemId::Function(id) => id.impl_def_id(db),
1295 ImplItemId::Type(id) => id.impl_def_id(db),
1296 ImplItemId::Constant(id) => id.impl_def_id(db),
1297 ImplItemId::Impl(id) => id.impl_def_id(db),
1298 }
1299 }
1300}
1301
1302define_language_element_id_as_enum! {
1303 #[toplevel]
1304 pub enum LookupItemId<'db> {
1308 ModuleItem(ModuleItemId<'db>),
1309 TraitItem(TraitItemId<'db>),
1310 ImplItem(ImplItemId<'db>),
1311 }
1312}