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