1use std::collections::VecDeque;
2use std::sync::Arc;
3
4use cairo_lang_diagnostics::{DiagnosticNote, Maybe, PluginFileDiagnosticNotes, ToMaybe};
5use cairo_lang_filesystem::db::FilesGroup;
6use cairo_lang_filesystem::ids::{CrateId, Directory, FileId, FileKind, FileLongId, VirtualFile};
7use cairo_lang_parser::db::ParserGroup;
8use cairo_lang_syntax::attribute::consts::{
9 ALLOW_ATTR, DEPRECATED_ATTR, FEATURE_ATTR, FMT_SKIP_ATTR, IMPLICIT_PRECEDENCE_ATTR,
10 INLINE_ATTR, INTERNAL_ATTR, MUST_USE_ATTR, PHANTOM_ATTR, STARKNET_INTERFACE_ATTR,
11 UNSTABLE_ATTR,
12};
13use cairo_lang_syntax::node::ast::MaybeModuleBody;
14use cairo_lang_syntax::node::db::SyntaxGroup;
15use cairo_lang_syntax::node::element_list::ElementList;
16use cairo_lang_syntax::node::helpers::QueryAttrs;
17use cairo_lang_syntax::node::ids::SyntaxStablePtrId;
18use cairo_lang_syntax::node::{Terminal, TypedStablePtr, TypedSyntaxNode, ast};
19use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
20use cairo_lang_utils::ordered_hash_set::OrderedHashSet;
21use cairo_lang_utils::{Intern, LookupIntern, Upcast};
22use itertools::{Itertools, chain};
23use salsa::InternKey;
24
25use crate::ids::*;
26use crate::plugin::{
27 DynGeneratedFileAuxData, InlineMacroExprPlugin, MacroPlugin, MacroPluginMetadata,
28 PluginDiagnostic,
29};
30
31#[salsa::query_group(DefsDatabase)]
34pub trait DefsGroup:
35 FilesGroup + SyntaxGroup + Upcast<dyn SyntaxGroup> + ParserGroup + Upcast<dyn FilesGroup>
36{
37 #[salsa::interned]
38 fn intern_constant(&self, id: ConstantLongId) -> ConstantId;
39 #[salsa::interned]
40 fn intern_submodule(&self, id: SubmoduleLongId) -> SubmoduleId;
41 #[salsa::interned]
42 fn intern_use(&self, id: UseLongId) -> UseId;
43 #[salsa::interned]
44 fn intern_global_use(&self, id: GlobalUseLongId) -> GlobalUseId;
45 #[salsa::interned]
46 fn intern_free_function(&self, id: FreeFunctionLongId) -> FreeFunctionId;
47 #[salsa::interned]
48 fn intern_impl_type_def(&self, id: ImplTypeDefLongId) -> ImplTypeDefId;
49 #[salsa::interned]
50 fn intern_impl_constant_def(&self, id: ImplConstantDefLongId) -> ImplConstantDefId;
51 #[salsa::interned]
52 fn intern_impl_impl_def(&self, id: ImplImplDefLongId) -> ImplImplDefId;
53 #[salsa::interned]
54 fn intern_impl_function(&self, id: ImplFunctionLongId) -> ImplFunctionId;
55 #[salsa::interned]
56 fn intern_struct(&self, id: StructLongId) -> StructId;
57 #[salsa::interned]
58 fn intern_enum(&self, id: EnumLongId) -> EnumId;
59 #[salsa::interned]
60 fn intern_module_type_alias(&self, id: ModuleTypeAliasLongId) -> ModuleTypeAliasId;
61 #[salsa::interned]
62 fn intern_impl_alias(&self, id: ImplAliasLongId) -> ImplAliasId;
63 #[salsa::interned]
64 fn intern_member(&self, id: MemberLongId) -> MemberId;
65 #[salsa::interned]
66 fn intern_variant(&self, id: VariantLongId) -> VariantId;
67 #[salsa::interned]
68 fn intern_trait(&self, id: TraitLongId) -> TraitId;
69 #[salsa::interned]
70 fn intern_trait_type(&self, id: TraitTypeLongId) -> TraitTypeId;
71 #[salsa::interned]
72 fn intern_trait_constant(&self, id: TraitConstantLongId) -> TraitConstantId;
73 #[salsa::interned]
74 fn intern_trait_impl(&self, id: TraitImplLongId) -> TraitImplId;
75 #[salsa::interned]
76 fn intern_trait_function(&self, id: TraitFunctionLongId) -> TraitFunctionId;
77 #[salsa::interned]
78 fn intern_impl_def(&self, id: ImplDefLongId) -> ImplDefId;
79 #[salsa::interned]
80 fn intern_extern_type(&self, id: ExternTypeLongId) -> ExternTypeId;
81 #[salsa::interned]
82 fn intern_extern_function(&self, id: ExternFunctionLongId) -> ExternFunctionId;
83 #[salsa::interned]
84 fn intern_param(&self, id: ParamLongId) -> ParamId;
85 #[salsa::interned]
86 fn intern_generic_param(&self, id: GenericParamLongId) -> GenericParamId;
87 #[salsa::interned]
88 fn intern_local_var(&self, id: LocalVarLongId) -> LocalVarId;
89 #[salsa::interned]
90 fn intern_statement_const(&self, id: StatementConstLongId) -> StatementConstId;
91 #[salsa::interned]
92 fn intern_statement_use(&self, id: StatementUseLongId) -> StatementUseId;
93 #[salsa::interned]
94 fn intern_plugin_generated_file(&self, id: PluginGeneratedFileLongId) -> PluginGeneratedFileId;
95
96 #[salsa::input]
99 fn macro_plugins(&self) -> Vec<Arc<dyn MacroPlugin>>;
100 #[salsa::input]
101 fn inline_macro_plugins(&self) -> Arc<OrderedHashMap<String, Arc<dyn InlineMacroExprPlugin>>>;
102
103 fn allowed_attributes(&self) -> Arc<OrderedHashSet<String>>;
106
107 fn allowed_statement_attributes(&self) -> Arc<OrderedHashSet<String>>;
110
111 fn declared_derives(&self) -> Arc<OrderedHashSet<String>>;
114
115 fn declared_phantom_type_attributes(&self) -> Arc<OrderedHashSet<String>>;
118
119 fn is_submodule_inline(&self, submodule_id: SubmoduleId) -> Maybe<bool>;
121
122 fn module_main_file(&self, module_id: ModuleId) -> Maybe<FileId>;
126 fn module_files(&self, module_id: ModuleId) -> Maybe<Arc<[FileId]>>;
128 fn module_file(&self, module_id: ModuleFileId) -> Maybe<FileId>;
130 fn module_dir(&self, module_id: ModuleId) -> Maybe<Directory>;
132
133 fn crate_modules(&self, crate_id: CrateId) -> Arc<[ModuleId]>;
135 fn priv_file_to_module_mapping(&self) -> Arc<OrderedHashMap<FileId, Vec<ModuleId>>>;
136 fn file_modules(&self, file_id: FileId) -> Maybe<Arc<[ModuleId]>>;
137
138 fn priv_module_data(&self, module_id: ModuleId) -> Maybe<ModuleData>;
140 fn priv_module_sub_files(
142 &self,
143 module_id: ModuleId,
144 file_id: FileId,
145 ) -> Maybe<Arc<PrivModuleSubFiles>>;
146 fn module_submodules(
147 &self,
148 module_id: ModuleId,
149 ) -> Maybe<Arc<OrderedHashMap<SubmoduleId, ast::ItemModule>>>;
150 fn module_submodules_ids(&self, module_id: ModuleId) -> Maybe<Arc<[SubmoduleId]>>;
151 fn module_constants(
152 &self,
153 module_id: ModuleId,
154 ) -> Maybe<Arc<OrderedHashMap<ConstantId, ast::ItemConstant>>>;
155 fn module_constants_ids(&self, module_id: ModuleId) -> Maybe<Arc<[ConstantId]>>;
156 fn module_constant_by_id(&self, constant_id: ConstantId) -> Maybe<Option<ast::ItemConstant>>;
157 fn module_free_functions(
158 &self,
159 module_id: ModuleId,
160 ) -> Maybe<Arc<OrderedHashMap<FreeFunctionId, ast::FunctionWithBody>>>;
161 fn module_free_functions_ids(&self, module_id: ModuleId) -> Maybe<Arc<[FreeFunctionId]>>;
162 fn module_free_function_by_id(
163 &self,
164 free_function_id: FreeFunctionId,
165 ) -> Maybe<Option<ast::FunctionWithBody>>;
166 fn module_items(&self, module_id: ModuleId) -> Maybe<Arc<[ModuleItemId]>>;
167 fn module_global_uses(
168 &self,
169 module_id: ModuleId,
170 ) -> Maybe<Arc<OrderedHashMap<GlobalUseId, ast::UsePathStar>>>;
171 fn module_item_name_stable_ptr(
173 &self,
174 module_id: ModuleId,
175 item_id: ModuleItemId,
176 ) -> Maybe<SyntaxStablePtrId>;
177 fn module_uses(
178 &self,
179 module_id: ModuleId,
180 ) -> Maybe<Arc<OrderedHashMap<UseId, ast::UsePathLeaf>>>;
181 fn module_uses_ids(&self, module_id: ModuleId) -> Maybe<Arc<[UseId]>>;
182 fn module_use_by_id(&self, use_id: UseId) -> Maybe<Option<ast::UsePathLeaf>>;
183 fn module_global_use_by_id(
184 &self,
185 global_use_id: GlobalUseId,
186 ) -> Maybe<Option<ast::UsePathStar>>;
187 fn module_structs(
188 &self,
189 module_id: ModuleId,
190 ) -> Maybe<Arc<OrderedHashMap<StructId, ast::ItemStruct>>>;
191 fn module_structs_ids(&self, module_id: ModuleId) -> Maybe<Arc<[StructId]>>;
192 fn module_struct_by_id(&self, struct_id: StructId) -> Maybe<Option<ast::ItemStruct>>;
193 fn module_enums(
194 &self,
195 module_id: ModuleId,
196 ) -> Maybe<Arc<OrderedHashMap<EnumId, ast::ItemEnum>>>;
197 fn module_enums_ids(&self, module_id: ModuleId) -> Maybe<Arc<[EnumId]>>;
198 fn module_enum_by_id(&self, enum_id: EnumId) -> Maybe<Option<ast::ItemEnum>>;
199 fn module_type_aliases(
200 &self,
201 module_id: ModuleId,
202 ) -> Maybe<Arc<OrderedHashMap<ModuleTypeAliasId, ast::ItemTypeAlias>>>;
203 fn module_type_aliases_ids(&self, module_id: ModuleId) -> Maybe<Arc<[ModuleTypeAliasId]>>;
204 fn module_type_alias_by_id(
205 &self,
206 module_type_alias_id: ModuleTypeAliasId,
207 ) -> Maybe<Option<ast::ItemTypeAlias>>;
208 fn module_impl_aliases(
209 &self,
210 module_id: ModuleId,
211 ) -> Maybe<Arc<OrderedHashMap<ImplAliasId, ast::ItemImplAlias>>>;
212 fn module_impl_aliases_ids(&self, module_id: ModuleId) -> Maybe<Arc<[ImplAliasId]>>;
213 fn module_impl_alias_by_id(
214 &self,
215 impl_alias_id: ImplAliasId,
216 ) -> Maybe<Option<ast::ItemImplAlias>>;
217 fn module_traits(
218 &self,
219 module_id: ModuleId,
220 ) -> Maybe<Arc<OrderedHashMap<TraitId, ast::ItemTrait>>>;
221 fn module_traits_ids(&self, module_id: ModuleId) -> Maybe<Arc<[TraitId]>>;
222 fn module_trait_by_id(&self, trait_id: TraitId) -> Maybe<Option<ast::ItemTrait>>;
223 fn module_impls(
224 &self,
225 module_id: ModuleId,
226 ) -> Maybe<Arc<OrderedHashMap<ImplDefId, ast::ItemImpl>>>;
227 fn module_impls_ids(&self, module_id: ModuleId) -> Maybe<Arc<[ImplDefId]>>;
228 fn module_impl_by_id(&self, impl_id: ImplDefId) -> Maybe<Option<ast::ItemImpl>>;
229 fn module_extern_types(
230 &self,
231 module_id: ModuleId,
232 ) -> Maybe<Arc<OrderedHashMap<ExternTypeId, ast::ItemExternType>>>;
233 fn module_extern_types_ids(&self, module_id: ModuleId) -> Maybe<Arc<[ExternTypeId]>>;
234 fn module_extern_type_by_id(
235 &self,
236 extern_type_id: ExternTypeId,
237 ) -> Maybe<Option<ast::ItemExternType>>;
238 fn module_extern_functions(
239 &self,
240 module_id: ModuleId,
241 ) -> Maybe<Arc<OrderedHashMap<ExternFunctionId, ast::ItemExternFunction>>>;
242 fn module_extern_functions_ids(&self, module_id: ModuleId) -> Maybe<Arc<[ExternFunctionId]>>;
243 fn module_extern_function_by_id(
244 &self,
245 extern_function_id: ExternFunctionId,
246 ) -> Maybe<Option<ast::ItemExternFunction>>;
247 fn module_ancestors(&self, module_id: ModuleId) -> OrderedHashSet<ModuleId>;
248 fn module_generated_file_aux_data(
249 &self,
250 module_id: ModuleId,
251 ) -> Maybe<Arc<[Option<DynGeneratedFileAuxData>]>>;
252 fn module_plugin_diagnostics(
253 &self,
254 module_id: ModuleId,
255 ) -> Maybe<Arc<[(ModuleFileId, PluginDiagnostic)]>>;
256 fn module_plugin_diagnostics_notes(
259 &self,
260 module_id: ModuleId,
261 ) -> Maybe<Arc<PluginFileDiagnosticNotes>>;
262}
263
264fn allowed_attributes(db: &dyn DefsGroup) -> Arc<OrderedHashSet<String>> {
265 let base_attrs = [
266 INLINE_ATTR,
267 MUST_USE_ATTR,
268 UNSTABLE_ATTR,
269 DEPRECATED_ATTR,
270 INTERNAL_ATTR,
271 ALLOW_ATTR,
272 FEATURE_ATTR,
273 PHANTOM_ATTR,
274 IMPLICIT_PRECEDENCE_ATTR,
275 FMT_SKIP_ATTR,
276 STARKNET_INTERFACE_ATTR,
278 ];
279 Arc::new(OrderedHashSet::from_iter(chain!(
280 base_attrs.map(|attr| attr.into()),
281 db.macro_plugins().into_iter().flat_map(|plugin| plugin.declared_attributes())
282 )))
283}
284
285fn allowed_statement_attributes(_db: &dyn DefsGroup) -> Arc<OrderedHashSet<String>> {
286 let all_attributes = [FMT_SKIP_ATTR, ALLOW_ATTR, FEATURE_ATTR];
287 Arc::new(OrderedHashSet::from_iter(all_attributes.map(|attr| attr.into())))
288}
289
290fn declared_derives(db: &dyn DefsGroup) -> Arc<OrderedHashSet<String>> {
291 Arc::new(OrderedHashSet::from_iter(
292 db.macro_plugins().into_iter().flat_map(|plugin| plugin.declared_derives()),
293 ))
294}
295
296fn declared_phantom_type_attributes(db: &dyn DefsGroup) -> Arc<OrderedHashSet<String>> {
297 Arc::new(OrderedHashSet::from_iter(chain!(
298 [PHANTOM_ATTR.into()],
299 db.macro_plugins().into_iter().flat_map(|plugin| plugin.phantom_type_attributes())
300 )))
301}
302
303fn is_submodule_inline(db: &dyn DefsGroup, submodule_id: SubmoduleId) -> Maybe<bool> {
304 let parent = submodule_id.parent_module(db);
305 let item_module_ast = &db.priv_module_data(parent)?.submodules[&submodule_id];
306 match item_module_ast.body(db.upcast()) {
307 MaybeModuleBody::Some(_) => Ok(true),
308 MaybeModuleBody::None(_) => Ok(false),
309 }
310}
311
312fn module_main_file(db: &dyn DefsGroup, module_id: ModuleId) -> Maybe<FileId> {
313 Ok(match module_id {
314 ModuleId::CrateRoot(crate_id) => {
315 db.crate_config(crate_id).to_maybe()?.root.file(db.upcast(), "lib.cairo".into())
316 }
317 ModuleId::Submodule(submodule_id) => {
318 let parent = submodule_id.parent_module(db);
319 if db.is_submodule_inline(submodule_id)? {
320 db.module_file(submodule_id.module_file_id(db))?
324 } else {
325 let name = submodule_id.name(db);
326 db.module_dir(parent)?.file(db.upcast(), format!("{name}.cairo").into())
327 }
328 }
329 })
330}
331
332fn module_files(db: &dyn DefsGroup, module_id: ModuleId) -> Maybe<Arc<[FileId]>> {
333 Ok(db.priv_module_data(module_id)?.files.into())
334}
335
336fn module_file(db: &dyn DefsGroup, module_file_id: ModuleFileId) -> Maybe<FileId> {
337 Ok(db.module_files(module_file_id.0)?[module_file_id.1.0])
338}
339
340fn module_dir(db: &dyn DefsGroup, module_id: ModuleId) -> Maybe<Directory> {
341 match module_id {
342 ModuleId::CrateRoot(crate_id) => {
343 db.crate_config(crate_id).to_maybe().map(|config| config.root)
344 }
345 ModuleId::Submodule(submodule_id) => {
346 let parent = submodule_id.parent_module(db);
347 let name = submodule_id.name(db);
348 Ok(db.module_dir(parent)?.subdir(name))
349 }
350 }
351}
352
353fn collect_modules_under(db: &dyn DefsGroup, modules: &mut Vec<ModuleId>, module_id: ModuleId) {
355 modules.push(module_id);
356 if let Ok(submodule_ids) = db.module_submodules_ids(module_id) {
357 for submodule_module_id in submodule_ids.iter().copied() {
358 collect_modules_under(db, modules, ModuleId::Submodule(submodule_module_id));
359 }
360 }
361}
362
363fn crate_modules(db: &dyn DefsGroup, crate_id: CrateId) -> Arc<[ModuleId]> {
365 let mut modules = Vec::new();
366 collect_modules_under(db, &mut modules, ModuleId::CrateRoot(crate_id));
367 modules.into()
368}
369
370fn priv_file_to_module_mapping(db: &dyn DefsGroup) -> Arc<OrderedHashMap<FileId, Vec<ModuleId>>> {
371 let mut mapping = OrderedHashMap::<FileId, Vec<ModuleId>>::default();
372 for crate_id in db.crates() {
373 for module_id in db.crate_modules(crate_id).iter().copied() {
374 if let Ok(files) = db.module_files(module_id) {
375 for file_id in files.iter().copied() {
376 match mapping.get_mut(&file_id) {
377 Some(file_modules) => {
378 file_modules.push(module_id);
379 }
380 None => {
381 mapping.insert(file_id, vec![module_id]);
382 }
383 }
384 }
385 }
386 }
387 }
388 mapping.into()
389}
390fn file_modules(db: &dyn DefsGroup, file_id: FileId) -> Maybe<Arc<[ModuleId]>> {
391 Ok(db.priv_file_to_module_mapping().get(&file_id).to_maybe()?.clone().into())
392}
393
394#[derive(Clone, Debug, PartialEq, Eq)]
395pub struct ModuleData {
396 items: Arc<[ModuleItemId]>,
399
400 constants: Arc<OrderedHashMap<ConstantId, ast::ItemConstant>>,
402 submodules: Arc<OrderedHashMap<SubmoduleId, ast::ItemModule>>,
403 uses: Arc<OrderedHashMap<UseId, ast::UsePathLeaf>>,
404 free_functions: Arc<OrderedHashMap<FreeFunctionId, ast::FunctionWithBody>>,
405 structs: Arc<OrderedHashMap<StructId, ast::ItemStruct>>,
406 enums: Arc<OrderedHashMap<EnumId, ast::ItemEnum>>,
407 type_aliases: Arc<OrderedHashMap<ModuleTypeAliasId, ast::ItemTypeAlias>>,
408 impl_aliases: Arc<OrderedHashMap<ImplAliasId, ast::ItemImplAlias>>,
409 traits: Arc<OrderedHashMap<TraitId, ast::ItemTrait>>,
410 impls: Arc<OrderedHashMap<ImplDefId, ast::ItemImpl>>,
411 extern_types: Arc<OrderedHashMap<ExternTypeId, ast::ItemExternType>>,
412 extern_functions: Arc<OrderedHashMap<ExternFunctionId, ast::ItemExternFunction>>,
413 global_uses: Arc<OrderedHashMap<GlobalUseId, ast::UsePathStar>>,
414
415 files: Vec<FileId>,
416 generated_file_aux_data: Vec<Option<DynGeneratedFileAuxData>>,
418 plugin_diagnostics: Vec<(ModuleFileId, PluginDiagnostic)>,
419 diagnostics_notes: PluginFileDiagnosticNotes,
423}
424
425#[derive(Clone, Debug, Eq, PartialEq)]
427pub struct PrivModuleSubFiles {
428 files: OrderedHashMap<FileId, VirtualFile>,
430 aux_data: Vec<Option<DynGeneratedFileAuxData>>,
432 items: Vec<ast::ModuleItem>,
434 plugin_diagnostics: Vec<PluginDiagnostic>,
436 diagnostics_notes: PluginFileDiagnosticNotes,
440}
441
442fn priv_module_data(db: &dyn DefsGroup, module_id: ModuleId) -> Maybe<ModuleData> {
443 let syntax_db = db.upcast();
444 let module_file = db.module_main_file(module_id)?;
445 let main_file_aux_data = if let ModuleId::Submodule(submodule_id) = module_id {
446 let parent_module_data = db.priv_module_data(submodule_id.parent_module(db))?;
447 let item_module_ast = &parent_module_data.submodules[&submodule_id];
448 if matches!(item_module_ast.body(syntax_db), MaybeModuleBody::Some(_)) {
449 parent_module_data
456 .generated_file_aux_data
457 .into_iter()
458 .nth(submodule_id.file_index(db).0)
459 .unwrap()
460 } else {
461 None
462 }
463 } else {
464 None
465 };
466 let mut file_queue = VecDeque::new();
467 file_queue.push_back(module_file);
468 let mut constants = OrderedHashMap::default();
469 let mut submodules = OrderedHashMap::default();
470 let mut uses = OrderedHashMap::default();
471 let mut free_functions = OrderedHashMap::default();
472 let mut structs = OrderedHashMap::default();
473 let mut enums = OrderedHashMap::default();
474 let mut type_aliases = OrderedHashMap::default();
475 let mut impl_aliases = OrderedHashMap::default();
476 let mut traits = OrderedHashMap::default();
477 let mut impls = OrderedHashMap::default();
478 let mut extern_types = OrderedHashMap::default();
479 let mut extern_functions = OrderedHashMap::default();
480 let mut global_uses = OrderedHashMap::default();
481 let mut aux_data = Vec::new();
482 let mut files = Vec::new();
483 let mut plugin_diagnostics = Vec::new();
484 let mut diagnostics_notes = OrderedHashMap::default();
485
486 let mut items = vec![];
487 aux_data.push(main_file_aux_data);
488 while let Some(file_id) = file_queue.pop_front() {
489 let file_index = FileIndex(files.len());
490 let module_file_id = ModuleFileId(module_id, file_index);
491 files.push(file_id);
492
493 let priv_module_data = db.priv_module_sub_files(module_id, file_id)?;
494 diagnostics_notes.extend(priv_module_data.diagnostics_notes.clone().into_iter());
495 file_queue.extend(priv_module_data.files.keys().copied());
496 for diag in &priv_module_data.plugin_diagnostics {
497 plugin_diagnostics.push((module_file_id, diag.clone()));
498 }
499 aux_data.extend(priv_module_data.aux_data.iter().cloned());
500 for item_ast in &priv_module_data.items {
501 match item_ast.clone() {
502 ast::ModuleItem::Constant(constant) => {
503 let item_id = ConstantLongId(module_file_id, constant.stable_ptr()).intern(db);
504 constants.insert(item_id, constant);
505 items.push(ModuleItemId::Constant(item_id));
506 }
507 ast::ModuleItem::Module(module) => {
508 let item_id = SubmoduleLongId(module_file_id, module.stable_ptr()).intern(db);
509 submodules.insert(item_id, module);
510 items.push(ModuleItemId::Submodule(item_id));
511 }
512 ast::ModuleItem::Use(us) => {
513 for leaf in get_all_path_leaves(db.upcast(), &us) {
514 let id = UseLongId(module_file_id, leaf.stable_ptr()).intern(db);
515 uses.insert(id, leaf);
516 items.push(ModuleItemId::Use(id));
517 }
518 for star in get_all_path_stars(db.upcast(), &us) {
519 let id = GlobalUseLongId(module_file_id, star.stable_ptr()).intern(db);
520 global_uses.insert(id, star);
521 }
522 }
523 ast::ModuleItem::FreeFunction(function) => {
524 let item_id =
525 FreeFunctionLongId(module_file_id, function.stable_ptr()).intern(db);
526 free_functions.insert(item_id, function);
527 items.push(ModuleItemId::FreeFunction(item_id));
528 }
529 ast::ModuleItem::ExternFunction(extern_function) => {
530 let item_id =
531 ExternFunctionLongId(module_file_id, extern_function.stable_ptr())
532 .intern(db);
533 extern_functions.insert(item_id, extern_function);
534 items.push(ModuleItemId::ExternFunction(item_id));
535 }
536 ast::ModuleItem::ExternType(extern_type) => {
537 let item_id =
538 ExternTypeLongId(module_file_id, extern_type.stable_ptr()).intern(db);
539 extern_types.insert(item_id, extern_type);
540 items.push(ModuleItemId::ExternType(item_id));
541 }
542 ast::ModuleItem::Trait(trt) => {
543 let item_id = TraitLongId(module_file_id, trt.stable_ptr()).intern(db);
544 traits.insert(item_id, trt);
545 items.push(ModuleItemId::Trait(item_id));
546 }
547 ast::ModuleItem::Impl(imp) => {
548 let item_id = ImplDefLongId(module_file_id, imp.stable_ptr()).intern(db);
549 impls.insert(item_id, imp);
550 items.push(ModuleItemId::Impl(item_id));
551 }
552 ast::ModuleItem::Struct(structure) => {
553 let item_id = StructLongId(module_file_id, structure.stable_ptr()).intern(db);
554 structs.insert(item_id, structure);
555 items.push(ModuleItemId::Struct(item_id));
556 }
557 ast::ModuleItem::Enum(enm) => {
558 let item_id = EnumLongId(module_file_id, enm.stable_ptr()).intern(db);
559 enums.insert(item_id, enm);
560 items.push(ModuleItemId::Enum(item_id));
561 }
562 ast::ModuleItem::TypeAlias(type_alias) => {
563 let item_id =
564 ModuleTypeAliasLongId(module_file_id, type_alias.stable_ptr()).intern(db);
565 type_aliases.insert(item_id, type_alias);
566 items.push(ModuleItemId::TypeAlias(item_id));
567 }
568 ast::ModuleItem::ImplAlias(impl_alias) => {
569 let item_id =
570 ImplAliasLongId(module_file_id, impl_alias.stable_ptr()).intern(db);
571 impl_aliases.insert(item_id, impl_alias);
572 items.push(ModuleItemId::ImplAlias(item_id));
573 }
574 ast::ModuleItem::InlineMacro(inline_macro_ast) => plugin_diagnostics.push((
575 module_file_id,
576 PluginDiagnostic::error(
577 &inline_macro_ast,
578 format!(
579 "Unknown inline item macro: '{}'.",
580 inline_macro_ast.name(db.upcast()).text(db.upcast())
581 ),
582 ),
583 )),
584 ast::ModuleItem::HeaderDoc(_) => {}
585 ast::ModuleItem::Missing(_) => {}
586 }
587 }
588 }
589 let res = ModuleData {
590 items: items.into(),
591 constants: constants.into(),
592 submodules: submodules.into(),
593 uses: uses.into(),
594 free_functions: free_functions.into(),
595 structs: structs.into(),
596 enums: enums.into(),
597 type_aliases: type_aliases.into(),
598 impl_aliases: impl_aliases.into(),
599 traits: traits.into(),
600 impls: impls.into(),
601 extern_types: extern_types.into(),
602 extern_functions: extern_functions.into(),
603 global_uses: global_uses.into(),
604 files,
605 generated_file_aux_data: aux_data,
606 plugin_diagnostics,
607 diagnostics_notes,
608 };
609 Ok(res)
610}
611
612pub fn try_ext_as_virtual_impl(
614 db: &dyn DefsGroup,
615 external_id: salsa::InternId,
616) -> Option<VirtualFile> {
617 let long_id = PluginGeneratedFileId::from_intern_id(external_id).lookup_intern(db);
618 let file_id = FileLongId::External(external_id).intern(db);
619 let data = db
620 .priv_module_sub_files(long_id.module_id, long_id.stable_ptr.file_id(db.upcast()))
621 .unwrap();
622 data.files.get(&file_id).cloned()
623}
624
625fn priv_module_sub_files(
626 db: &dyn DefsGroup,
627 module_id: ModuleId,
628 file_id: FileId,
629) -> Maybe<Arc<PrivModuleSubFiles>> {
630 let syntax_db = db.upcast();
631 let module_main_file = db.module_main_file(module_id)?;
632 let file_syntax = db.file_module_syntax(file_id)?;
633 let item_asts = if module_main_file == file_id {
634 if let ModuleId::Submodule(submodule_id) = module_id {
635 let data = db.priv_module_data(submodule_id.parent_module(db))?;
636 if let MaybeModuleBody::Some(body) = data.submodules[&submodule_id].body(db.upcast()) {
637 Some(body.items(syntax_db))
638 } else {
639 None
640 }
641 } else {
642 None
643 }
644 } else {
645 None
646 }
647 .unwrap_or_else(|| file_syntax.items(syntax_db));
648
649 let allowed_attributes = db.allowed_attributes();
650 let allowed_features = Default::default();
652
653 let crate_id = module_id.owning_crate(db);
654 let cfg_set = db
655 .crate_config(crate_id)
656 .and_then(|cfg| cfg.settings.cfg_set.map(Arc::new))
657 .unwrap_or(db.cfg_set());
658 let edition = db
659 .crate_config(module_id.owning_crate(db))
660 .map(|cfg| cfg.settings.edition)
661 .unwrap_or_default();
662 let metadata = MacroPluginMetadata {
663 cfg_set: &cfg_set,
664 declared_derives: &db.declared_derives(),
665 allowed_features: &allowed_features,
666 edition,
667 };
668
669 let mut files = OrderedHashMap::<_, _>::default();
670 let mut aux_data = Vec::new();
671 let mut items = Vec::new();
672 let mut plugin_diagnostics = Vec::new();
673 let mut diagnostics_notes = OrderedHashMap::default();
674 for item_ast in item_asts.elements(syntax_db) {
675 let mut remove_original_item = false;
676 for plugin in db.macro_plugins() {
680 let result = plugin.generate_code(db.upcast(), item_ast.clone(), &metadata);
681 plugin_diagnostics.extend(result.diagnostics);
682 if result.remove_original_item {
683 remove_original_item = true;
684 }
685
686 if let Some(generated) = result.code {
687 let generated_file_id = FileLongId::External(
688 PluginGeneratedFileLongId {
689 module_id,
690 stable_ptr: item_ast.stable_ptr().untyped(),
691 name: generated.name.clone(),
692 }
693 .intern(db)
694 .as_intern_id(),
695 )
696 .intern(db);
697 if let Some(text) = generated.diagnostics_note {
698 diagnostics_notes
699 .insert(generated_file_id, DiagnosticNote { text, location: None });
700 }
701 files.insert(generated_file_id, VirtualFile {
702 parent: Some(file_id),
703 name: generated.name,
704 content: generated.content.into(),
705 code_mappings: generated.code_mappings.into(),
706 kind: FileKind::Module,
707 });
708 aux_data.push(generated.aux_data);
709 }
710 if remove_original_item {
711 break;
712 }
713 }
714 if remove_original_item {
715 continue;
717 }
718 validate_attributes(syntax_db, &allowed_attributes, &item_ast, &mut plugin_diagnostics);
719 items.push(item_ast);
720 }
721 let res = PrivModuleSubFiles { files, aux_data, items, plugin_diagnostics, diagnostics_notes };
722 Ok(res.into())
723}
724
725pub fn validate_attributes_flat(
727 db: &dyn SyntaxGroup,
728 allowed_attributes: &OrderedHashSet<String>,
729 item: &impl QueryAttrs,
730 plugin_diagnostics: &mut Vec<PluginDiagnostic>,
731) {
732 for attr in item.attributes_elements(db) {
733 if !allowed_attributes.contains(&attr.attr(db).as_syntax_node().get_text_without_trivia(db))
734 {
735 plugin_diagnostics
736 .push(PluginDiagnostic::error(&attr, "Unsupported attribute.".to_string()));
737 }
738 }
739}
740
741fn validate_attributes_element_list<Item: QueryAttrs + TypedSyntaxNode, const STEP: usize>(
744 db: &dyn SyntaxGroup,
745 allowed_attributes: &OrderedHashSet<String>,
746 items: &ElementList<Item, STEP>,
747 plugin_diagnostics: &mut Vec<PluginDiagnostic>,
748) {
749 for item in items.elements(db) {
750 validate_attributes_flat(db, allowed_attributes, &item, plugin_diagnostics);
751 }
752}
753
754fn validate_attributes(
757 db: &dyn SyntaxGroup,
758 allowed_attributes: &OrderedHashSet<String>,
759 item_ast: &ast::ModuleItem,
760 plugin_diagnostics: &mut Vec<PluginDiagnostic>,
761) {
762 validate_attributes_flat(db, allowed_attributes, item_ast, plugin_diagnostics);
763 match item_ast {
764 ast::ModuleItem::Trait(item) => {
765 if let ast::MaybeTraitBody::Some(body) = item.body(db) {
766 validate_attributes_element_list(
767 db,
768 allowed_attributes,
769 &body.items(db),
770 plugin_diagnostics,
771 );
772 }
773 }
774 ast::ModuleItem::Impl(item) => {
775 if let ast::MaybeImplBody::Some(body) = item.body(db) {
776 validate_attributes_element_list(
777 db,
778 allowed_attributes,
779 &body.items(db),
780 plugin_diagnostics,
781 );
782 }
783 }
784 ast::ModuleItem::Struct(item) => {
785 validate_attributes_element_list(
786 db,
787 allowed_attributes,
788 &item.members(db),
789 plugin_diagnostics,
790 );
791 }
792 ast::ModuleItem::Enum(item) => {
793 validate_attributes_element_list(
794 db,
795 allowed_attributes,
796 &item.variants(db),
797 plugin_diagnostics,
798 );
799 }
800 _ => {}
801 }
802}
803
804pub fn get_all_path_leaves(db: &dyn SyntaxGroup, use_item: &ast::ItemUse) -> Vec<ast::UsePathLeaf> {
806 let mut res = vec![];
807 let mut stack = vec![use_item.use_path(db)];
808 while let Some(use_path) = stack.pop() {
809 match use_path {
810 ast::UsePath::Leaf(use_path) => res.push(use_path),
811 ast::UsePath::Single(use_path) => stack.push(use_path.use_path(db)),
812 ast::UsePath::Multi(use_path) => {
813 stack.extend(use_path.use_paths(db).elements(db).into_iter().rev())
814 }
815 ast::UsePath::Star(_) => {}
816 }
817 }
818 res
819}
820
821pub fn get_all_path_stars(db: &dyn SyntaxGroup, use_item: &ast::ItemUse) -> Vec<ast::UsePathStar> {
823 let mut res = vec![];
824 let mut stack = vec![use_item.use_path(db)];
825 while let Some(use_path) = stack.pop() {
826 match use_path {
827 ast::UsePath::Leaf(_) => {}
828 ast::UsePath::Single(use_path) => stack.push(use_path.use_path(db)),
829 ast::UsePath::Multi(use_path) => {
830 stack.extend(use_path.use_paths(db).elements(db).into_iter().rev())
831 }
832 ast::UsePath::Star(use_path) => res.push(use_path),
833 }
834 }
835 res
836}
837
838pub fn module_constants(
840 db: &dyn DefsGroup,
841 module_id: ModuleId,
842) -> Maybe<Arc<OrderedHashMap<ConstantId, ast::ItemConstant>>> {
843 Ok(db.priv_module_data(module_id)?.constants)
844}
845pub fn module_constants_ids(db: &dyn DefsGroup, module_id: ModuleId) -> Maybe<Arc<[ConstantId]>> {
846 Ok(db.module_constants(module_id)?.keys().copied().collect_vec().into())
847}
848pub fn module_constant_by_id(
849 db: &dyn DefsGroup,
850 constant_id: ConstantId,
851) -> Maybe<Option<ast::ItemConstant>> {
852 let module_constants = db.module_constants(constant_id.module_file_id(db.upcast()).0)?;
853 Ok(module_constants.get(&constant_id).cloned())
854}
855
856fn module_submodules(
859 db: &dyn DefsGroup,
860 module_id: ModuleId,
861) -> Maybe<Arc<OrderedHashMap<SubmoduleId, ast::ItemModule>>> {
862 Ok(db.priv_module_data(module_id)?.submodules)
863}
864fn module_submodules_ids(db: &dyn DefsGroup, module_id: ModuleId) -> Maybe<Arc<[SubmoduleId]>> {
865 Ok(db.module_submodules(module_id)?.keys().copied().collect_vec().into())
866}
867pub fn module_submodule_by_id(
868 db: &dyn DefsGroup,
869 submodule_id: SubmoduleId,
870) -> Maybe<Option<ast::ItemModule>> {
871 let module_submodules = db.module_submodules(submodule_id.module_file_id(db.upcast()).0)?;
872 Ok(module_submodules.get(&submodule_id).cloned())
873}
874
875pub fn module_free_functions(
877 db: &dyn DefsGroup,
878 module_id: ModuleId,
879) -> Maybe<Arc<OrderedHashMap<FreeFunctionId, ast::FunctionWithBody>>> {
880 Ok(db.priv_module_data(module_id)?.free_functions)
881}
882pub fn module_free_functions_ids(
883 db: &dyn DefsGroup,
884 module_id: ModuleId,
885) -> Maybe<Arc<[FreeFunctionId]>> {
886 Ok(db.module_free_functions(module_id)?.keys().copied().collect_vec().into())
887}
888pub fn module_free_function_by_id(
889 db: &dyn DefsGroup,
890 free_function_id: FreeFunctionId,
891) -> Maybe<Option<ast::FunctionWithBody>> {
892 let module_free_functions =
893 db.module_free_functions(free_function_id.module_file_id(db.upcast()).0)?;
894 Ok(module_free_functions.get(&free_function_id).cloned())
895}
896
897pub fn module_uses(
899 db: &dyn DefsGroup,
900 module_id: ModuleId,
901) -> Maybe<Arc<OrderedHashMap<UseId, ast::UsePathLeaf>>> {
902 Ok(db.priv_module_data(module_id)?.uses)
903}
904pub fn module_uses_ids(db: &dyn DefsGroup, module_id: ModuleId) -> Maybe<Arc<[UseId]>> {
905 Ok(db.module_uses(module_id)?.keys().copied().collect_vec().into())
906}
907pub fn module_use_by_id(db: &dyn DefsGroup, use_id: UseId) -> Maybe<Option<ast::UsePathLeaf>> {
908 let module_uses = db.module_uses(use_id.module_file_id(db.upcast()).0)?;
909 Ok(module_uses.get(&use_id).cloned())
910}
911
912pub fn module_global_use_by_id(
914 db: &dyn DefsGroup,
915 global_use_id: GlobalUseId,
916) -> Maybe<Option<ast::UsePathStar>> {
917 let module_global_uses = db.module_global_uses(global_use_id.module_file_id(db.upcast()).0)?;
918 Ok(module_global_uses.get(&global_use_id).cloned())
919}
920
921pub fn module_structs(
923 db: &dyn DefsGroup,
924 module_id: ModuleId,
925) -> Maybe<Arc<OrderedHashMap<StructId, ast::ItemStruct>>> {
926 Ok(db.priv_module_data(module_id)?.structs)
927}
928pub fn module_structs_ids(db: &dyn DefsGroup, module_id: ModuleId) -> Maybe<Arc<[StructId]>> {
929 Ok(db.module_structs(module_id)?.keys().copied().collect_vec().into())
930}
931pub fn module_struct_by_id(
932 db: &dyn DefsGroup,
933 struct_id: StructId,
934) -> Maybe<Option<ast::ItemStruct>> {
935 let module_structs = db.module_structs(struct_id.module_file_id(db.upcast()).0)?;
936 Ok(module_structs.get(&struct_id).cloned())
937}
938
939pub fn module_enums(
941 db: &dyn DefsGroup,
942 module_id: ModuleId,
943) -> Maybe<Arc<OrderedHashMap<EnumId, ast::ItemEnum>>> {
944 Ok(db.priv_module_data(module_id)?.enums)
945}
946pub fn module_enums_ids(db: &dyn DefsGroup, module_id: ModuleId) -> Maybe<Arc<[EnumId]>> {
947 Ok(db.module_enums(module_id)?.keys().copied().collect_vec().into())
948}
949pub fn module_enum_by_id(db: &dyn DefsGroup, enum_id: EnumId) -> Maybe<Option<ast::ItemEnum>> {
950 let module_enums = db.module_enums(enum_id.module_file_id(db.upcast()).0)?;
951 Ok(module_enums.get(&enum_id).cloned())
952}
953
954pub fn module_type_aliases(
956 db: &dyn DefsGroup,
957 module_id: ModuleId,
958) -> Maybe<Arc<OrderedHashMap<ModuleTypeAliasId, ast::ItemTypeAlias>>> {
959 Ok(db.priv_module_data(module_id)?.type_aliases)
960}
961pub fn module_type_aliases_ids(
962 db: &dyn DefsGroup,
963 module_id: ModuleId,
964) -> Maybe<Arc<[ModuleTypeAliasId]>> {
965 Ok(db.module_type_aliases(module_id)?.keys().copied().collect_vec().into())
966}
967pub fn module_type_alias_by_id(
968 db: &dyn DefsGroup,
969 module_type_alias_id: ModuleTypeAliasId,
970) -> Maybe<Option<ast::ItemTypeAlias>> {
971 let module_type_aliases =
972 db.module_type_aliases(module_type_alias_id.module_file_id(db.upcast()).0)?;
973 Ok(module_type_aliases.get(&module_type_alias_id).cloned())
974}
975
976pub fn module_impl_aliases(
978 db: &dyn DefsGroup,
979 module_id: ModuleId,
980) -> Maybe<Arc<OrderedHashMap<ImplAliasId, ast::ItemImplAlias>>> {
981 Ok(db.priv_module_data(module_id)?.impl_aliases)
982}
983pub fn module_impl_aliases_ids(
984 db: &dyn DefsGroup,
985 module_id: ModuleId,
986) -> Maybe<Arc<[ImplAliasId]>> {
987 Ok(db.module_impl_aliases(module_id)?.keys().copied().collect_vec().into())
988}
989pub fn module_impl_alias_by_id(
990 db: &dyn DefsGroup,
991 impl_alias_id: ImplAliasId,
992) -> Maybe<Option<ast::ItemImplAlias>> {
993 let module_impl_aliases =
994 db.module_impl_aliases(impl_alias_id.module_file_id(db.upcast()).0)?;
995 Ok(module_impl_aliases.get(&impl_alias_id).cloned())
996}
997
998pub fn module_traits(
1000 db: &dyn DefsGroup,
1001 module_id: ModuleId,
1002) -> Maybe<Arc<OrderedHashMap<TraitId, ast::ItemTrait>>> {
1003 Ok(db.priv_module_data(module_id)?.traits)
1004}
1005pub fn module_traits_ids(db: &dyn DefsGroup, module_id: ModuleId) -> Maybe<Arc<[TraitId]>> {
1006 Ok(db.module_traits(module_id)?.keys().copied().collect_vec().into())
1007}
1008pub fn module_trait_by_id(db: &dyn DefsGroup, trait_id: TraitId) -> Maybe<Option<ast::ItemTrait>> {
1009 let module_traits = db.module_traits(trait_id.module_file_id(db.upcast()).0)?;
1010 Ok(module_traits.get(&trait_id).cloned())
1011}
1012
1013pub fn module_impls(
1015 db: &dyn DefsGroup,
1016 module_id: ModuleId,
1017) -> Maybe<Arc<OrderedHashMap<ImplDefId, ast::ItemImpl>>> {
1018 Ok(db.priv_module_data(module_id)?.impls)
1019}
1020pub fn module_impls_ids(db: &dyn DefsGroup, module_id: ModuleId) -> Maybe<Arc<[ImplDefId]>> {
1021 Ok(db.module_impls(module_id)?.keys().copied().collect_vec().into())
1022}
1023pub fn module_impl_by_id(
1024 db: &dyn DefsGroup,
1025 impl_def_id: ImplDefId,
1026) -> Maybe<Option<ast::ItemImpl>> {
1027 let module_impls = db.module_impls(impl_def_id.module_file_id(db.upcast()).0)?;
1028 Ok(module_impls.get(&impl_def_id).cloned())
1029}
1030
1031pub fn module_extern_types(
1033 db: &dyn DefsGroup,
1034 module_id: ModuleId,
1035) -> Maybe<Arc<OrderedHashMap<ExternTypeId, ast::ItemExternType>>> {
1036 Ok(db.priv_module_data(module_id)?.extern_types)
1037}
1038pub fn module_extern_types_ids(
1039 db: &dyn DefsGroup,
1040 module_id: ModuleId,
1041) -> Maybe<Arc<[ExternTypeId]>> {
1042 Ok(db.module_extern_types(module_id)?.keys().copied().collect_vec().into())
1043}
1044pub fn module_extern_type_by_id(
1045 db: &dyn DefsGroup,
1046 extern_type_id: ExternTypeId,
1047) -> Maybe<Option<ast::ItemExternType>> {
1048 let module_extern_types =
1049 db.module_extern_types(extern_type_id.module_file_id(db.upcast()).0)?;
1050 Ok(module_extern_types.get(&extern_type_id).cloned())
1051}
1052
1053pub fn module_extern_functions(
1055 db: &dyn DefsGroup,
1056 module_id: ModuleId,
1057) -> Maybe<Arc<OrderedHashMap<ExternFunctionId, ast::ItemExternFunction>>> {
1058 Ok(db.priv_module_data(module_id)?.extern_functions)
1059}
1060pub fn module_extern_functions_ids(
1061 db: &dyn DefsGroup,
1062 module_id: ModuleId,
1063) -> Maybe<Arc<[ExternFunctionId]>> {
1064 Ok(db.module_extern_functions(module_id)?.keys().copied().collect_vec().into())
1065}
1066pub fn module_extern_function_by_id(
1067 db: &dyn DefsGroup,
1068 extern_function_id: ExternFunctionId,
1069) -> Maybe<Option<ast::ItemExternFunction>> {
1070 let module_extern_functions =
1071 db.module_extern_functions(extern_function_id.module_file_id(db.upcast()).0)?;
1072 Ok(module_extern_functions.get(&extern_function_id).cloned())
1073}
1074
1075pub fn module_ancestors(db: &dyn DefsGroup, module_id: ModuleId) -> OrderedHashSet<ModuleId> {
1076 let mut current = module_id;
1077 let mut ancestors = OrderedHashSet::default();
1078 while let ModuleId::Submodule(submodule_id) = current {
1079 let parent = submodule_id.parent_module(db);
1080 ancestors.insert(parent);
1081 current = parent
1082 }
1083 ancestors
1084}
1085
1086pub fn module_generated_file_aux_data(
1088 db: &dyn DefsGroup,
1089 module_id: ModuleId,
1090) -> Maybe<Arc<[Option<DynGeneratedFileAuxData>]>> {
1091 Ok(db.priv_module_data(module_id)?.generated_file_aux_data.into())
1092}
1093
1094pub fn module_plugin_diagnostics(
1096 db: &dyn DefsGroup,
1097 module_id: ModuleId,
1098) -> Maybe<Arc<[(ModuleFileId, PluginDiagnostic)]>> {
1099 Ok(db.priv_module_data(module_id)?.plugin_diagnostics.into())
1100}
1101
1102pub fn module_plugin_diagnostics_notes(
1105 db: &dyn DefsGroup,
1106 module_id: ModuleId,
1107) -> Maybe<Arc<PluginFileDiagnosticNotes>> {
1108 Ok(db.priv_module_data(module_id)?.diagnostics_notes.into())
1109}
1110
1111fn module_items(db: &dyn DefsGroup, module_id: ModuleId) -> Maybe<Arc<[ModuleItemId]>> {
1112 Ok(db.priv_module_data(module_id)?.items)
1113}
1114
1115fn module_global_uses(
1116 db: &dyn DefsGroup,
1117 module_id: ModuleId,
1118) -> Maybe<Arc<OrderedHashMap<GlobalUseId, ast::UsePathStar>>> {
1119 Ok(db.priv_module_data(module_id)?.global_uses)
1120}
1121
1122fn module_item_name_stable_ptr(
1123 db: &dyn DefsGroup,
1124 module_id: ModuleId,
1125 item_id: ModuleItemId,
1126) -> Maybe<SyntaxStablePtrId> {
1127 let data = db.priv_module_data(module_id)?;
1128 let db = db.upcast();
1129 Ok(match &item_id {
1130 ModuleItemId::Constant(id) => data.constants[id].name(db).stable_ptr().untyped(),
1131 ModuleItemId::Submodule(id) => data.submodules[id].name(db).stable_ptr().untyped(),
1132 ModuleItemId::Use(id) => data.uses[id].name_stable_ptr(db),
1133 ModuleItemId::FreeFunction(id) => {
1134 data.free_functions[id].declaration(db).name(db).stable_ptr().untyped()
1135 }
1136 ModuleItemId::Struct(id) => data.structs[id].name(db).stable_ptr().untyped(),
1137 ModuleItemId::Enum(id) => data.enums[id].name(db).stable_ptr().untyped(),
1138 ModuleItemId::TypeAlias(id) => data.type_aliases[id].name(db).stable_ptr().untyped(),
1139 ModuleItemId::ImplAlias(id) => data.impl_aliases[id].name(db).stable_ptr().untyped(),
1140 ModuleItemId::Trait(id) => data.traits[id].name(db).stable_ptr().untyped(),
1141 ModuleItemId::Impl(id) => data.impls[id].name(db).stable_ptr().untyped(),
1142 ModuleItemId::ExternType(id) => data.extern_types[id].name(db).stable_ptr().untyped(),
1143 ModuleItemId::ExternFunction(id) => {
1144 data.extern_functions[id].declaration(db).name(db).stable_ptr().untyped()
1145 }
1146 })
1147}