1use std::fmt::Write;
2use std::sync::Arc;
3
4use cairo_lang_debug::DebugWithDb;
5use cairo_lang_defs::ids::{
6 FunctionTitleId, LanguageElementId, LookupItemId, ModuleItemId, NamedLanguageElementId,
7 NamedLanguageElementLongId, TopLevelLanguageElementId, TraitConstantId, TraitConstantLongId,
8 TraitFunctionId, TraitFunctionLongId, TraitId, TraitImplId, TraitImplLongId, TraitItemId,
9 TraitTypeId, TraitTypeLongId, UseId,
10};
11use cairo_lang_diagnostics::{Diagnostics, DiagnosticsBuilder, Maybe, ToMaybe};
12use cairo_lang_proc_macros::{DebugWithDb, SemanticObject};
13use cairo_lang_syntax::attribute::structured::{Attribute, AttributeListStructurize};
14use cairo_lang_syntax::node::helpers::OptionWrappedGenericParamListHelper;
15use cairo_lang_syntax::node::{Terminal, TypedStablePtr, TypedSyntaxNode, ast};
16use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
17use cairo_lang_utils::ordered_hash_set::OrderedHashSet;
18use cairo_lang_utils::unordered_hash_map::UnorderedHashMap;
19use cairo_lang_utils::{Intern, LookupIntern, define_short_id};
20use smol_str::SmolStr;
21
22use super::TraitOrImplContext;
23use super::feature_kind::FeatureKind;
24use super::function_with_body::{FunctionBodyData, get_implicit_precedence, get_inline_config};
25use super::functions::{
26 FunctionDeclarationData, GenericFunctionId, ImplGenericFunctionId, ImplicitPrecedence,
27 InlineConfiguration,
28};
29use super::generics::{
30 GenericParamsData, fmt_generic_args, generic_params_to_args, semantic_generic_params,
31 semantic_generic_params_ex,
32};
33use super::imp::{GenericsHeadFilter, ImplLongId, TraitFilter};
34use crate::db::{SemanticGroup, get_resolver_data_options};
35use crate::diagnostic::SemanticDiagnosticKind::{self, *};
36use crate::diagnostic::{NotFoundItemType, SemanticDiagnostics, SemanticDiagnosticsBuilder};
37use crate::expr::compute::{ComputationContext, ContextFunction, Environment, compute_root_expr};
38use crate::expr::fmt::CountingWriter;
39use crate::expr::inference::InferenceId;
40use crate::expr::inference::canonic::ResultNoErrEx;
41use crate::items::feature_kind::HasFeatureKind;
42use crate::resolve::{ResolvedConcreteItem, Resolver, ResolverData};
43use crate::substitution::{GenericSubstitution, SemanticRewriter};
44use crate::types::resolve_type;
45use crate::{
46 Arenas, FunctionBody, FunctionLongId, GenericArgumentId, GenericParam, Mutability,
47 SemanticDiagnostic, TypeId, semantic, semantic_object_for_id,
48};
49
50#[cfg(test)]
51#[path = "trt_test.rs"]
52mod test;
53
54#[derive(Clone, Debug, Hash, PartialEq, Eq, SemanticObject)]
55pub struct ConcreteTraitLongId {
56 pub trait_id: TraitId,
57 pub generic_args: Vec<GenericArgumentId>,
58}
59impl DebugWithDb<dyn SemanticGroup> for ConcreteTraitLongId {
60 fn fmt(
61 &self,
62 f: &mut std::fmt::Formatter<'_>,
63 db: &(dyn SemanticGroup + 'static),
64 ) -> std::fmt::Result {
65 let mut f = CountingWriter::new(f);
66 write!(f, "{}", self.trait_id.full_path(db))?;
67 fmt_generic_args(&self.generic_args, &mut f, db)
68 }
69}
70
71define_short_id!(
72 ConcreteTraitId,
73 ConcreteTraitLongId,
74 SemanticGroup,
75 lookup_intern_concrete_trait,
76 intern_concrete_trait
77);
78semantic_object_for_id!(
79 ConcreteTraitId,
80 lookup_intern_concrete_trait,
81 intern_concrete_trait,
82 ConcreteTraitLongId
83);
84impl ConcreteTraitId {
85 pub fn trait_id(&self, db: &dyn SemanticGroup) -> TraitId {
86 self.lookup_intern(db).trait_id
87 }
88 pub fn generic_args(&self, db: &dyn SemanticGroup) -> Vec<GenericArgumentId> {
89 self.lookup_intern(db).generic_args
90 }
91 pub fn name(&self, db: &dyn SemanticGroup) -> SmolStr {
92 self.trait_id(db).name(db)
93 }
94 pub fn full_path(&self, db: &dyn SemanticGroup) -> String {
95 format!("{:?}", self.debug(db.elongate()))
96 }
97 pub fn filter(&self, db: &dyn SemanticGroup) -> TraitFilter {
98 let generics_filter = match self.generic_args(db).first() {
99 Some(first_generic) => match first_generic.head(db) {
100 Some(head) => GenericsHeadFilter::FirstGenericFilter(head),
101 None => GenericsHeadFilter::NoFilter,
102 },
103 None => GenericsHeadFilter::NoGenerics,
104 };
105 TraitFilter { trait_id: self.trait_id(db), generics_filter }
106 }
107
108 pub fn is_fully_concrete(&self, db: &dyn SemanticGroup) -> bool {
110 self.lookup_intern(db)
111 .generic_args
112 .iter()
113 .all(|generic_argument_id| generic_argument_id.is_fully_concrete(db))
114 }
115 pub fn is_var_free(&self, db: &dyn SemanticGroup) -> bool {
117 self.lookup_intern(db)
118 .generic_args
119 .iter()
120 .all(|generic_argument_id| generic_argument_id.is_var_free(db))
121 }
122}
123
124#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
126#[debug_db(dyn SemanticGroup + 'static)]
127pub struct ConcreteTraitGenericFunctionLongId {
128 concrete_trait: ConcreteTraitId,
130 trait_function: TraitFunctionId,
131}
132impl ConcreteTraitGenericFunctionLongId {
133 pub fn new(
134 db: &dyn SemanticGroup,
135 concrete_trait: ConcreteTraitId,
136 trait_function: TraitFunctionId,
137 ) -> Self {
138 assert_eq!(
139 concrete_trait.trait_id(db),
140 trait_function.trait_id(db),
141 "Concrete trait and trait function must belong to the same generic trait."
142 );
143 Self { concrete_trait, trait_function }
144 }
145}
146define_short_id!(
147 ConcreteTraitGenericFunctionId,
148 ConcreteTraitGenericFunctionLongId,
149 SemanticGroup,
150 lookup_intern_concrete_trait_function,
151 intern_concrete_trait_function
152);
153semantic_object_for_id!(
154 ConcreteTraitGenericFunctionId,
155 lookup_intern_concrete_trait_function,
156 intern_concrete_trait_function,
157 ConcreteTraitGenericFunctionLongId
158);
159impl ConcreteTraitGenericFunctionId {
160 pub fn new(
161 db: &dyn SemanticGroup,
162 concrete_trait: ConcreteTraitId,
163 trait_function: TraitFunctionId,
164 ) -> Self {
165 ConcreteTraitGenericFunctionLongId::new(db, concrete_trait, trait_function).intern(db)
166 }
167
168 pub fn trait_function(&self, db: &dyn SemanticGroup) -> TraitFunctionId {
169 self.lookup_intern(db).trait_function
170 }
171
172 pub fn concrete_trait(&self, db: &dyn SemanticGroup) -> ConcreteTraitId {
173 self.lookup_intern(db).concrete_trait
174 }
175}
176
177#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
179#[debug_db(dyn SemanticGroup + 'static)]
180pub struct ConcreteTraitTypeLongId {
181 concrete_trait: ConcreteTraitId,
183 trait_type: TraitTypeId,
184}
185impl ConcreteTraitTypeLongId {
186 pub fn new(
187 db: &dyn SemanticGroup,
188 concrete_trait: ConcreteTraitId,
189 trait_type: TraitTypeId,
190 ) -> Self {
191 assert_eq!(
192 concrete_trait.trait_id(db),
193 trait_type.trait_id(db),
194 "Concrete trait and trait type must belong to the same generic trait."
195 );
196 Self { concrete_trait, trait_type }
197 }
198}
199define_short_id!(
200 ConcreteTraitTypeId,
201 ConcreteTraitTypeLongId,
202 SemanticGroup,
203 lookup_intern_concrete_trait_type,
204 intern_concrete_trait_type
205);
206semantic_object_for_id!(
207 ConcreteTraitTypeId,
208 lookup_intern_concrete_trait_type,
209 intern_concrete_trait_type,
210 ConcreteTraitTypeLongId
211);
212impl ConcreteTraitTypeId {
213 pub fn new(
214 db: &dyn SemanticGroup,
215 concrete_trait: ConcreteTraitId,
216 trait_type: TraitTypeId,
217 ) -> Self {
218 ConcreteTraitTypeLongId::new(db, concrete_trait, trait_type).intern(db)
219 }
220
221 pub fn trait_type(&self, db: &dyn SemanticGroup) -> TraitTypeId {
222 self.lookup_intern(db).trait_type
223 }
224
225 pub fn concrete_trait(&self, db: &dyn SemanticGroup) -> ConcreteTraitId {
226 self.lookup_intern(db).concrete_trait
227 }
228}
229
230#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
232#[debug_db(dyn SemanticGroup + 'static)]
233pub struct ConcreteTraitConstantLongId {
234 concrete_trait: ConcreteTraitId,
236 trait_constant: TraitConstantId,
237}
238impl ConcreteTraitConstantLongId {
239 pub fn new(
240 db: &dyn SemanticGroup,
241 concrete_trait: ConcreteTraitId,
242 trait_constant: TraitConstantId,
243 ) -> Self {
244 assert_eq!(
245 concrete_trait.trait_id(db),
246 trait_constant.trait_id(db),
247 "Concrete trait and trait constant must belong to the same generic trait."
248 );
249 Self { concrete_trait, trait_constant }
250 }
251}
252define_short_id!(
253 ConcreteTraitConstantId,
254 ConcreteTraitConstantLongId,
255 SemanticGroup,
256 lookup_intern_concrete_trait_constant,
257 intern_concrete_trait_constant
258);
259semantic_object_for_id!(
260 ConcreteTraitConstantId,
261 lookup_intern_concrete_trait_constant,
262 intern_concrete_trait_constant,
263 ConcreteTraitConstantLongId
264);
265impl ConcreteTraitConstantId {
266 pub fn new(
267 db: &dyn SemanticGroup,
268 concrete_trait: ConcreteTraitId,
269 trait_constant: TraitConstantId,
270 ) -> Self {
271 ConcreteTraitConstantLongId::new(db, concrete_trait, trait_constant).intern(db)
272 }
273
274 pub fn trait_constant(&self, db: &dyn SemanticGroup) -> TraitConstantId {
275 self.lookup_intern(db).trait_constant
276 }
277
278 pub fn concrete_trait(&self, db: &dyn SemanticGroup) -> ConcreteTraitId {
279 self.lookup_intern(db).concrete_trait
280 }
281}
282
283#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject)]
285#[debug_db(dyn SemanticGroup + 'static)]
286pub struct ConcreteTraitImplLongId {
287 concrete_trait: ConcreteTraitId,
289 trait_impl: TraitImplId,
290}
291impl ConcreteTraitImplLongId {
292 pub fn new(
293 db: &dyn SemanticGroup,
294 concrete_trait: ConcreteTraitId,
295 trait_impl: TraitImplId,
296 ) -> Self {
297 assert_eq!(
298 concrete_trait.trait_id(db),
299 trait_impl.trait_id(db),
300 "Concrete trait and trait impl must belong to the same generic trait."
301 );
302 Self { concrete_trait, trait_impl }
303 }
304}
305define_short_id!(
306 ConcreteTraitImplId,
307 ConcreteTraitImplLongId,
308 SemanticGroup,
309 lookup_intern_concrete_trait_impl,
310 intern_concrete_trait_impl
311);
312semantic_object_for_id!(
313 ConcreteTraitImplId,
314 lookup_intern_concrete_trait_impl,
315 intern_concrete_trait_impl,
316 ConcreteTraitImplLongId
317);
318impl ConcreteTraitImplId {
319 pub fn new(
320 db: &dyn SemanticGroup,
321 concrete_trait: ConcreteTraitId,
322 trait_impl: TraitImplId,
323 ) -> Self {
324 ConcreteTraitImplLongId::new(db, concrete_trait, trait_impl).intern(db)
325 }
326
327 pub fn trait_impl(&self, db: &dyn SemanticGroup) -> TraitImplId {
328 self.lookup_intern(db).trait_impl
329 }
330
331 pub fn concrete_trait(&self, db: &dyn SemanticGroup) -> ConcreteTraitId {
332 self.lookup_intern(db).concrete_trait
333 }
334}
335
336#[derive(Clone, Debug, PartialEq, Eq, DebugWithDb)]
339#[debug_db(dyn SemanticGroup + 'static)]
340pub struct TraitDeclarationData {
341 diagnostics: Diagnostics<SemanticDiagnostic>,
342 generic_params: Vec<GenericParam>,
343 attributes: Vec<Attribute>,
344 resolver_data: Arc<ResolverData>,
345}
346
347pub fn trait_semantic_declaration_diagnostics(
351 db: &dyn SemanticGroup,
352 trait_id: TraitId,
353) -> Diagnostics<SemanticDiagnostic> {
354 db.priv_trait_declaration_data(trait_id).map(|data| data.diagnostics).unwrap_or_default()
355}
356
357pub fn trait_generic_params(db: &dyn SemanticGroup, trait_id: TraitId) -> Maybe<Vec<GenericParam>> {
359 Ok(db.trait_generic_params_data(trait_id, false)?.generic_params)
360}
361pub fn trait_generic_params_cycle(
363 db: &dyn SemanticGroup,
364 _cycle: &salsa::Cycle,
365 trait_id: &TraitId,
366) -> Maybe<Vec<GenericParam>> {
367 Ok(db.trait_generic_params_data(*trait_id, true)?.generic_params)
369}
370
371pub fn trait_generic_params_data(
373 db: &dyn SemanticGroup,
374 trait_id: TraitId,
375 in_cycle: bool,
376) -> Maybe<GenericParamsData> {
377 let module_file_id = trait_id.module_file_id(db);
378 let mut diagnostics = SemanticDiagnostics::default();
379 let trait_ast = db.module_trait_by_id(trait_id)?.to_maybe()?;
380
381 let inference_id =
383 InferenceId::LookupItemGenerics(LookupItemId::ModuleItem(ModuleItemId::Trait(trait_id)));
384 let mut resolver = Resolver::new(db, module_file_id, inference_id);
385 resolver.set_feature_config(&trait_id, &trait_ast, &mut diagnostics);
386 let generic_params = semantic_generic_params_ex(
387 db,
388 &mut diagnostics,
389 &mut resolver,
390 module_file_id,
391 &trait_ast.generic_params(db),
392 in_cycle,
393 );
394
395 let inference = &mut resolver.inference();
396 inference.finalize(&mut diagnostics, trait_ast.stable_ptr(db).untyped());
397
398 let generic_params = inference.rewrite(generic_params).no_err();
399 let resolver_data = Arc::new(resolver.data);
400 Ok(GenericParamsData { diagnostics: diagnostics.build(), generic_params, resolver_data })
401}
402pub fn trait_generic_params_data_cycle(
404 db: &dyn SemanticGroup,
405 _cycle: &salsa::Cycle,
406 trait_id: &TraitId,
407 _in_cycle: &bool,
408) -> Maybe<GenericParamsData> {
409 trait_generic_params_data(db, *trait_id, true)
411}
412pub fn trait_attributes(db: &dyn SemanticGroup, trait_id: TraitId) -> Maybe<Vec<Attribute>> {
414 Ok(db.priv_trait_declaration_data(trait_id)?.attributes)
415}
416
417pub fn trait_resolver_data(db: &dyn SemanticGroup, trait_id: TraitId) -> Maybe<Arc<ResolverData>> {
419 Ok(db.priv_trait_declaration_data(trait_id)?.resolver_data)
420}
421
422pub fn priv_trait_declaration_data(
426 db: &dyn SemanticGroup,
427 trait_id: TraitId,
428) -> Maybe<TraitDeclarationData> {
429 let mut diagnostics = SemanticDiagnostics::default();
430 let trait_ast = db.module_trait_by_id(trait_id)?.to_maybe()?;
434
435 let generic_params_data = db.trait_generic_params_data(trait_id, false)?;
437 let generic_params = generic_params_data.generic_params;
438 let inference_id =
439 InferenceId::LookupItemDeclaration(LookupItemId::ModuleItem(ModuleItemId::Trait(trait_id)));
440 let mut resolver = Resolver::with_data(
441 db,
442 (*generic_params_data.resolver_data).clone_with_inference_id(db, inference_id),
443 );
444 diagnostics.extend(generic_params_data.diagnostics);
445
446 let attributes = trait_ast.attributes(db).structurize(db);
447
448 let inference = &mut resolver.inference();
450 inference.finalize(&mut diagnostics, trait_ast.stable_ptr(db).untyped());
451
452 let generic_params = inference.rewrite(generic_params).no_err();
453
454 let mut resolver_data = resolver.data;
455 resolver_data.trait_or_impl_ctx = TraitOrImplContext::Trait(trait_id);
456 Ok(TraitDeclarationData {
457 diagnostics: diagnostics.build(),
458 generic_params,
459 attributes,
460 resolver_data: Arc::new(resolver_data),
461 })
462}
463
464#[derive(Clone, Debug, PartialEq, Eq, DebugWithDb)]
467#[debug_db(dyn SemanticGroup + 'static)]
468pub struct TraitDefinitionData {
469 diagnostics: Diagnostics<SemanticDiagnostic>,
474
475 function_asts: OrderedHashMap<TraitFunctionId, ast::TraitItemFunction>,
477 item_type_asts: OrderedHashMap<TraitTypeId, ast::TraitItemType>,
478 item_constant_asts: OrderedHashMap<TraitConstantId, ast::TraitItemConstant>,
479 item_impl_asts: OrderedHashMap<TraitImplId, ast::TraitItemImpl>,
480
481 item_id_by_name: Arc<OrderedHashMap<SmolStr, TraitItemInfo>>,
483}
484
485impl TraitDefinitionData {
486 pub fn get_trait_item_info(&self, item_name: &SmolStr) -> Option<TraitItemInfo> {
488 self.item_id_by_name.get(item_name).cloned()
489 }
490}
491#[derive(Clone, Debug, PartialEq, Eq)]
493pub struct TraitItemInfo {
494 pub id: TraitItemId,
496 pub feature_kind: FeatureKind,
498}
499
500impl HasFeatureKind for TraitItemInfo {
501 fn feature_kind(&self) -> &FeatureKind {
503 &self.feature_kind
504 }
505}
506
507pub fn trait_semantic_definition_diagnostics(
511 db: &dyn SemanticGroup,
512 trait_id: TraitId,
513) -> Diagnostics<SemanticDiagnostic> {
514 let mut diagnostics = DiagnosticsBuilder::default();
515
516 let Ok(data) = db.priv_trait_definition_data(trait_id) else {
517 return Diagnostics::default();
518 };
519
520 diagnostics.extend(data.diagnostics);
523 for trait_function_id in data.function_asts.keys() {
524 diagnostics.extend(db.trait_function_declaration_diagnostics(*trait_function_id));
525 diagnostics.extend(db.trait_function_body_diagnostics(*trait_function_id));
526 }
527 for trait_type_id in data.item_type_asts.keys() {
528 diagnostics.extend(db.trait_type_diagnostics(*trait_type_id));
529 }
530 for trait_constant in data.item_constant_asts.keys() {
531 diagnostics.extend(db.trait_constant_diagnostics(*trait_constant));
532 }
533 for trait_impl in data.item_impl_asts.keys() {
534 diagnostics.extend(db.trait_impl_diagnostics(*trait_impl));
535 }
536
537 diagnostics.build()
538}
539
540pub fn trait_required_item_names(
542 db: &dyn SemanticGroup,
543 trait_id: TraitId,
544) -> Maybe<OrderedHashSet<SmolStr>> {
545 let mut required_items = OrderedHashSet::<_>::default();
546 for (item_name, item_id) in db.priv_trait_definition_data(trait_id)?.item_id_by_name.iter() {
547 if match item_id.id {
548 TraitItemId::Function(id) => {
549 let body = id.stable_ptr(db).lookup(db).body(db);
550 matches!(body, ast::MaybeTraitFunctionBody::None(_))
551 }
552 TraitItemId::Type(_) | TraitItemId::Constant(_) => true,
553 TraitItemId::Impl(_) => false,
554 } {
555 required_items.insert(item_name.clone());
556 }
557 }
558 Ok(required_items)
559}
560
561pub fn trait_item_by_name(
563 db: &dyn SemanticGroup,
564 trait_id: TraitId,
565 name: SmolStr,
566) -> Maybe<Option<TraitItemId>> {
567 Ok(db.priv_trait_definition_data(trait_id)?.item_id_by_name.get(&name).map(|info| info.id))
568}
569
570pub fn trait_item_info_by_name(
572 db: &dyn SemanticGroup,
573 trait_id: TraitId,
574 name: SmolStr,
575) -> Maybe<Option<TraitItemInfo>> {
576 let trait_definition_data = db.priv_trait_definition_data(trait_id)?;
577 Ok(trait_definition_data.get_trait_item_info(&name))
578}
579
580pub fn trait_all_used_uses(
582 db: &dyn SemanticGroup,
583 trait_id: TraitId,
584) -> Maybe<Arc<OrderedHashSet<UseId>>> {
585 let mut all_used_uses = db.trait_resolver_data(trait_id)?.used_uses.clone();
586 let data = db.priv_trait_definition_data(trait_id)?;
587 for item in data.item_id_by_name.values() {
588 for resolver_data in get_resolver_data_options(LookupItemId::TraitItem(item.id), db) {
589 all_used_uses.extend(resolver_data.used_uses.iter().cloned());
590 }
591 }
592 Ok(all_used_uses.into())
593}
594
595pub fn trait_functions(
597 db: &dyn SemanticGroup,
598 trait_id: TraitId,
599) -> Maybe<OrderedHashMap<SmolStr, TraitFunctionId>> {
600 Ok(db
601 .priv_trait_definition_data(trait_id)?
602 .function_asts
603 .keys()
604 .map(|function_id| {
605 let function_long_id = function_id.lookup_intern(db);
606 (function_long_id.name(db), *function_id)
607 })
608 .collect())
609}
610
611pub fn trait_function_by_name(
613 db: &dyn SemanticGroup,
614 trait_id: TraitId,
615 name: SmolStr,
616) -> Maybe<Option<TraitFunctionId>> {
617 Ok(db.trait_functions(trait_id)?.get(&name).copied())
618}
619
620pub fn trait_types(
622 db: &dyn SemanticGroup,
623 trait_id: TraitId,
624) -> Maybe<OrderedHashMap<SmolStr, TraitTypeId>> {
625 Ok(db
626 .priv_trait_definition_data(trait_id)?
627 .item_type_asts
628 .keys()
629 .map(|type_id| {
630 let type_long_id = type_id.lookup_intern(db);
631 (type_long_id.name(db), *type_id)
632 })
633 .collect())
634}
635
636pub fn trait_type_by_name(
638 db: &dyn SemanticGroup,
639 trait_id: TraitId,
640 name: SmolStr,
641) -> Maybe<Option<TraitTypeId>> {
642 Ok(db.trait_types(trait_id)?.get(&name).copied())
643}
644
645pub fn trait_constants(
647 db: &dyn SemanticGroup,
648 trait_id: TraitId,
649) -> Maybe<OrderedHashMap<SmolStr, TraitConstantId>> {
650 Ok(db
651 .priv_trait_definition_data(trait_id)?
652 .item_constant_asts
653 .keys()
654 .map(|constant_id| {
655 let constant_long_id = constant_id.lookup_intern(db);
656 (constant_long_id.name(db), *constant_id)
657 })
658 .collect())
659}
660
661pub fn trait_constant_by_name(
663 db: &dyn SemanticGroup,
664 trait_id: TraitId,
665 name: SmolStr,
666) -> Maybe<Option<TraitConstantId>> {
667 Ok(db.trait_constants(trait_id)?.get(&name).copied())
668}
669
670pub fn trait_impls(
672 db: &dyn SemanticGroup,
673 trait_id: TraitId,
674) -> Maybe<OrderedHashMap<SmolStr, TraitImplId>> {
675 Ok(db
676 .priv_trait_definition_data(trait_id)?
677 .item_impl_asts
678 .keys()
679 .map(|impl_id| {
680 let impl_long_id = impl_id.lookup_intern(db);
681 (impl_long_id.name(db), *impl_id)
682 })
683 .collect())
684}
685
686pub fn trait_impl_by_name(
688 db: &dyn SemanticGroup,
689 trait_id: TraitId,
690 name: SmolStr,
691) -> Maybe<Option<TraitImplId>> {
692 Ok(db.trait_impls(trait_id)?.get(&name).copied())
693}
694
695pub fn priv_trait_definition_data(
699 db: &dyn SemanticGroup,
700 trait_id: TraitId,
701) -> Maybe<TraitDefinitionData> {
702 let module_file_id = trait_id.module_file_id(db);
703 let mut diagnostics = SemanticDiagnostics::default();
704
705 let trait_ast = db.module_trait_by_id(trait_id)?.to_maybe()?;
709
710 let mut function_asts = OrderedHashMap::default();
711 let mut item_type_asts = OrderedHashMap::default();
712 let mut item_constant_asts = OrderedHashMap::default();
713 let mut item_impl_asts = OrderedHashMap::default();
714 let mut item_id_by_name: OrderedHashMap<SmolStr, TraitItemInfo> = OrderedHashMap::default();
715
716 if let ast::MaybeTraitBody::Some(body) = trait_ast.body(db) {
717 for item in body.items(db).elements(db) {
718 match item {
719 ast::TraitItem::Function(func) => {
720 let trait_func_id =
721 TraitFunctionLongId(module_file_id, func.stable_ptr(db)).intern(db);
722 let name_node = func.declaration(db).name(db);
723 let name = name_node.text(db);
724 let attributes = func.attributes(db);
725 let feature_kind = FeatureKind::from_ast(db, &mut diagnostics, &attributes);
726 if item_id_by_name
727 .insert(
728 name.clone(),
729 TraitItemInfo {
730 id: TraitItemId::Function(trait_func_id),
731 feature_kind,
732 },
733 )
734 .is_some()
735 {
736 diagnostics.report(
737 name_node.stable_ptr(db),
738 SemanticDiagnosticKind::NameDefinedMultipleTimes(name),
739 );
740 }
741 function_asts.insert(trait_func_id, func);
742 }
743 ast::TraitItem::Type(ty) => {
744 let trait_type_id =
745 TraitTypeLongId(module_file_id, ty.stable_ptr(db)).intern(db);
746 let name_node = ty.name(db);
747 let name = name_node.text(db);
748 let attributes = ty.attributes(db);
749 let feature_kind = FeatureKind::from_ast(db, &mut diagnostics, &attributes);
750 if item_id_by_name
751 .insert(
752 name.clone(),
753 TraitItemInfo { id: TraitItemId::Type(trait_type_id), feature_kind },
754 )
755 .is_some()
756 {
757 diagnostics.report(
758 name_node.stable_ptr(db),
759 SemanticDiagnosticKind::NameDefinedMultipleTimes(name),
760 );
761 }
762 item_type_asts.insert(trait_type_id, ty);
763 }
764 ast::TraitItem::Constant(constant) => {
765 let trait_constant =
766 TraitConstantLongId(module_file_id, constant.stable_ptr(db)).intern(db);
767
768 let name_node = constant.name(db);
769 let name = name_node.text(db);
770 let attributes = constant.attributes(db);
771 let feature_kind = FeatureKind::from_ast(db, &mut diagnostics, &attributes);
772 if item_id_by_name
773 .insert(
774 name.clone(),
775 TraitItemInfo {
776 id: TraitItemId::Constant(trait_constant),
777 feature_kind,
778 },
779 )
780 .is_some()
781 {
782 diagnostics.report(
783 name_node.stable_ptr(db),
784 SemanticDiagnosticKind::NameDefinedMultipleTimes(name),
785 );
786 }
787 item_constant_asts.insert(trait_constant, constant);
788 }
789 ast::TraitItem::Impl(imp) => {
790 let trait_impl = TraitImplLongId(module_file_id, imp.stable_ptr(db)).intern(db);
791
792 let name_node = imp.name(db);
793 let name = name_node.text(db);
794 let attributes = imp.attributes(db);
795 let feature_kind = FeatureKind::from_ast(db, &mut diagnostics, &attributes);
796 if item_id_by_name
797 .insert(
798 name.clone(),
799 TraitItemInfo { id: TraitItemId::Impl(trait_impl), feature_kind },
800 )
801 .is_some()
802 {
803 diagnostics.report(
804 name_node.stable_ptr(db),
805 SemanticDiagnosticKind::NameDefinedMultipleTimes(name),
806 );
807 }
808 item_impl_asts.insert(trait_impl, imp);
809 }
810 ast::TraitItem::Missing(_) => {}
811 }
812 }
813 }
814
815 Ok(TraitDefinitionData {
816 diagnostics: diagnostics.build(),
817 function_asts,
818 item_type_asts,
819 item_constant_asts,
820 item_impl_asts,
821 item_id_by_name: Arc::new(item_id_by_name),
822 })
823}
824
825#[derive(Clone, Debug, PartialEq, Eq, DebugWithDb)]
828#[debug_db(dyn SemanticGroup + 'static)]
829pub struct TraitItemTypeData {
830 pub diagnostics: Diagnostics<SemanticDiagnostic>,
831 pub generic_params: Vec<semantic::GenericParam>,
832 pub attributes: Vec<Attribute>,
833 pub resolver_data: Arc<ResolverData>,
834}
835
836pub fn trait_type_diagnostics(
840 db: &dyn SemanticGroup,
841 trait_type_id: TraitTypeId,
842) -> Diagnostics<SemanticDiagnostic> {
843 db.priv_trait_type_data(trait_type_id).map(|data| data.diagnostics).unwrap_or_default()
844}
845
846pub fn trait_type_generic_params(
848 db: &dyn SemanticGroup,
849 trait_type_id: TraitTypeId,
850) -> Maybe<Vec<GenericParam>> {
851 Ok(db.priv_trait_type_generic_params_data(trait_type_id)?.generic_params)
852}
853
854pub fn trait_type_attributes(
856 db: &dyn SemanticGroup,
857 trait_type_id: TraitTypeId,
858) -> Maybe<Vec<Attribute>> {
859 Ok(db.priv_trait_type_data(trait_type_id)?.attributes)
860}
861
862pub fn trait_type_resolver_data(
864 db: &dyn SemanticGroup,
865 trait_type_id: TraitTypeId,
866) -> Maybe<Arc<ResolverData>> {
867 Ok(db.priv_trait_type_data(trait_type_id)?.resolver_data)
868}
869
870pub fn priv_trait_type_generic_params_data(
874 db: &dyn SemanticGroup,
875 trait_type_id: TraitTypeId,
876) -> Maybe<GenericParamsData> {
877 let module_file_id = trait_type_id.module_file_id(db);
878 let mut diagnostics = SemanticDiagnostics::default();
879 let trait_id = trait_type_id.trait_id(db);
880 let data = db.priv_trait_definition_data(trait_id)?;
881 let trait_type_ast = &data.item_type_asts[&trait_type_id];
882 let inference_id =
883 InferenceId::LookupItemGenerics(LookupItemId::TraitItem(TraitItemId::Type(trait_type_id)));
884 let parent_resolver_data = db.trait_resolver_data(trait_id)?;
885 let mut resolver =
886 Resolver::with_data(db, parent_resolver_data.clone_with_inference_id(db, inference_id));
887 for trait_generic_param in db.trait_generic_params(trait_id)? {
888 resolver.add_generic_param(trait_generic_param.id());
889 }
890 let generic_params_node = trait_type_ast.generic_params(db);
891 let type_generic_params = semantic_generic_params(
892 db,
893 &mut diagnostics,
894 &mut resolver,
895 module_file_id,
896 &generic_params_node,
897 );
898 let type_generic_params = resolver.inference().rewrite(type_generic_params).no_err();
899
900 if !generic_params_node.is_empty(db) {
903 diagnostics.report(
904 generic_params_node.stable_ptr(db),
905 GenericsNotSupportedInItem { scope: "Trait".into(), item_kind: "type".into() },
906 );
907 }
908
909 let resolver_data = Arc::new(resolver.data);
910 Ok(GenericParamsData {
911 diagnostics: diagnostics.build(),
912 generic_params: type_generic_params,
913 resolver_data,
914 })
915}
916
917pub fn priv_trait_type_data(
919 db: &dyn SemanticGroup,
920 trait_type_id: TraitTypeId,
921) -> Maybe<TraitItemTypeData> {
922 let mut diagnostics = SemanticDiagnostics::default();
923 let trait_id = trait_type_id.trait_id(db);
924 let data = db.priv_trait_definition_data(trait_id)?;
925 let type_syntax = &data.item_type_asts[&trait_type_id];
926
927 let type_generic_params_data = db.priv_trait_type_generic_params_data(trait_type_id)?;
928 let type_generic_params = type_generic_params_data.generic_params;
929 let inference_id = InferenceId::LookupItemDeclaration(LookupItemId::TraitItem(
930 TraitItemId::Type(trait_type_id),
931 ));
932 let resolver = Resolver::with_data(
933 db,
934 (*type_generic_params_data.resolver_data).clone_with_inference_id(db, inference_id),
935 );
936 diagnostics.extend(type_generic_params_data.diagnostics);
937
938 let attributes = type_syntax.attributes(db).structurize(db);
939 let resolver_data = Arc::new(resolver.data);
940
941 Ok(TraitItemTypeData {
942 diagnostics: diagnostics.build(),
943 generic_params: type_generic_params,
944 attributes,
945 resolver_data,
946 })
947}
948
949#[derive(Clone, Debug, PartialEq, Eq, DebugWithDb)]
952#[debug_db(dyn SemanticGroup + 'static)]
953pub struct TraitItemConstantData {
954 pub diagnostics: Diagnostics<SemanticDiagnostic>,
955 pub ty: TypeId,
956 pub attributes: Vec<Attribute>,
957 pub resolver_data: Arc<ResolverData>,
958}
959
960pub fn trait_constant_diagnostics(
964 db: &dyn SemanticGroup,
965 trait_constant: TraitConstantId,
966) -> Diagnostics<SemanticDiagnostic> {
967 db.priv_trait_constant_data(trait_constant).map(|data| data.diagnostics).unwrap_or_default()
968}
969
970pub fn trait_constant_resolver_data(
972 db: &dyn SemanticGroup,
973 trait_constant: TraitConstantId,
974) -> Maybe<Arc<ResolverData>> {
975 Ok(db.priv_trait_constant_data(trait_constant)?.resolver_data)
976}
977
978pub fn trait_constant_attributes(
980 db: &dyn SemanticGroup,
981 trait_constant: TraitConstantId,
982) -> Maybe<Vec<Attribute>> {
983 Ok(db.priv_trait_constant_data(trait_constant)?.attributes)
984}
985
986pub fn trait_constant_type(
988 db: &dyn SemanticGroup,
989 trait_constant_id: TraitConstantId,
990) -> Maybe<TypeId> {
991 Ok(db.priv_trait_constant_data(trait_constant_id)?.ty)
992}
993
994pub fn priv_trait_constant_data(
998 db: &dyn SemanticGroup,
999 trait_constant: TraitConstantId,
1000) -> Maybe<TraitItemConstantData> {
1001 let mut diagnostics = SemanticDiagnostics::default();
1002 let trait_id = trait_constant.trait_id(db);
1003 let data = db.priv_trait_definition_data(trait_id)?;
1004 let constant_syntax = &data.item_constant_asts[&trait_constant];
1005 let inference_id = InferenceId::LookupItemDeclaration(LookupItemId::TraitItem(
1006 TraitItemId::Constant(trait_constant),
1007 ));
1008 let parent_resolver_data = db.trait_resolver_data(trait_id)?;
1009 let mut resolver =
1010 Resolver::with_data(db, parent_resolver_data.clone_with_inference_id(db, inference_id));
1011
1012 let ty =
1013 resolve_type(db, &mut diagnostics, &mut resolver, &constant_syntax.type_clause(db).ty(db));
1014 let attributes = constant_syntax.attributes(db).structurize(db);
1015 let resolver_data = Arc::new(resolver.data);
1016
1017 Ok(TraitItemConstantData { diagnostics: diagnostics.build(), ty, attributes, resolver_data })
1018}
1019
1020pub fn concrete_trait_constant_type(
1022 db: &dyn SemanticGroup,
1023 concrete_trait_constant_id: ConcreteTraitConstantId,
1024) -> Maybe<TypeId> {
1025 let concrete_trait_id = concrete_trait_constant_id.concrete_trait(db);
1026 let substitution = GenericSubstitution::new(
1027 &db.trait_generic_params(concrete_trait_id.trait_id(db))?,
1028 &concrete_trait_id.generic_args(db),
1029 );
1030 let generic_ty = db.trait_constant_type(concrete_trait_constant_id.trait_constant(db))?;
1031 substitution.substitute(db, generic_ty)
1032}
1033
1034#[derive(Clone, Debug, PartialEq, Eq, DebugWithDb)]
1037#[debug_db(dyn SemanticGroup + 'static)]
1038pub struct TraitItemImplData {
1039 pub diagnostics: Diagnostics<SemanticDiagnostic>,
1040 pub concrete_trait: Maybe<ConcreteTraitId>,
1041 pub attributes: Vec<Attribute>,
1042 pub resolver_data: Arc<ResolverData>,
1043}
1044
1045pub fn trait_impl_diagnostics(
1049 db: &dyn SemanticGroup,
1050 trait_impl: TraitImplId,
1051) -> Diagnostics<SemanticDiagnostic> {
1052 db.priv_trait_impl_data(trait_impl).map(|data| data.diagnostics).unwrap_or_default()
1053}
1054
1055pub fn trait_impl_resolver_data(
1057 db: &dyn SemanticGroup,
1058 trait_impl: TraitImplId,
1059) -> Maybe<Arc<ResolverData>> {
1060 Ok(db.priv_trait_impl_data(trait_impl)?.resolver_data)
1061}
1062
1063pub fn trait_impl_attributes(
1065 db: &dyn SemanticGroup,
1066 trait_impl: TraitImplId,
1067) -> Maybe<Vec<Attribute>> {
1068 Ok(db.priv_trait_impl_data(trait_impl)?.attributes)
1069}
1070
1071pub fn trait_impl_concrete_trait(
1073 db: &dyn SemanticGroup,
1074 trait_impl_id: TraitImplId,
1075) -> Maybe<ConcreteTraitId> {
1076 db.priv_trait_impl_data(trait_impl_id)?.concrete_trait
1077}
1078
1079pub fn priv_trait_impl_data(
1083 db: &dyn SemanticGroup,
1084 trait_impl: TraitImplId,
1085) -> Maybe<TraitItemImplData> {
1086 let mut diagnostics = SemanticDiagnostics::default();
1087 let trait_id = trait_impl.trait_id(db);
1088 let data = db.priv_trait_definition_data(trait_id)?;
1089 let impl_syntax = &data.item_impl_asts[&trait_impl];
1090 let trait_path = impl_syntax.trait_path(db);
1091 let inference_id =
1092 InferenceId::LookupItemDeclaration(LookupItemId::TraitItem(TraitItemId::Impl(trait_impl)));
1093 let parent_resolver_data = db.trait_resolver_data(trait_id)?;
1094 let mut resolver =
1095 Resolver::with_data(db, parent_resolver_data.clone_with_inference_id(db, inference_id));
1096 let concrete_trait =
1097 resolver
1098 .resolve_concrete_path(&mut diagnostics, &trait_path, NotFoundItemType::Trait)
1099 .and_then(|resolved_item: crate::resolve::ResolvedConcreteItem| match resolved_item {
1100 ResolvedConcreteItem::Trait(id) | ResolvedConcreteItem::SelfTrait(id) => Ok(id),
1101 _ => Err(diagnostics
1102 .report(trait_path.stable_ptr(db), SemanticDiagnosticKind::UnknownTrait)),
1103 });
1104 let attributes = impl_syntax.attributes(db).structurize(db);
1105 let resolver_data = Arc::new(resolver.data);
1106
1107 Ok(TraitItemImplData {
1108 diagnostics: diagnostics.build(),
1109 concrete_trait,
1110 attributes,
1111 resolver_data,
1112 })
1113}
1114
1115pub fn concrete_trait_impl_concrete_trait(
1117 db: &dyn SemanticGroup,
1118 concrete_trait_impl_id: ConcreteTraitImplId,
1119) -> Maybe<ConcreteTraitId> {
1120 let concrete_trait_id = concrete_trait_impl_id.concrete_trait(db);
1121 GenericSubstitution::new(
1122 &db.trait_generic_params(concrete_trait_id.trait_id(db))?,
1123 &concrete_trait_id.generic_args(db),
1124 )
1125 .substitute(db, db.trait_impl_concrete_trait(concrete_trait_impl_id.trait_impl(db))?)
1126}
1127
1128pub fn trait_function_declaration_diagnostics(
1134 db: &dyn SemanticGroup,
1135 trait_function_id: TraitFunctionId,
1136) -> Diagnostics<SemanticDiagnostic> {
1137 db.priv_trait_function_declaration_data(trait_function_id)
1138 .map(|data| data.diagnostics)
1139 .unwrap_or_default()
1140}
1141
1142pub fn trait_function_signature(
1144 db: &dyn SemanticGroup,
1145 trait_function_id: TraitFunctionId,
1146) -> Maybe<semantic::Signature> {
1147 Ok(db.priv_trait_function_declaration_data(trait_function_id)?.signature)
1148}
1149
1150pub fn trait_function_generic_params(
1152 db: &dyn SemanticGroup,
1153 trait_function_id: TraitFunctionId,
1154) -> Maybe<Vec<GenericParam>> {
1155 Ok(db.priv_trait_function_generic_params_data(trait_function_id)?.generic_params)
1156}
1157
1158pub fn priv_trait_function_generic_params_data(
1160 db: &dyn SemanticGroup,
1161 trait_function_id: TraitFunctionId,
1162) -> Maybe<GenericParamsData> {
1163 let module_file_id = trait_function_id.module_file_id(db);
1164 let mut diagnostics = SemanticDiagnostics::default();
1165 let trait_id = trait_function_id.trait_id(db);
1166 let data = db.priv_trait_definition_data(trait_id)?;
1167 let function_syntax = &data.function_asts[&trait_function_id];
1168 let declaration = function_syntax.declaration(db);
1169 let inference_id = InferenceId::LookupItemGenerics(LookupItemId::TraitItem(
1170 TraitItemId::Function(trait_function_id),
1171 ));
1172 let parent_resolver_data = db.trait_resolver_data(trait_id)?;
1173 let mut resolver =
1174 Resolver::with_data(db, parent_resolver_data.clone_with_inference_id(db, inference_id));
1175 let trait_generic_params = db.trait_generic_params(trait_id)?;
1176 for generic_param in trait_generic_params {
1177 resolver.add_generic_param(generic_param.id());
1178 }
1179 let function_generic_params = semantic_generic_params(
1180 db,
1181 &mut diagnostics,
1182 &mut resolver,
1183 module_file_id,
1184 &declaration.generic_params(db),
1185 );
1186 let function_generic_params = resolver.inference().rewrite(function_generic_params).no_err();
1187 let resolver_data = Arc::new(resolver.data);
1188 Ok(GenericParamsData {
1189 diagnostics: diagnostics.build(),
1190 generic_params: function_generic_params,
1191 resolver_data,
1192 })
1193}
1194
1195pub fn trait_function_attributes(
1197 db: &dyn SemanticGroup,
1198 trait_function_id: TraitFunctionId,
1199) -> Maybe<Vec<Attribute>> {
1200 Ok(db.priv_trait_function_declaration_data(trait_function_id)?.attributes)
1201}
1202
1203pub fn trait_function_resolver_data(
1205 db: &dyn SemanticGroup,
1206 trait_function_id: TraitFunctionId,
1207) -> Maybe<Arc<ResolverData>> {
1208 Ok(db.priv_trait_function_declaration_data(trait_function_id)?.resolver_data)
1209}
1210
1211pub fn trait_function_declaration_inline_config(
1213 db: &dyn SemanticGroup,
1214 trait_function_id: TraitFunctionId,
1215) -> Maybe<InlineConfiguration> {
1216 Ok(db.priv_trait_function_declaration_data(trait_function_id)?.inline_config)
1217}
1218
1219pub fn trait_function_declaration_implicit_precedence(
1221 db: &dyn SemanticGroup,
1222 trait_function_id: TraitFunctionId,
1223) -> Maybe<ImplicitPrecedence> {
1224 Ok(db.priv_trait_function_declaration_data(trait_function_id)?.implicit_precedence)
1225}
1226
1227pub fn trait_function_declaration_implicits(
1229 db: &dyn SemanticGroup,
1230 trait_function_id: TraitFunctionId,
1231) -> Maybe<Vec<TypeId>> {
1232 Ok(db.priv_trait_function_declaration_data(trait_function_id)?.signature.implicits)
1233}
1234
1235pub fn priv_trait_function_declaration_data(
1239 db: &dyn SemanticGroup,
1240 trait_function_id: TraitFunctionId,
1241) -> Maybe<FunctionDeclarationData> {
1242 let mut diagnostics = SemanticDiagnostics::default();
1243 let trait_id = trait_function_id.trait_id(db);
1244 let data = db.priv_trait_definition_data(trait_id)?;
1245 let function_syntax = &data.function_asts[&trait_function_id];
1246 let declaration_syntax = function_syntax.declaration(db);
1247 let function_generic_params_data =
1248 db.priv_trait_function_generic_params_data(trait_function_id)?;
1249 let function_generic_params = function_generic_params_data.generic_params;
1250 let lookup_item_id = LookupItemId::TraitItem(TraitItemId::Function(trait_function_id));
1251 let inference_id = InferenceId::LookupItemDeclaration(lookup_item_id);
1252 let mut resolver = Resolver::with_data(
1253 db,
1254 (*function_generic_params_data.resolver_data).clone_with_inference_id(db, inference_id),
1255 );
1256 diagnostics.extend(function_generic_params_data.diagnostics);
1257 resolver.set_feature_config(&trait_function_id, function_syntax, &mut diagnostics);
1258 let mut environment = Environment::empty();
1259 let signature = semantic::Signature::from_ast(
1260 &mut diagnostics,
1261 db,
1262 &mut resolver,
1263 &declaration_syntax,
1264 FunctionTitleId::Trait(trait_function_id),
1265 &mut environment,
1266 );
1267
1268 let inference = &mut resolver.inference();
1270 inference.finalize(&mut diagnostics, function_syntax.stable_ptr(db).untyped());
1271 let signature = inference.rewrite(signature).no_err();
1272 let function_generic_params = inference.rewrite(function_generic_params).no_err();
1273
1274 validate_trait_function_signature(
1275 db,
1276 &mut diagnostics,
1277 trait_id,
1278 trait_function_id,
1279 &signature,
1280 );
1281
1282 let attributes = function_syntax.attributes(db).structurize(db);
1283
1284 let inline_config = get_inline_config(db, &mut diagnostics, &attributes)?;
1285 let (implicit_precedence, _) =
1286 get_implicit_precedence(db, &mut diagnostics, &mut resolver, &attributes);
1287 let resolver_data = Arc::new(resolver.data);
1288
1289 Ok(FunctionDeclarationData {
1290 diagnostics: diagnostics.build(),
1291 signature,
1292 generic_params: function_generic_params,
1293 environment,
1294 attributes,
1295 resolver_data,
1296 inline_config,
1297 implicit_precedence,
1298 })
1299}
1300
1301fn validate_trait_function_signature(
1302 db: &dyn SemanticGroup,
1303 diagnostics: &mut SemanticDiagnostics,
1304 trait_id: TraitId,
1305 function_id: TraitFunctionId,
1306 sig: &semantic::Signature,
1307) {
1308 for param in &sig.params {
1309 if param.mutability == Mutability::Mutable {
1310 diagnostics.report(
1311 param.stable_ptr(db).lookup(db).modifiers(db).stable_ptr(db),
1312 crate::diagnostic::SemanticDiagnosticKind::TraitParamMutable {
1313 trait_id,
1314 function_id,
1315 },
1316 );
1317 }
1318 }
1319}
1320
1321pub fn concrete_trait_function_generic_params(
1325 db: &dyn SemanticGroup,
1326 concrete_trait_function_id: ConcreteTraitGenericFunctionId,
1327) -> Maybe<Vec<GenericParam>> {
1328 let concrete_trait_id = concrete_trait_function_id.concrete_trait(db);
1329 GenericSubstitution::new(
1330 &db.trait_generic_params(concrete_trait_id.trait_id(db))?,
1331 &concrete_trait_id.generic_args(db),
1332 )
1333 .substitute(
1334 db,
1335 db.trait_function_generic_params(concrete_trait_function_id.trait_function(db))?,
1336 )
1337}
1338
1339pub fn concrete_trait_function_signature(
1341 db: &dyn SemanticGroup,
1342 concrete_trait_function_id: ConcreteTraitGenericFunctionId,
1343) -> Maybe<semantic::Signature> {
1344 let concrete_trait_id = concrete_trait_function_id.concrete_trait(db);
1345 GenericSubstitution::new(
1346 &db.trait_generic_params(concrete_trait_id.trait_id(db))?,
1347 &concrete_trait_id.generic_args(db),
1348 )
1349 .substitute(db, db.trait_function_signature(concrete_trait_function_id.trait_function(db))?)
1350}
1351
1352pub fn trait_function_body_diagnostics(
1358 db: &dyn SemanticGroup,
1359 trait_function_id: TraitFunctionId,
1360) -> Diagnostics<SemanticDiagnostic> {
1361 db.priv_trait_function_body_data(trait_function_id)
1362 .map(|data| match data {
1363 Some(data) => data.diagnostics,
1364 None => Diagnostics::<SemanticDiagnostic>::new(),
1365 })
1366 .unwrap_or_default()
1367}
1368
1369pub fn trait_function_body(
1371 db: &dyn SemanticGroup,
1372 trait_function_id: TraitFunctionId,
1373) -> Maybe<Option<Arc<FunctionBody>>> {
1374 Ok(match db.priv_trait_function_body_data(trait_function_id)? {
1375 Some(body_data) => Some(body_data.body),
1376 None => None,
1377 })
1378}
1379
1380pub fn priv_trait_function_body_data(
1384 db: &dyn SemanticGroup,
1385 trait_function_id: TraitFunctionId,
1386) -> Maybe<Option<FunctionBodyData>> {
1387 let mut diagnostics = SemanticDiagnostics::default();
1388 let trait_id = trait_function_id.trait_id(db);
1389 let data = db.priv_trait_definition_data(trait_id)?;
1390 let function_syntax = &data.function_asts[&trait_function_id];
1391 let trait_function_declaration_data =
1393 db.priv_trait_function_declaration_data(trait_function_id)?;
1394 let parent_resolver_data = trait_function_declaration_data.resolver_data;
1395 let inference_id = InferenceId::LookupItemDefinition(LookupItemId::TraitItem(
1396 TraitItemId::Function(trait_function_id),
1397 ));
1398 let mut resolver =
1399 Resolver::with_data(db, (*parent_resolver_data).clone_with_inference_id(db, inference_id));
1400 resolver.trait_or_impl_ctx = TraitOrImplContext::Trait(trait_id);
1401 let environment = trait_function_declaration_data.environment;
1402
1403 let function_id = (|| {
1404 let generic_parameters = db.trait_generic_params(trait_id)?;
1405 let concrete_trait = ConcreteTraitLongId {
1406 trait_id,
1407 generic_args: generic_params_to_args(&generic_parameters, db),
1408 }
1409 .intern(db);
1410 let generic_function = GenericFunctionId::Impl(ImplGenericFunctionId {
1411 impl_id: ImplLongId::SelfImpl(concrete_trait).intern(db),
1412 function: trait_function_id,
1413 });
1414
1415 Ok(FunctionLongId::from_generic(db, generic_function)?.intern(db))
1416 })();
1417 let mut ctx = ComputationContext::new(
1419 db,
1420 &mut diagnostics,
1421 resolver,
1422 Some(&trait_function_declaration_data.signature),
1423 environment,
1424 ContextFunction::Function(function_id),
1425 );
1426 let function_body = match function_syntax.body(db) {
1427 ast::MaybeTraitFunctionBody::Some(expr_block) => expr_block,
1428 ast::MaybeTraitFunctionBody::None(_) => return Ok(None),
1429 };
1430 let return_type = trait_function_declaration_data.signature.return_type;
1431 let body_expr = compute_root_expr(&mut ctx, &function_body, return_type)?;
1432 let ComputationContext { arenas: Arenas { exprs, patterns, statements }, resolver, .. } = ctx;
1433
1434 let expr_lookup: UnorderedHashMap<_, _> =
1435 exprs.iter().map(|(expr_id, expr)| (expr.stable_ptr(), expr_id)).collect();
1436 let pattern_lookup: UnorderedHashMap<_, _> =
1437 patterns.iter().map(|(pattern_id, pattern)| (pattern.stable_ptr(), pattern_id)).collect();
1438 let resolver_data = Arc::new(resolver.data);
1439 Ok(Some(FunctionBodyData {
1440 diagnostics: diagnostics.build(),
1441 expr_lookup,
1442 pattern_lookup,
1443 resolver_data,
1444 body: Arc::new(FunctionBody { arenas: Arenas { exprs, patterns, statements }, body_expr }),
1445 }))
1446}