1use std::sync::Arc;
2
3use cairo_lang_debug::DebugWithDb;
4use cairo_lang_defs::db::DefsGroup;
5use cairo_lang_defs::ids::{
6 FunctionTitleId, GenericParamId, GenericParamLongId, LanguageElementId, LookupItemId,
7 ModuleItemId, NamedLanguageElementId, NamedLanguageElementLongId, TopLevelLanguageElementId,
8 TraitConstantId, TraitConstantLongId, TraitFunctionId, TraitFunctionLongId, TraitId,
9 TraitImplId, TraitImplLongId, TraitItemId, TraitTypeId, TraitTypeLongId, UseId,
10};
11use cairo_lang_diagnostics::{Diagnostics, DiagnosticsBuilder, Maybe, MaybeAsRef};
12use cairo_lang_filesystem::ids::SmolStrId;
13use cairo_lang_proc_macros::{DebugWithDb, HeapSize, SemanticObject};
14use cairo_lang_syntax as syntax;
15use cairo_lang_syntax::attribute::structured::{Attribute, AttributeListStructurize};
16use cairo_lang_syntax::node::helpers::OptionWrappedGenericParamListHelper;
17use cairo_lang_syntax::node::{Terminal, TypedStablePtr, TypedSyntaxNode, ast};
18use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
19use cairo_lang_utils::ordered_hash_set::OrderedHashSet;
20use cairo_lang_utils::unordered_hash_map::UnorderedHashMap;
21use cairo_lang_utils::{Intern, define_short_id};
22use salsa::Database;
23
24use super::TraitOrImplContext;
25use super::feature_kind::FeatureKind;
26use super::function_with_body::{FunctionBodyData, get_implicit_precedence, get_inline_config};
27use super::functions::{
28 FunctionDeclarationData, GenericFunctionId, ImplGenericFunctionId, ImplicitPrecedence,
29 InlineConfiguration,
30};
31use super::generics::{
32 GenericParamsData, displayable_concrete, generic_params_to_args, semantic_generic_params,
33 semantic_generic_params_ex,
34};
35use super::imp::{GenericsHeadFilter, ImplLongId, TraitFilter};
36use crate::db::get_resolver_data_options;
37use crate::diagnostic::SemanticDiagnosticKind::{self, *};
38use crate::diagnostic::{NotFoundItemType, SemanticDiagnostics, SemanticDiagnosticsBuilder};
39use crate::expr::compute::{ComputationContext, ContextFunction, Environment, compute_root_expr};
40use crate::expr::inference::InferenceId;
41use crate::expr::inference::canonic::ResultNoErrEx;
42use crate::items::feature_kind::HasFeatureKind;
43use crate::resolve::{ResolvedConcreteItem, Resolver, ResolverData};
44use crate::substitution::{GenericSubstitution, SemanticRewriter};
45use crate::types::resolve_type;
46use crate::{
47 FunctionBody, FunctionLongId, GenericArgumentId, GenericParam, Mutability, SemanticDiagnostic,
48 TypeId, semantic, semantic_object_for_id,
49};
50
51#[cfg(test)]
52#[path = "trt_test.rs"]
53mod test;
54
55#[derive(Clone, Debug, Hash, PartialEq, Eq, SemanticObject, salsa::Update, HeapSize)]
56pub struct ConcreteTraitLongId<'db> {
57 pub trait_id: TraitId<'db>,
58 pub generic_args: Vec<GenericArgumentId<'db>>,
59}
60impl<'db> DebugWithDb<'db> for ConcreteTraitLongId<'db> {
61 type Db = dyn Database;
62
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>, db: &'db dyn Database) -> std::fmt::Result {
64 write!(f, "{}", displayable_concrete(db, &self.trait_id.full_path(db), &self.generic_args))
65 }
66}
67
68define_short_id!(ConcreteTraitId, ConcreteTraitLongId<'db>);
69semantic_object_for_id!(ConcreteTraitId, ConcreteTraitLongId<'a>);
70impl<'db> ConcreteTraitId<'db> {
71 pub fn trait_id(&self, db: &'db dyn Database) -> TraitId<'db> {
72 self.long(db).trait_id
73 }
74 pub fn generic_args(&self, db: &'db dyn Database) -> &'db [GenericArgumentId<'db>] {
75 &self.long(db).generic_args
76 }
77 pub fn name(&self, db: &'db dyn Database) -> SmolStrId<'db> {
78 self.trait_id(db).name(db)
79 }
80 pub fn full_path(&self, db: &dyn Database) -> String {
81 format!("{:?}", self.debug(db))
82 }
83 pub fn filter(&self, db: &'db dyn Database) -> TraitFilter<'db> {
84 let generics_filter = match self.generic_args(db).first() {
85 Some(first_generic) => match first_generic.head(db) {
86 Some(head) => GenericsHeadFilter::FirstGenericFilter(head),
87 None => GenericsHeadFilter::NoFilter,
88 },
89 None => GenericsHeadFilter::NoGenerics,
90 };
91 TraitFilter { trait_id: self.trait_id(db), generics_filter }
92 }
93
94 pub fn is_fully_concrete(&self, db: &dyn Database) -> bool {
96 self.long(db)
97 .generic_args
98 .iter()
99 .all(|generic_argument_id| generic_argument_id.is_fully_concrete(db))
100 }
101 pub fn is_var_free(&self, db: &dyn Database) -> bool {
103 self.long(db)
104 .generic_args
105 .iter()
106 .all(|generic_argument_id| generic_argument_id.is_var_free(db))
107 }
108}
109
110#[derive(
112 Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject, salsa::Update, HeapSize,
113)]
114#[debug_db(dyn Database)]
115pub struct ConcreteTraitGenericFunctionLongId<'db> {
116 concrete_trait: ConcreteTraitId<'db>,
118 trait_function: TraitFunctionId<'db>,
119}
120impl<'db> ConcreteTraitGenericFunctionLongId<'db> {
121 pub fn new(
122 db: &dyn Database,
123 concrete_trait: ConcreteTraitId<'db>,
124 trait_function: TraitFunctionId<'db>,
125 ) -> Self {
126 assert_eq!(
127 concrete_trait.trait_id(db),
128 trait_function.trait_id(db),
129 "Concrete trait and trait function must belong to the same generic trait."
130 );
131 Self { concrete_trait, trait_function }
132 }
133}
134define_short_id!(ConcreteTraitGenericFunctionId, ConcreteTraitGenericFunctionLongId<'db>);
135semantic_object_for_id!(ConcreteTraitGenericFunctionId, ConcreteTraitGenericFunctionLongId<'a>);
136impl<'db> ConcreteTraitGenericFunctionId<'db> {
137 pub fn new_from_data(
138 db: &'db dyn Database,
139 concrete_trait: ConcreteTraitId<'db>,
140 trait_function: TraitFunctionId<'db>,
141 ) -> Self {
142 ConcreteTraitGenericFunctionLongId::new(db, concrete_trait, trait_function).intern(db)
143 }
144
145 pub fn trait_function(&self, db: &'db dyn Database) -> TraitFunctionId<'db> {
146 self.long(db).trait_function
147 }
148
149 pub fn concrete_trait(&self, db: &'db dyn Database) -> ConcreteTraitId<'db> {
150 self.long(db).concrete_trait
151 }
152}
153
154#[derive(
156 Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject, salsa::Update, HeapSize,
157)]
158#[debug_db(dyn Database)]
159pub struct ConcreteTraitTypeLongId<'db> {
160 concrete_trait: ConcreteTraitId<'db>,
162 trait_type: TraitTypeId<'db>,
163}
164impl<'db> ConcreteTraitTypeLongId<'db> {
165 pub fn new(
166 db: &dyn Database,
167 concrete_trait: ConcreteTraitId<'db>,
168 trait_type: TraitTypeId<'db>,
169 ) -> Self {
170 assert_eq!(
171 concrete_trait.trait_id(db),
172 trait_type.trait_id(db),
173 "Concrete trait and trait type must belong to the same generic trait."
174 );
175 Self { concrete_trait, trait_type }
176 }
177}
178define_short_id!(ConcreteTraitTypeId, ConcreteTraitTypeLongId<'db>);
179semantic_object_for_id!(ConcreteTraitTypeId, ConcreteTraitTypeLongId<'a>);
180impl<'db> ConcreteTraitTypeId<'db> {
181 pub fn new_from_data(
182 db: &'db dyn Database,
183 concrete_trait: ConcreteTraitId<'db>,
184 trait_type: TraitTypeId<'db>,
185 ) -> Self {
186 ConcreteTraitTypeLongId::new(db, concrete_trait, trait_type).intern(db)
187 }
188
189 pub fn trait_type(&self, db: &'db dyn Database) -> TraitTypeId<'db> {
190 self.long(db).trait_type
191 }
192
193 pub fn concrete_trait(&self, db: &'db dyn Database) -> ConcreteTraitId<'db> {
194 self.long(db).concrete_trait
195 }
196}
197
198#[derive(
200 Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject, salsa::Update, HeapSize,
201)]
202#[debug_db(dyn Database)]
203pub struct ConcreteTraitConstantLongId<'db> {
204 concrete_trait: ConcreteTraitId<'db>,
206 trait_constant: TraitConstantId<'db>,
207}
208impl<'db> ConcreteTraitConstantLongId<'db> {
209 pub fn new(
210 db: &'db dyn Database,
211 concrete_trait: ConcreteTraitId<'db>,
212 trait_constant: TraitConstantId<'db>,
213 ) -> Self {
214 assert_eq!(
215 concrete_trait.trait_id(db),
216 trait_constant.trait_id(db),
217 "Concrete trait and trait constant must belong to the same generic trait."
218 );
219 Self { concrete_trait, trait_constant }
220 }
221}
222define_short_id!(ConcreteTraitConstantId, ConcreteTraitConstantLongId<'db>);
223semantic_object_for_id!(ConcreteTraitConstantId, ConcreteTraitConstantLongId<'a>);
224impl<'db> ConcreteTraitConstantId<'db> {
225 pub fn new_from_data(
226 db: &'db dyn Database,
227 concrete_trait: ConcreteTraitId<'db>,
228 trait_constant: TraitConstantId<'db>,
229 ) -> Self {
230 ConcreteTraitConstantLongId::new(db, concrete_trait, trait_constant).intern(db)
231 }
232
233 pub fn trait_constant(&self, db: &'db dyn Database) -> TraitConstantId<'db> {
234 self.long(db).trait_constant
235 }
236
237 pub fn concrete_trait(&self, db: &'db dyn Database) -> ConcreteTraitId<'db> {
238 self.long(db).concrete_trait
239 }
240}
241
242#[derive(
244 Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject, salsa::Update, HeapSize,
245)]
246#[debug_db(dyn Database)]
247pub struct ConcreteTraitImplLongId<'db> {
248 concrete_trait: ConcreteTraitId<'db>,
250 trait_impl: TraitImplId<'db>,
251}
252impl<'db> ConcreteTraitImplLongId<'db> {
253 pub fn new_from_data(
254 db: &dyn Database,
255 concrete_trait: ConcreteTraitId<'db>,
256 trait_impl: TraitImplId<'db>,
257 ) -> Self {
258 assert_eq!(
259 concrete_trait.trait_id(db),
260 trait_impl.trait_id(db),
261 "Concrete trait and trait impl must belong to the same generic trait."
262 );
263 Self { concrete_trait, trait_impl }
264 }
265}
266define_short_id!(ConcreteTraitImplId, ConcreteTraitImplLongId<'db>);
267semantic_object_for_id!(ConcreteTraitImplId, ConcreteTraitImplLongId<'a>);
268impl<'db> ConcreteTraitImplId<'db> {
269 pub fn new_from_data(
270 db: &'db dyn Database,
271 concrete_trait: ConcreteTraitId<'db>,
272 trait_impl: TraitImplId<'db>,
273 ) -> Self {
274 ConcreteTraitImplLongId::new_from_data(db, concrete_trait, trait_impl).intern(db)
275 }
276
277 pub fn trait_impl(&self, db: &'db dyn Database) -> TraitImplId<'db> {
278 self.long(db).trait_impl
279 }
280
281 pub fn concrete_trait(&self, db: &'db dyn Database) -> ConcreteTraitId<'db> {
282 self.long(db).concrete_trait
283 }
284}
285
286#[derive(Clone, Debug, PartialEq, Eq, DebugWithDb, salsa::Update)]
289#[debug_db(dyn Database)]
290struct TraitDeclarationData<'db> {
291 diagnostics: Diagnostics<'db, SemanticDiagnostic<'db>>,
292 attributes: Vec<Attribute<'db>>,
293 resolver_data: Arc<ResolverData<'db>>,
294}
295
296fn trait_generic_params_data<'db>(
298 db: &'db dyn Database,
299 trait_id: TraitId<'db>,
300 in_cycle: bool,
301) -> Maybe<GenericParamsData<'db>> {
302 let module_id = trait_id.parent_module(db);
303 let mut diagnostics = SemanticDiagnostics::new(module_id);
304 let trait_ast = db.module_trait_by_id(trait_id)?;
305
306 let inference_id =
308 InferenceId::LookupItemGenerics(LookupItemId::ModuleItem(ModuleItemId::Trait(trait_id)));
309 let mut resolver = Resolver::new(db, module_id, inference_id);
310 resolver.set_feature_config(&trait_id, &trait_ast, &mut diagnostics);
311 let generic_params = semantic_generic_params_ex(
312 db,
313 &mut diagnostics,
314 &mut resolver,
315 module_id,
316 &trait_ast.generic_params(db),
317 in_cycle,
318 );
319
320 let inference = &mut resolver.inference();
321 inference.finalize(&mut diagnostics, trait_ast.stable_ptr(db).untyped());
322
323 let generic_params = inference.rewrite(generic_params).no_err();
324 let resolver_data = Arc::new(resolver.data);
325 Ok(GenericParamsData { diagnostics: diagnostics.build(), generic_params, resolver_data })
326}
327
328#[salsa::tracked(cycle_result=trait_generic_params_data_cycle, returns(ref))]
330fn trait_generic_params_data_tracked<'db>(
331 db: &'db dyn Database,
332 trait_id: TraitId<'db>,
333 in_cycle: bool,
334) -> Maybe<GenericParamsData<'db>> {
335 trait_generic_params_data(db, trait_id, in_cycle)
336}
337
338fn trait_generic_params_data_cycle<'db>(
340 db: &'db dyn Database,
341 _id: salsa::Id,
342 trait_id: TraitId<'db>,
343 _in_cycle: bool,
344) -> Maybe<GenericParamsData<'db>> {
345 trait_generic_params_data(db, trait_id, true)
347}
348
349#[salsa::tracked(returns(ref))]
351fn trait_generic_params_ids<'db>(
352 db: &'db dyn Database,
353 trait_id: TraitId<'db>,
354) -> Maybe<Vec<GenericParamId<'db>>> {
355 let module_id = trait_id.parent_module(db);
356 let trait_ast = db.module_trait_by_id(trait_id)?;
357
358 let generic_params = &trait_ast.generic_params(db);
359
360 let syntax_db = db;
361 Ok(match generic_params {
362 syntax::node::ast::OptionWrappedGenericParamList::Empty(_) => vec![],
363 syntax::node::ast::OptionWrappedGenericParamList::WrappedGenericParamList(syntax) => syntax
364 .generic_params(syntax_db)
365 .elements(syntax_db)
366 .map(|param_syntax| {
367 GenericParamLongId(module_id, param_syntax.stable_ptr(syntax_db)).intern(db)
368 })
369 .collect(),
370 })
371}
372
373#[salsa::tracked(returns(ref))]
375fn priv_trait_declaration_data<'db>(
376 db: &'db dyn Database,
377 trait_id: TraitId<'db>,
378) -> Maybe<TraitDeclarationData<'db>> {
379 let mut diagnostics = SemanticDiagnostics::new(trait_id.parent_module(db));
380 let trait_ast = db.module_trait_by_id(trait_id)?;
384
385 let generic_params_data = db.trait_generic_params_data(trait_id, false)?;
387 let inference_id =
388 InferenceId::LookupItemDeclaration(LookupItemId::ModuleItem(ModuleItemId::Trait(trait_id)));
389 let mut resolver = Resolver::with_data(
390 db,
391 (*generic_params_data.resolver_data).clone_with_inference_id(db, inference_id),
392 );
393 diagnostics.extend(generic_params_data.diagnostics.clone());
394
395 let attributes = trait_ast.attributes(db).structurize(db);
396
397 let inference = &mut resolver.inference();
399 inference.finalize(&mut diagnostics, trait_ast.stable_ptr(db).untyped());
400
401 let mut resolver_data = resolver.data;
402 resolver_data.trait_or_impl_ctx = TraitOrImplContext::Trait(trait_id);
403 Ok(TraitDeclarationData {
404 diagnostics: diagnostics.build(),
405 attributes,
406 resolver_data: Arc::new(resolver_data),
407 })
408}
409
410#[derive(Clone, Debug, PartialEq, Eq, DebugWithDb, salsa::Update)]
413#[debug_db(dyn Database)]
414struct TraitDefinitionData<'db> {
415 diagnostics: Diagnostics<'db, SemanticDiagnostic<'db>>,
420
421 function_asts: OrderedHashMap<TraitFunctionId<'db>, ast::TraitItemFunction<'db>>,
423 item_type_asts: OrderedHashMap<TraitTypeId<'db>, ast::TraitItemType<'db>>,
424 item_constant_asts: OrderedHashMap<TraitConstantId<'db>, ast::TraitItemConstant<'db>>,
425 item_impl_asts: OrderedHashMap<TraitImplId<'db>, ast::TraitItemImpl<'db>>,
426
427 item_id_by_name: OrderedHashMap<SmolStrId<'db>, TraitItemInfo<'db>>,
429}
430
431#[derive(Clone, Debug, PartialEq, Eq, salsa::Update)]
433pub struct TraitItemInfo<'db> {
434 pub id: TraitItemId<'db>,
436 pub feature_kind: FeatureKind<'db>,
438}
439
440impl<'db> HasFeatureKind<'db> for TraitItemInfo<'db> {
441 fn feature_kind(&self) -> &FeatureKind<'db> {
443 &self.feature_kind
444 }
445}
446
447fn trait_semantic_definition_diagnostics<'db>(
451 db: &'db dyn Database,
452 trait_id: TraitId<'db>,
453) -> Diagnostics<'db, SemanticDiagnostic<'db>> {
454 let mut diagnostics = DiagnosticsBuilder::default();
455
456 let Ok(data) = db.priv_trait_definition_data(trait_id) else {
457 return Diagnostics::default();
458 };
459
460 diagnostics.extend(data.diagnostics.clone());
463 for trait_function_id in data.function_asts.keys() {
464 diagnostics.extend(db.trait_function_declaration_diagnostics(*trait_function_id));
465 diagnostics.extend(db.trait_function_body_diagnostics(*trait_function_id));
466 }
467 for trait_type_id in data.item_type_asts.keys() {
468 diagnostics.extend(db.trait_type_diagnostics(*trait_type_id));
469 }
470 for trait_constant in data.item_constant_asts.keys() {
471 diagnostics.extend(db.trait_constant_diagnostics(*trait_constant));
472 }
473 for trait_impl in data.item_impl_asts.keys() {
474 diagnostics.extend(db.trait_impl_diagnostics(*trait_impl));
475 }
476
477 diagnostics.build()
478}
479
480#[salsa::tracked]
482fn trait_semantic_definition_diagnostics_tracked<'db>(
483 db: &'db dyn Database,
484 trait_id: TraitId<'db>,
485) -> Diagnostics<'db, SemanticDiagnostic<'db>> {
486 trait_semantic_definition_diagnostics(db, trait_id)
487}
488
489#[salsa::tracked(returns(ref))]
491fn trait_required_item_names<'db>(
492 db: &'db dyn Database,
493 trait_id: TraitId<'db>,
494) -> Maybe<OrderedHashSet<SmolStrId<'db>>> {
495 let mut required_items = OrderedHashSet::<_>::default();
496 for (item_name, item_id) in db.priv_trait_definition_data(trait_id)?.item_id_by_name.iter() {
497 if match item_id.id {
498 TraitItemId::Function(id) => {
499 let body = id.stable_ptr(db).lookup(db).body(db);
500 matches!(body, ast::MaybeTraitFunctionBody::None(_))
501 }
502 TraitItemId::Type(_) | TraitItemId::Constant(_) => true,
503 TraitItemId::Impl(_) => false,
504 } {
505 required_items.insert(*item_name);
506 }
507 }
508 Ok(required_items)
509}
510
511#[salsa::tracked(returns(ref))]
513fn trait_all_used_uses<'db>(
514 db: &'db dyn Database,
515 trait_id: TraitId<'db>,
516) -> Maybe<OrderedHashSet<UseId<'db>>> {
517 let mut all_used_uses = db.trait_resolver_data(trait_id)?.used_uses.clone();
518 let data = db.priv_trait_definition_data(trait_id)?;
519 for item in data.item_id_by_name.values() {
520 for resolver_data in get_resolver_data_options(LookupItemId::TraitItem(item.id), db) {
521 all_used_uses.extend(resolver_data.used_uses.iter().cloned());
522 }
523 }
524 Ok(all_used_uses)
525}
526
527#[salsa::tracked(returns(ref))]
529fn trait_functions<'db>(
530 db: &'db dyn Database,
531 trait_id: TraitId<'db>,
532) -> Maybe<OrderedHashMap<SmolStrId<'db>, TraitFunctionId<'db>>> {
533 Ok(db
534 .priv_trait_definition_data(trait_id)?
535 .function_asts
536 .keys()
537 .map(|function_id| {
538 let function_long_id = function_id.long(db);
539 (function_long_id.name(db), *function_id)
540 })
541 .collect())
542}
543
544#[salsa::tracked(returns(ref))]
546fn trait_types<'db>(
547 db: &'db dyn Database,
548 trait_id: TraitId<'db>,
549) -> Maybe<OrderedHashMap<SmolStrId<'db>, TraitTypeId<'db>>> {
550 Ok(db
551 .priv_trait_definition_data(trait_id)?
552 .item_type_asts
553 .keys()
554 .map(|type_id| {
555 let type_long_id = type_id.long(db);
556 (type_long_id.name(db), *type_id)
557 })
558 .collect())
559}
560
561#[salsa::tracked(returns(ref))]
563fn trait_constants<'db>(
564 db: &'db dyn Database,
565 trait_id: TraitId<'db>,
566) -> Maybe<OrderedHashMap<SmolStrId<'db>, TraitConstantId<'db>>> {
567 Ok(db
568 .priv_trait_definition_data(trait_id)?
569 .item_constant_asts
570 .keys()
571 .map(|constant_id| {
572 let constant_long_id = constant_id.long(db);
573 (constant_long_id.name(db), *constant_id)
574 })
575 .collect())
576}
577
578#[salsa::tracked(returns(ref))]
580fn trait_impls<'db>(
581 db: &'db dyn Database,
582 trait_id: TraitId<'db>,
583) -> Maybe<OrderedHashMap<SmolStrId<'db>, TraitImplId<'db>>> {
584 Ok(db
585 .priv_trait_definition_data(trait_id)?
586 .item_impl_asts
587 .keys()
588 .map(|impl_id| {
589 let impl_long_id = impl_id.long(db);
590 (impl_long_id.name(db), *impl_id)
591 })
592 .collect())
593}
594
595#[salsa::tracked(returns(ref))]
599fn priv_trait_definition_data<'db>(
600 db: &'db dyn Database,
601 trait_id: TraitId<'db>,
602) -> Maybe<TraitDefinitionData<'db>> {
603 let module_id = trait_id.parent_module(db);
604 let mut diagnostics = SemanticDiagnostics::new(module_id);
605
606 let trait_ast = db.module_trait_by_id(trait_id)?;
610
611 let mut function_asts = OrderedHashMap::default();
612 let mut item_type_asts = OrderedHashMap::default();
613 let mut item_constant_asts = OrderedHashMap::default();
614 let mut item_impl_asts = OrderedHashMap::default();
615 let mut item_id_by_name: OrderedHashMap<SmolStrId<'db>, TraitItemInfo<'db>> =
616 OrderedHashMap::default();
617
618 if let ast::MaybeTraitBody::Some(body) = trait_ast.body(db) {
619 for item in body.items(db).elements(db) {
620 match item {
621 ast::TraitItem::Function(func) => {
622 let trait_func_id =
623 TraitFunctionLongId(module_id, func.stable_ptr(db)).intern(db);
624 let name_node = func.declaration(db).name(db);
625 let name = name_node.text(db);
626 let attributes = func.attributes(db);
627 let feature_kind = FeatureKind::from_ast(db, &mut diagnostics, &attributes);
628 if item_id_by_name
629 .insert(
630 name,
631 TraitItemInfo {
632 id: TraitItemId::Function(trait_func_id),
633 feature_kind,
634 },
635 )
636 .is_some()
637 {
638 diagnostics.report(
639 name_node.stable_ptr(db),
640 SemanticDiagnosticKind::NameDefinedMultipleTimes(name),
641 );
642 }
643 function_asts.insert(trait_func_id, func);
644 }
645 ast::TraitItem::Type(ty) => {
646 let trait_type_id = TraitTypeLongId(module_id, ty.stable_ptr(db)).intern(db);
647 let name_node = ty.name(db);
648 let name = name_node.text(db);
649 let attributes = ty.attributes(db);
650 let feature_kind = FeatureKind::from_ast(db, &mut diagnostics, &attributes);
651 if item_id_by_name
652 .insert(
653 name,
654 TraitItemInfo { id: TraitItemId::Type(trait_type_id), feature_kind },
655 )
656 .is_some()
657 {
658 diagnostics.report(
659 name_node.stable_ptr(db),
660 SemanticDiagnosticKind::NameDefinedMultipleTimes(name),
661 );
662 }
663 item_type_asts.insert(trait_type_id, ty);
664 }
665 ast::TraitItem::Constant(constant) => {
666 let trait_constant =
667 TraitConstantLongId(module_id, constant.stable_ptr(db)).intern(db);
668
669 let name_node = constant.name(db);
670 let name = name_node.text(db);
671 let attributes = constant.attributes(db);
672 let feature_kind = FeatureKind::from_ast(db, &mut diagnostics, &attributes);
673 if item_id_by_name
674 .insert(
675 name,
676 TraitItemInfo {
677 id: TraitItemId::Constant(trait_constant),
678 feature_kind,
679 },
680 )
681 .is_some()
682 {
683 diagnostics.report(
684 name_node.stable_ptr(db),
685 SemanticDiagnosticKind::NameDefinedMultipleTimes(name),
686 );
687 }
688 item_constant_asts.insert(trait_constant, constant);
689 }
690 ast::TraitItem::Impl(imp) => {
691 let trait_impl = TraitImplLongId(module_id, imp.stable_ptr(db)).intern(db);
692
693 let name_node = imp.name(db);
694 let name = name_node.text(db);
695 let attributes = imp.attributes(db);
696 let feature_kind = FeatureKind::from_ast(db, &mut diagnostics, &attributes);
697 if item_id_by_name
698 .insert(
699 name,
700 TraitItemInfo { id: TraitItemId::Impl(trait_impl), feature_kind },
701 )
702 .is_some()
703 {
704 diagnostics.report(
705 name_node.stable_ptr(db),
706 SemanticDiagnosticKind::NameDefinedMultipleTimes(name),
707 );
708 }
709 item_impl_asts.insert(trait_impl, imp);
710 }
711 ast::TraitItem::Missing(_) => {}
712 }
713 }
714 }
715
716 Ok(TraitDefinitionData {
717 diagnostics: diagnostics.build(),
718 function_asts,
719 item_type_asts,
720 item_constant_asts,
721 item_impl_asts,
722 item_id_by_name,
723 })
724}
725
726#[derive(Clone, Debug, PartialEq, Eq, DebugWithDb, salsa::Update)]
729#[debug_db(dyn Database)]
730struct TraitItemTypeData<'db> {
731 pub diagnostics: Diagnostics<'db, SemanticDiagnostic<'db>>,
732 pub attributes: Vec<Attribute<'db>>,
733 pub resolver_data: Arc<ResolverData<'db>>,
734}
735
736#[salsa::tracked(returns(ref))]
738fn priv_trait_type_generic_params_data<'db>(
739 db: &'db dyn Database,
740 trait_type_id: TraitTypeId<'db>,
741) -> Maybe<GenericParamsData<'db>> {
742 let module_id = trait_type_id.parent_module(db);
743 let mut diagnostics = SemanticDiagnostics::new(module_id);
744 let trait_id = trait_type_id.trait_id(db);
745 let data = db.priv_trait_definition_data(trait_id)?;
746 let trait_type_ast = &data.item_type_asts[&trait_type_id];
747 let inference_id =
748 InferenceId::LookupItemGenerics(LookupItemId::TraitItem(TraitItemId::Type(trait_type_id)));
749 let parent_resolver_data = db.trait_resolver_data(trait_id)?;
750 let mut resolver =
751 Resolver::with_data(db, parent_resolver_data.clone_with_inference_id(db, inference_id));
752 for trait_generic_param in db.trait_generic_params(trait_id)? {
753 resolver.add_generic_param(trait_generic_param.id());
754 }
755 let generic_params_node = trait_type_ast.generic_params(db);
756 let type_generic_params = semantic_generic_params(
757 db,
758 &mut diagnostics,
759 &mut resolver,
760 module_id,
761 &generic_params_node,
762 );
763 let type_generic_params = resolver.inference().rewrite(type_generic_params).no_err();
764
765 if !generic_params_node.is_empty(db) {
768 diagnostics.report(
769 generic_params_node.stable_ptr(db),
770 GenericsNotSupportedInItem { scope: "Trait".into(), item_kind: "type".into() },
771 );
772 }
773
774 let resolver_data = Arc::new(resolver.data);
775 Ok(GenericParamsData {
776 diagnostics: diagnostics.build(),
777 generic_params: type_generic_params,
778 resolver_data,
779 })
780}
781
782#[salsa::tracked(returns(ref))]
784fn priv_trait_type_data<'db>(
785 db: &'db dyn Database,
786 trait_type_id: TraitTypeId<'db>,
787) -> Maybe<TraitItemTypeData<'db>> {
788 let mut diagnostics = SemanticDiagnostics::new(trait_type_id.parent_module(db));
789 let trait_id = trait_type_id.trait_id(db);
790 let data = db.priv_trait_definition_data(trait_id)?;
791 let type_syntax = &data.item_type_asts[&trait_type_id];
792
793 let type_generic_params_data = db.priv_trait_type_generic_params_data(trait_type_id)?;
794 let inference_id = InferenceId::LookupItemDeclaration(LookupItemId::TraitItem(
795 TraitItemId::Type(trait_type_id),
796 ));
797 let resolver = Resolver::with_data(
798 db,
799 (*type_generic_params_data.resolver_data).clone_with_inference_id(db, inference_id),
800 );
801 diagnostics.extend(type_generic_params_data.diagnostics.clone());
802
803 let attributes = type_syntax.attributes(db).structurize(db);
804 let resolver_data = Arc::new(resolver.data);
805
806 Ok(TraitItemTypeData { diagnostics: diagnostics.build(), attributes, resolver_data })
807}
808
809#[derive(Clone, Debug, PartialEq, Eq, DebugWithDb, salsa::Update)]
812#[debug_db(dyn Database)]
813struct TraitItemConstantData<'db> {
814 pub diagnostics: Diagnostics<'db, SemanticDiagnostic<'db>>,
815 pub ty: TypeId<'db>,
816 pub attributes: Vec<Attribute<'db>>,
817 pub resolver_data: Arc<ResolverData<'db>>,
818}
819
820#[salsa::tracked(returns(ref))]
824fn priv_trait_constant_data<'db>(
825 db: &'db dyn Database,
826 trait_constant: TraitConstantId<'db>,
827) -> Maybe<TraitItemConstantData<'db>> {
828 let mut diagnostics = SemanticDiagnostics::new(trait_constant.parent_module(db));
829 let trait_id = trait_constant.trait_id(db);
830 let data = db.priv_trait_definition_data(trait_id)?;
831 let constant_syntax = &data.item_constant_asts[&trait_constant];
832 let inference_id = InferenceId::LookupItemDeclaration(LookupItemId::TraitItem(
833 TraitItemId::Constant(trait_constant),
834 ));
835 let parent_resolver_data = db.trait_resolver_data(trait_id)?;
836 let mut resolver =
837 Resolver::with_data(db, parent_resolver_data.clone_with_inference_id(db, inference_id));
838
839 let ty =
840 resolve_type(db, &mut diagnostics, &mut resolver, &constant_syntax.type_clause(db).ty(db));
841 let attributes = constant_syntax.attributes(db).structurize(db);
842 let resolver_data = Arc::new(resolver.data);
843
844 Ok(TraitItemConstantData { diagnostics: diagnostics.build(), ty, attributes, resolver_data })
845}
846
847fn concrete_trait_constant_type<'db>(
849 db: &'db dyn Database,
850 concrete_trait_constant_id: ConcreteTraitConstantId<'db>,
851) -> Maybe<TypeId<'db>> {
852 let concrete_trait_id = concrete_trait_constant_id.concrete_trait(db);
853 let substitution = GenericSubstitution::new(
854 db.trait_generic_params(concrete_trait_id.trait_id(db))?,
855 concrete_trait_id.generic_args(db),
856 );
857 let generic_ty = db.trait_constant_type(concrete_trait_constant_id.trait_constant(db))?;
858 substitution.substitute(db, generic_ty)
859}
860
861#[salsa::tracked]
863fn concrete_trait_constant_type_tracked<'db>(
864 db: &'db dyn Database,
865 concrete_trait_constant_id: ConcreteTraitConstantId<'db>,
866) -> Maybe<TypeId<'db>> {
867 concrete_trait_constant_type(db, concrete_trait_constant_id)
868}
869
870#[derive(Clone, Debug, PartialEq, Eq, DebugWithDb, salsa::Update)]
873#[debug_db(dyn Database)]
874struct TraitItemImplData<'db> {
875 diagnostics: Diagnostics<'db, SemanticDiagnostic<'db>>,
876 concrete_trait: Maybe<ConcreteTraitId<'db>>,
877 attributes: Vec<Attribute<'db>>,
878 resolver_data: Arc<ResolverData<'db>>,
879}
880
881#[salsa::tracked(returns(ref))]
883fn priv_trait_impl_data<'db>(
884 db: &'db dyn Database,
885 trait_impl: TraitImplId<'db>,
886) -> Maybe<TraitItemImplData<'db>> {
887 let mut diagnostics = SemanticDiagnostics::new(trait_impl.parent_module(db));
888 let trait_id = trait_impl.trait_id(db);
889 let data = db.priv_trait_definition_data(trait_id)?;
890 let impl_syntax = &data.item_impl_asts[&trait_impl];
891 let trait_path = impl_syntax.trait_path(db);
892 let inference_id =
893 InferenceId::LookupItemDeclaration(LookupItemId::TraitItem(TraitItemId::Impl(trait_impl)));
894 let parent_resolver_data = db.trait_resolver_data(trait_id)?;
895 let mut resolver =
896 Resolver::with_data(db, parent_resolver_data.clone_with_inference_id(db, inference_id));
897 let concrete_trait = resolver
898 .resolve_concrete_path(&mut diagnostics, &trait_path, NotFoundItemType::Trait)
899 .and_then(|resolved_item: crate::resolve::ResolvedConcreteItem<'_>| match resolved_item {
900 ResolvedConcreteItem::Trait(id) | ResolvedConcreteItem::SelfTrait(id) => Ok(id),
901 _ => {
902 Err(diagnostics
903 .report(trait_path.stable_ptr(db), SemanticDiagnosticKind::UnknownTrait))
904 }
905 });
906 let attributes = impl_syntax.attributes(db).structurize(db);
907 let resolver_data = Arc::new(resolver.data);
908
909 Ok(TraitItemImplData {
910 diagnostics: diagnostics.build(),
911 concrete_trait,
912 attributes,
913 resolver_data,
914 })
915}
916
917fn concrete_trait_impl_concrete_trait<'db>(
919 db: &'db dyn Database,
920 concrete_trait_impl_id: ConcreteTraitImplId<'db>,
921) -> Maybe<ConcreteTraitId<'db>> {
922 let concrete_trait_id = concrete_trait_impl_id.concrete_trait(db);
923 GenericSubstitution::new(
924 db.trait_generic_params(concrete_trait_id.trait_id(db))?,
925 concrete_trait_id.generic_args(db),
926 )
927 .substitute(db, db.trait_impl_concrete_trait(concrete_trait_impl_id.trait_impl(db))?)
928}
929
930#[salsa::tracked]
932fn concrete_trait_impl_concrete_trait_tracked<'db>(
933 db: &'db dyn Database,
934 concrete_trait_impl_id: ConcreteTraitImplId<'db>,
935) -> Maybe<ConcreteTraitId<'db>> {
936 concrete_trait_impl_concrete_trait(db, concrete_trait_impl_id)
937}
938
939#[salsa::tracked(returns(ref))]
943fn priv_trait_function_generic_params_data<'db>(
944 db: &'db dyn Database,
945 trait_function_id: TraitFunctionId<'db>,
946) -> Maybe<GenericParamsData<'db>> {
947 let module_id = trait_function_id.parent_module(db);
948 let mut diagnostics = SemanticDiagnostics::new(module_id);
949 let trait_id = trait_function_id.trait_id(db);
950 let data = db.priv_trait_definition_data(trait_id)?;
951 let function_syntax = &data.function_asts[&trait_function_id];
952 let declaration = function_syntax.declaration(db);
953 let inference_id = InferenceId::LookupItemGenerics(LookupItemId::TraitItem(
954 TraitItemId::Function(trait_function_id),
955 ));
956 let parent_resolver_data = db.trait_resolver_data(trait_id)?;
957 let mut resolver =
958 Resolver::with_data(db, parent_resolver_data.clone_with_inference_id(db, inference_id));
959 let trait_generic_params = db.trait_generic_params(trait_id)?;
960 for generic_param in trait_generic_params {
961 resolver.add_generic_param(generic_param.id());
962 }
963 let function_generic_params = semantic_generic_params(
964 db,
965 &mut diagnostics,
966 &mut resolver,
967 module_id,
968 &declaration.generic_params(db),
969 );
970 let function_generic_params = resolver.inference().rewrite(function_generic_params).no_err();
971 let resolver_data = Arc::new(resolver.data);
972 Ok(GenericParamsData {
973 diagnostics: diagnostics.build(),
974 generic_params: function_generic_params,
975 resolver_data,
976 })
977}
978
979#[salsa::tracked(returns(ref))]
981fn priv_trait_function_declaration_data<'db>(
982 db: &'db dyn Database,
983 trait_function_id: TraitFunctionId<'db>,
984) -> Maybe<FunctionDeclarationData<'db>> {
985 let mut diagnostics = SemanticDiagnostics::new(trait_function_id.parent_module(db));
986 let trait_id = trait_function_id.trait_id(db);
987 let data = db.priv_trait_definition_data(trait_id)?;
988 let function_syntax = &data.function_asts[&trait_function_id];
989 let declaration_syntax = function_syntax.declaration(db);
990 let function_generic_params_data =
991 db.priv_trait_function_generic_params_data(trait_function_id)?;
992 let lookup_item_id = LookupItemId::TraitItem(TraitItemId::Function(trait_function_id));
993 let inference_id = InferenceId::LookupItemDeclaration(lookup_item_id);
994 let mut resolver = Resolver::with_data(
995 db,
996 (*function_generic_params_data.resolver_data).clone_with_inference_id(db, inference_id),
997 );
998 diagnostics.extend(function_generic_params_data.diagnostics.clone());
999 resolver.set_feature_config(&trait_function_id, function_syntax, &mut diagnostics);
1000 let mut environment = Environment::empty();
1001 let signature = semantic::Signature::from_ast(
1002 &mut diagnostics,
1003 db,
1004 &mut resolver,
1005 &declaration_syntax,
1006 FunctionTitleId::Trait(trait_function_id),
1007 &mut environment,
1008 );
1009
1010 let inference = &mut resolver.inference();
1012 inference.finalize(&mut diagnostics, function_syntax.stable_ptr(db).untyped());
1013 let signature = inference.rewrite(signature).no_err();
1014
1015 validate_trait_function_signature(
1016 db,
1017 &mut diagnostics,
1018 trait_id,
1019 trait_function_id,
1020 &signature,
1021 );
1022
1023 let attributes = function_syntax.attributes(db).structurize(db);
1024
1025 let inline_config = get_inline_config(db, &mut diagnostics, &attributes)?;
1026 let (implicit_precedence, _) =
1027 get_implicit_precedence(db, &mut diagnostics, &mut resolver, &attributes);
1028 let resolver_data = Arc::new(resolver.data);
1029
1030 Ok(FunctionDeclarationData {
1031 diagnostics: diagnostics.build(),
1032 signature,
1033 environment,
1034 attributes,
1035 resolver_data,
1036 inline_config,
1037 implicit_precedence,
1038 })
1039}
1040
1041fn validate_trait_function_signature<'db>(
1042 db: &'db dyn Database,
1043 diagnostics: &mut SemanticDiagnostics<'db>,
1044 trait_id: TraitId<'db>,
1045 function_id: TraitFunctionId<'db>,
1046 sig: &semantic::Signature<'db>,
1047) {
1048 for param in &sig.params {
1049 if param.mutability == Mutability::Mutable {
1050 diagnostics.report(
1051 param.stable_ptr(db).lookup(db).modifiers(db).stable_ptr(db),
1052 crate::diagnostic::SemanticDiagnosticKind::TraitParamMutable {
1053 trait_id,
1054 function_id,
1055 },
1056 );
1057 }
1058 }
1059}
1060
1061fn concrete_trait_function_generic_params<'db>(
1065 db: &'db dyn Database,
1066 concrete_trait_function_id: ConcreteTraitGenericFunctionId<'db>,
1067) -> Maybe<Vec<GenericParam<'db>>> {
1068 let concrete_trait_id = concrete_trait_function_id.concrete_trait(db);
1069 GenericSubstitution::new(
1070 db.trait_generic_params(concrete_trait_id.trait_id(db))?,
1071 concrete_trait_id.generic_args(db),
1072 )
1073 .substitute(
1074 db,
1075 db.trait_function_generic_params(concrete_trait_function_id.trait_function(db))?.to_vec(),
1076 )
1077}
1078
1079#[salsa::tracked(returns(ref))]
1081fn concrete_trait_function_generic_params_tracked<'db>(
1082 db: &'db dyn Database,
1083 concrete_trait_function_id: ConcreteTraitGenericFunctionId<'db>,
1084) -> Maybe<Vec<GenericParam<'db>>> {
1085 concrete_trait_function_generic_params(db, concrete_trait_function_id)
1086}
1087
1088#[salsa::tracked(returns(ref))]
1090fn concrete_trait_function_signature<'db>(
1091 db: &'db dyn Database,
1092 concrete_trait_function_id: ConcreteTraitGenericFunctionId<'db>,
1093) -> Maybe<semantic::Signature<'db>> {
1094 let concrete_trait_id = concrete_trait_function_id.concrete_trait(db);
1095 GenericSubstitution::new(
1096 db.trait_generic_params(concrete_trait_id.trait_id(db))?,
1097 concrete_trait_id.generic_args(db),
1098 )
1099 .substitute(
1100 db,
1101 db.trait_function_signature(concrete_trait_function_id.trait_function(db))?.clone(),
1102 )
1103}
1104
1105#[salsa::tracked(returns(ref))]
1109fn priv_trait_function_body_data<'db>(
1110 db: &'db dyn Database,
1111 trait_function_id: TraitFunctionId<'db>,
1112) -> Maybe<Option<FunctionBodyData<'db>>> {
1113 let mut diagnostics = SemanticDiagnostics::new(trait_function_id.parent_module(db));
1114 let trait_id = trait_function_id.trait_id(db);
1115 let data = db.priv_trait_definition_data(trait_id)?;
1116 let function_syntax = &data.function_asts[&trait_function_id];
1117 let trait_function_declaration_data =
1119 db.priv_trait_function_declaration_data(trait_function_id)?;
1120 let parent_resolver_data = &trait_function_declaration_data.resolver_data;
1121 let inference_id = InferenceId::LookupItemDefinition(LookupItemId::TraitItem(
1122 TraitItemId::Function(trait_function_id),
1123 ));
1124 let mut resolver =
1125 Resolver::with_data(db, (*parent_resolver_data).clone_with_inference_id(db, inference_id));
1126 resolver.trait_or_impl_ctx = TraitOrImplContext::Trait(trait_id);
1127 let environment = trait_function_declaration_data.environment.clone();
1128
1129 let function_id: Result<crate::FunctionId<'db>, cairo_lang_diagnostics::DiagnosticAdded> =
1130 (|| {
1131 let generic_parameters = db.trait_generic_params(trait_id)?;
1132 let concrete_trait = ConcreteTraitLongId {
1133 trait_id,
1134 generic_args: generic_params_to_args(generic_parameters, db),
1135 }
1136 .intern(db);
1137 let generic_function = GenericFunctionId::Impl(ImplGenericFunctionId {
1138 impl_id: ImplLongId::SelfImpl(concrete_trait).intern(db),
1139 function: trait_function_id,
1140 });
1141
1142 Ok(FunctionLongId::from_generic(db, generic_function)?.intern(db))
1143 })();
1144 let mut ctx: ComputationContext<'db, '_> = ComputationContext::new(
1146 db,
1147 &mut diagnostics,
1148 &mut resolver,
1149 Some(&trait_function_declaration_data.signature),
1150 environment,
1151 ContextFunction::Function(function_id),
1152 );
1153 let function_body = match function_syntax.body(db) {
1154 ast::MaybeTraitFunctionBody::Some(expr_block) => expr_block,
1155 ast::MaybeTraitFunctionBody::None(_) => return Ok(None),
1156 };
1157 let return_type = trait_function_declaration_data.signature.return_type;
1158 let body_expr = compute_root_expr(&mut ctx, &function_body, return_type)?;
1159 let ComputationContext { arenas, .. } = ctx;
1160
1161 let expr_lookup: UnorderedHashMap<_, _> =
1162 arenas.exprs.iter().map(|(id, expr)| (expr.stable_ptr(), id)).collect();
1163 let pattern_lookup: UnorderedHashMap<_, _> =
1164 arenas.patterns.iter().map(|(id, pattern)| (pattern.stable_ptr(), id)).collect();
1165 let resolver_data = Arc::new(resolver.data);
1166 Ok(Some(FunctionBodyData {
1167 diagnostics: diagnostics.build(),
1168 expr_lookup,
1169 pattern_lookup,
1170 resolver_data,
1171 body: FunctionBody { arenas, body_expr },
1172 }))
1173}
1174
1175pub trait TraitSemantic<'db>: Database {
1177 fn trait_semantic_declaration_diagnostics(
1179 &'db self,
1180 trait_id: TraitId<'db>,
1181 ) -> Diagnostics<'db, SemanticDiagnostic<'db>> {
1182 self.priv_trait_declaration_data(trait_id)
1183 .map(|data| data.diagnostics.clone())
1184 .unwrap_or_default()
1185 }
1186 fn trait_generic_params(&'db self, trait_id: TraitId<'db>) -> Maybe<&'db [GenericParam<'db>]> {
1188 Ok(&self.trait_generic_params_data(trait_id, false)?.generic_params)
1189 }
1190 fn trait_generic_params_ids(
1192 &'db self,
1193 trait_id: TraitId<'db>,
1194 ) -> Maybe<&'db [GenericParamId<'db>]> {
1195 Ok(trait_generic_params_ids(self.as_dyn_database(), trait_id).maybe_as_ref()?)
1196 }
1197 fn trait_attributes(&'db self, trait_id: TraitId<'db>) -> Maybe<&'db [Attribute<'db>]> {
1199 Ok(&self.priv_trait_declaration_data(trait_id)?.attributes)
1200 }
1201 fn trait_resolver_data(&'db self, trait_id: TraitId<'db>) -> Maybe<Arc<ResolverData<'db>>> {
1203 Ok(self.priv_trait_declaration_data(trait_id)?.resolver_data.clone())
1204 }
1205 fn trait_semantic_definition_diagnostics(
1207 &'db self,
1208 trait_id: TraitId<'db>,
1209 ) -> Diagnostics<'db, SemanticDiagnostic<'db>> {
1210 trait_semantic_definition_diagnostics_tracked(self.as_dyn_database(), trait_id)
1211 }
1212 fn trait_required_item_names(
1214 &'db self,
1215 trait_id: TraitId<'db>,
1216 ) -> Maybe<&'db OrderedHashSet<SmolStrId<'db>>> {
1217 trait_required_item_names(self.as_dyn_database(), trait_id).maybe_as_ref()
1218 }
1219 fn trait_item_by_name(
1221 &'db self,
1222 trait_id: TraitId<'db>,
1223 name: SmolStrId<'db>,
1224 ) -> Maybe<Option<TraitItemId<'db>>> {
1225 Ok(self
1226 .priv_trait_definition_data(trait_id)?
1227 .item_id_by_name
1228 .get(&name)
1229 .map(|info| info.id))
1230 }
1231 fn trait_item_info_by_name(
1233 &'db self,
1234 trait_id: TraitId<'db>,
1235 name: SmolStrId<'db>,
1236 ) -> Maybe<Option<TraitItemInfo<'db>>> {
1237 Ok(self.priv_trait_definition_data(trait_id)?.item_id_by_name.get(&name).cloned())
1238 }
1239 fn trait_all_used_uses(
1241 &'db self,
1242 trait_id: TraitId<'db>,
1243 ) -> Maybe<&'db OrderedHashSet<UseId<'db>>> {
1244 trait_all_used_uses(self.as_dyn_database(), trait_id).maybe_as_ref()
1245 }
1246 fn trait_functions(
1248 &'db self,
1249 trait_id: TraitId<'db>,
1250 ) -> Maybe<&'db OrderedHashMap<SmolStrId<'db>, TraitFunctionId<'db>>> {
1251 trait_functions(self.as_dyn_database(), trait_id).maybe_as_ref()
1252 }
1253 fn trait_function_by_name(
1255 &'db self,
1256 trait_id: TraitId<'db>,
1257 name: SmolStrId<'db>,
1258 ) -> Maybe<Option<TraitFunctionId<'db>>> {
1259 Ok(self.trait_functions(trait_id)?.get(&name).copied())
1260 }
1261 fn trait_types(
1263 &'db self,
1264 trait_id: TraitId<'db>,
1265 ) -> Maybe<&'db OrderedHashMap<SmolStrId<'db>, TraitTypeId<'db>>> {
1266 trait_types(self.as_dyn_database(), trait_id).maybe_as_ref()
1267 }
1268 fn trait_type_by_name(
1270 &'db self,
1271 trait_id: TraitId<'db>,
1272 name: SmolStrId<'db>,
1273 ) -> Maybe<Option<TraitTypeId<'db>>> {
1274 Ok(self.trait_types(trait_id)?.get(&name).copied())
1275 }
1276 fn trait_constants(
1278 &'db self,
1279 trait_id: TraitId<'db>,
1280 ) -> Maybe<&'db OrderedHashMap<SmolStrId<'db>, TraitConstantId<'db>>> {
1281 trait_constants(self.as_dyn_database(), trait_id).maybe_as_ref()
1282 }
1283 fn trait_constant_by_name(
1285 &'db self,
1286 trait_id: TraitId<'db>,
1287 name: SmolStrId<'db>,
1288 ) -> Maybe<Option<TraitConstantId<'db>>> {
1289 Ok(self.trait_constants(trait_id)?.get(&name).copied())
1290 }
1291 fn trait_impls(
1293 &'db self,
1294 trait_id: TraitId<'db>,
1295 ) -> Maybe<&'db OrderedHashMap<SmolStrId<'db>, TraitImplId<'db>>> {
1296 trait_impls(self.as_dyn_database(), trait_id).maybe_as_ref()
1297 }
1298 fn trait_impl_by_name(
1300 &'db self,
1301 trait_id: TraitId<'db>,
1302 name: SmolStrId<'db>,
1303 ) -> Maybe<Option<TraitImplId<'db>>> {
1304 Ok(self.trait_impls(trait_id)?.get(&name).copied())
1305 }
1306
1307 fn trait_type_generic_params(
1311 &'db self,
1312 trait_type_id: TraitTypeId<'db>,
1313 ) -> Maybe<&'db [GenericParam<'db>]> {
1314 Ok(&self.priv_trait_type_generic_params_data(trait_type_id)?.generic_params)
1315 }
1316 fn trait_type_attributes(
1318 &'db self,
1319 trait_type_id: TraitTypeId<'db>,
1320 ) -> Maybe<&'db [Attribute<'db>]> {
1321 Ok(&self.priv_trait_type_data(trait_type_id).maybe_as_ref()?.attributes)
1322 }
1323 fn trait_type_resolver_data(
1325 &'db self,
1326 trait_type_id: TraitTypeId<'db>,
1327 ) -> Maybe<Arc<ResolverData<'db>>> {
1328 Ok(self.priv_trait_type_data(trait_type_id)?.resolver_data.clone())
1329 }
1330
1331 fn trait_constant_attributes(
1335 &'db self,
1336 id: TraitConstantId<'db>,
1337 ) -> Maybe<Vec<Attribute<'db>>> {
1338 Ok(self.priv_trait_constant_data(id)?.attributes.clone())
1339 }
1340 fn trait_constant_type(&'db self, id: TraitConstantId<'db>) -> Maybe<TypeId<'db>> {
1342 Ok(self.priv_trait_constant_data(id)?.ty)
1343 }
1344 fn trait_constant_resolver_data(
1346 &'db self,
1347 id: TraitConstantId<'db>,
1348 ) -> Maybe<Arc<ResolverData<'db>>> {
1349 Ok(self.priv_trait_constant_data(id)?.resolver_data.clone())
1350 }
1351 fn concrete_trait_constant_type(
1353 &'db self,
1354 concrete_trait_constant_id: ConcreteTraitConstantId<'db>,
1355 ) -> Maybe<TypeId<'db>> {
1356 concrete_trait_constant_type_tracked(self.as_dyn_database(), concrete_trait_constant_id)
1357 }
1358
1359 fn trait_impl_concrete_trait(&'db self, id: TraitImplId<'db>) -> Maybe<ConcreteTraitId<'db>> {
1363 self.priv_trait_impl_data(id)?.concrete_trait
1364 }
1365 fn trait_impl_resolver_data(&'db self, id: TraitImplId<'db>) -> Maybe<Arc<ResolverData<'db>>> {
1367 Ok(self.priv_trait_impl_data(id)?.resolver_data.clone())
1368 }
1369 fn concrete_trait_impl_concrete_trait(
1371 &'db self,
1372 concrete_trait_impl_id: ConcreteTraitImplId<'db>,
1373 ) -> Maybe<ConcreteTraitId<'db>> {
1374 concrete_trait_impl_concrete_trait_tracked(self.as_dyn_database(), concrete_trait_impl_id)
1375 }
1376
1377 fn trait_function_declaration_diagnostics(
1381 &'db self,
1382 trait_function_id: TraitFunctionId<'db>,
1383 ) -> Diagnostics<'db, SemanticDiagnostic<'db>> {
1384 self.priv_trait_function_declaration_data(trait_function_id)
1385 .map(|data| data.diagnostics.clone())
1386 .unwrap_or_default()
1387 }
1388 fn trait_function_signature(
1390 &'db self,
1391 trait_function_id: TraitFunctionId<'db>,
1392 ) -> Maybe<&'db semantic::Signature<'db>> {
1393 Ok(&self.priv_trait_function_declaration_data(trait_function_id)?.signature)
1394 }
1395 fn trait_function_generic_params(
1397 &'db self,
1398 trait_function_id: TraitFunctionId<'db>,
1399 ) -> Maybe<&'db [GenericParam<'db>]> {
1400 Ok(&self.priv_trait_function_generic_params_data(trait_function_id)?.generic_params)
1401 }
1402 fn trait_function_attributes(
1404 &'db self,
1405 trait_function_id: TraitFunctionId<'db>,
1406 ) -> Maybe<&'db [Attribute<'db>]> {
1407 Ok(&self.priv_trait_function_declaration_data(trait_function_id)?.attributes)
1408 }
1409 fn trait_function_resolver_data(
1411 &'db self,
1412 trait_function_id: TraitFunctionId<'db>,
1413 ) -> Maybe<Arc<ResolverData<'db>>> {
1414 Ok(self.priv_trait_function_declaration_data(trait_function_id)?.resolver_data.clone())
1415 }
1416 fn trait_function_declaration_inline_config(
1418 &'db self,
1419 trait_function_id: TraitFunctionId<'db>,
1420 ) -> Maybe<InlineConfiguration<'db>> {
1421 Ok(self.priv_trait_function_declaration_data(trait_function_id)?.inline_config.clone())
1422 }
1423 fn trait_function_declaration_implicit_precedence(
1425 &'db self,
1426 trait_function_id: TraitFunctionId<'db>,
1427 ) -> Maybe<&'db ImplicitPrecedence<'db>> {
1428 Ok(&self.priv_trait_function_declaration_data(trait_function_id)?.implicit_precedence)
1429 }
1430 fn trait_function_body_diagnostics(
1432 &'db self,
1433 trait_function_id: TraitFunctionId<'db>,
1434 ) -> Diagnostics<'db, SemanticDiagnostic<'db>> {
1435 self.priv_trait_function_body_data(trait_function_id)
1436 .ok()
1437 .flatten()
1438 .map(|data| data.diagnostics.clone())
1439 .unwrap_or_default()
1440 }
1441 fn trait_function_body(
1443 &'db self,
1444 trait_function_id: TraitFunctionId<'db>,
1445 ) -> Maybe<Option<&'db FunctionBody<'db>>> {
1446 Ok(self.priv_trait_function_body_data(trait_function_id)?.map(|data| &data.body))
1447 }
1448 fn trait_function_body_resolver_data(
1450 &'db self,
1451 trait_function_id: TraitFunctionId<'db>,
1452 ) -> Maybe<Option<Arc<ResolverData<'db>>>> {
1453 self.priv_trait_function_body_data(trait_function_id)
1454 .map(|x| x.map(|y| y.resolver_data.clone()))
1455 }
1456 fn priv_trait_function_body_data(
1458 &'db self,
1459 trait_function_id: TraitFunctionId<'db>,
1460 ) -> Maybe<Option<&'db FunctionBodyData<'db>>> {
1461 priv_trait_function_body_data(self.as_dyn_database(), trait_function_id)
1462 .maybe_as_ref()
1463 .map(Option::as_ref)
1464 }
1465
1466 fn concrete_trait_function_generic_params(
1470 &'db self,
1471 concrete_trait_function_id: ConcreteTraitGenericFunctionId<'db>,
1472 ) -> Maybe<&'db [GenericParam<'db>]> {
1473 Ok(concrete_trait_function_generic_params_tracked(
1474 self.as_dyn_database(),
1475 concrete_trait_function_id,
1476 )
1477 .maybe_as_ref()?)
1478 }
1479 fn concrete_trait_function_signature(
1481 &'db self,
1482 concrete_trait_function_id: ConcreteTraitGenericFunctionId<'db>,
1483 ) -> Maybe<&'db semantic::Signature<'db>> {
1484 concrete_trait_function_signature(self.as_dyn_database(), concrete_trait_function_id)
1485 .maybe_as_ref()
1486 }
1487}
1488impl<'db, T: Database + ?Sized> TraitSemantic<'db> for T {}
1489
1490trait PrivTraitSemantic<'db>: Database {
1492 fn trait_generic_params_data(
1494 &'db self,
1495 trait_id: TraitId<'db>,
1496 in_cycle: bool,
1497 ) -> Maybe<&'db GenericParamsData<'db>> {
1498 trait_generic_params_data_tracked(self.as_dyn_database(), trait_id, in_cycle).maybe_as_ref()
1499 }
1500 fn priv_trait_declaration_data(
1502 &'db self,
1503 trait_id: TraitId<'db>,
1504 ) -> Maybe<&'db TraitDeclarationData<'db>> {
1505 priv_trait_declaration_data(self.as_dyn_database(), trait_id).maybe_as_ref()
1506 }
1507 fn priv_trait_definition_data(
1509 &'db self,
1510 trait_id: TraitId<'db>,
1511 ) -> Maybe<&'db TraitDefinitionData<'db>> {
1512 priv_trait_definition_data(self.as_dyn_database(), trait_id).maybe_as_ref()
1513 }
1514 fn trait_type_diagnostics(
1516 &'db self,
1517 id: TraitTypeId<'db>,
1518 ) -> Diagnostics<'db, SemanticDiagnostic<'db>> {
1519 self.priv_trait_type_data(id).map(|data| data.diagnostics.clone()).unwrap_or_default()
1520 }
1521 fn trait_impl_diagnostics(
1523 &'db self,
1524 id: TraitImplId<'db>,
1525 ) -> Diagnostics<'db, SemanticDiagnostic<'db>> {
1526 self.priv_trait_impl_data(id).map(|data| data.diagnostics.clone()).unwrap_or_default()
1527 }
1528 fn priv_trait_type_generic_params_data(
1530 &'db self,
1531 trait_type_id: TraitTypeId<'db>,
1532 ) -> Maybe<&'db GenericParamsData<'db>> {
1533 priv_trait_type_generic_params_data(self.as_dyn_database(), trait_type_id).maybe_as_ref()
1534 }
1535 fn priv_trait_type_data(
1537 &'db self,
1538 type_id: TraitTypeId<'db>,
1539 ) -> Maybe<&'db TraitItemTypeData<'db>> {
1540 priv_trait_type_data(self.as_dyn_database(), type_id).maybe_as_ref()
1541 }
1542 fn trait_constant_diagnostics(
1544 &'db self,
1545 id: TraitConstantId<'db>,
1546 ) -> Diagnostics<'db, SemanticDiagnostic<'db>> {
1547 self.priv_trait_constant_data(id).map(|data| data.diagnostics.clone()).unwrap_or_default()
1548 }
1549 fn priv_trait_constant_data(
1551 &'db self,
1552 trait_constant: TraitConstantId<'db>,
1553 ) -> Maybe<&'db TraitItemConstantData<'db>> {
1554 priv_trait_constant_data(self.as_dyn_database(), trait_constant).maybe_as_ref()
1555 }
1556 fn priv_trait_impl_data(
1558 &'db self,
1559 trait_impl: TraitImplId<'db>,
1560 ) -> Maybe<&'db TraitItemImplData<'db>> {
1561 priv_trait_impl_data(self.as_dyn_database(), trait_impl).maybe_as_ref()
1562 }
1563 fn priv_trait_function_generic_params_data(
1565 &'db self,
1566 trait_function_id: TraitFunctionId<'db>,
1567 ) -> Maybe<&'db GenericParamsData<'db>> {
1568 priv_trait_function_generic_params_data(self.as_dyn_database(), trait_function_id)
1569 .maybe_as_ref()
1570 }
1571 fn priv_trait_function_declaration_data(
1573 &'db self,
1574 function_id: TraitFunctionId<'db>,
1575 ) -> Maybe<&'db FunctionDeclarationData<'db>> {
1576 priv_trait_function_declaration_data(self.as_dyn_database(), function_id).maybe_as_ref()
1577 }
1578}
1579impl<'db, T: Database + ?Sized> PrivTraitSemantic<'db> for T {}