cairo_lang_semantic/items/
imp.rs

1use std::collections::BTreeSet;
2use std::hash::Hash;
3use std::sync::Arc;
4use std::{mem, panic, vec};
5
6use cairo_lang_debug::DebugWithDb;
7use cairo_lang_defs::ids::{
8    FunctionTitleId, GenericKind, GenericParamId, ImplAliasId, ImplConstantDefId,
9    ImplConstantDefLongId, ImplDefId, ImplFunctionId, ImplFunctionLongId, ImplImplDefId,
10    ImplImplDefLongId, ImplItemId, ImplTypeDefId, ImplTypeDefLongId, LanguageElementId,
11    LookupItemId, ModuleId, ModuleItemId, NamedLanguageElementId, NamedLanguageElementLongId,
12    TopLevelLanguageElementId, TraitConstantId, TraitFunctionId, TraitId, TraitImplId, TraitTypeId,
13};
14use cairo_lang_diagnostics::{
15    DiagnosticAdded, Diagnostics, DiagnosticsBuilder, Maybe, ToMaybe, ToOption, skip_diagnostic,
16};
17use cairo_lang_filesystem::ids::UnstableSalsaId;
18use cairo_lang_proc_macros::{DebugWithDb, SemanticObject};
19use cairo_lang_syntax as syntax;
20use cairo_lang_syntax::node::ast::OptionTypeClause;
21use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
22use cairo_lang_utils::ordered_hash_set::OrderedHashSet;
23use cairo_lang_utils::unordered_hash_map::UnorderedHashMap;
24use cairo_lang_utils::{
25    Intern, LookupIntern, define_short_id, extract_matches, try_extract_matches,
26};
27use itertools::{Itertools, chain, izip};
28use smol_str::SmolStr;
29use syntax::attribute::structured::{Attribute, AttributeListStructurize};
30use syntax::node::ast::{self, GenericArg, ImplItem, MaybeImplBody, OptionReturnTypeClause};
31use syntax::node::db::SyntaxGroup;
32use syntax::node::helpers::OptionWrappedGenericParamListHelper;
33use syntax::node::ids::SyntaxStablePtrId;
34use syntax::node::{Terminal, TypedStablePtr, TypedSyntaxNode};
35
36use super::constant::{
37    ConstValue, ConstValueId, ConstantData, ImplConstantId, constant_semantic_data_cycle_helper,
38    constant_semantic_data_helper,
39};
40use super::enm::SemanticEnumEx;
41use super::function_with_body::{FunctionBody, FunctionBodyData, get_inline_config};
42use super::functions::{
43    FunctionDeclarationData, GenericFunctionId, ImplGenericFunctionId, InlineConfiguration,
44    forbid_inline_always_with_impl_generic_param,
45};
46use super::generics::{
47    GenericArgumentHead, GenericParamImpl, GenericParamsData, generic_params_to_args,
48    semantic_generic_params,
49};
50use super::impl_alias::{
51    ImplAliasData, impl_alias_generic_params_data_helper, impl_alias_semantic_data_cycle_helper,
52    impl_alias_semantic_data_helper,
53};
54use super::trt::{
55    ConcreteTraitConstantId, ConcreteTraitGenericFunctionId, ConcreteTraitGenericFunctionLongId,
56    ConcreteTraitImplId,
57};
58use super::type_aliases::{
59    TypeAliasData, type_alias_generic_params_data_helper, type_alias_semantic_data_cycle_helper,
60    type_alias_semantic_data_helper,
61};
62use super::visibility::peek_visible_in;
63use super::{TraitOrImplContext, resolve_trait_path};
64use crate::corelib::{
65    CoreTraitContext, concrete_destruct_trait, concrete_drop_trait, copy_trait, core_crate,
66    deref_trait, destruct_trait, drop_trait, fn_once_trait, fn_trait, get_core_trait,
67    panic_destruct_trait,
68};
69use crate::db::{SemanticGroup, get_resolver_data_options};
70use crate::diagnostic::SemanticDiagnosticKind::{self, *};
71use crate::diagnostic::{NotFoundItemType, SemanticDiagnostics, SemanticDiagnosticsBuilder};
72use crate::expr::compute::{ComputationContext, ContextFunction, Environment, compute_root_expr};
73use crate::expr::inference::canonic::ResultNoErrEx;
74use crate::expr::inference::conform::InferenceConform;
75use crate::expr::inference::infers::InferenceEmbeddings;
76use crate::expr::inference::solver::SolutionSet;
77use crate::expr::inference::{
78    ImplVarId, ImplVarTraitItemMappings, Inference, InferenceError, InferenceId,
79};
80use crate::items::function_with_body::get_implicit_precedence;
81use crate::items::functions::ImplicitPrecedence;
82use crate::items::us::SemanticUseEx;
83use crate::resolve::{ResolvedConcreteItem, ResolvedGenericItem, Resolver, ResolverData};
84use crate::substitution::{GenericSubstitution, SemanticRewriter, SubstitutionRewriter};
85use crate::types::{ImplTypeId, add_type_based_diagnostics, get_impl_at_context, resolve_type};
86use crate::{
87    Arenas, ConcreteFunction, ConcreteTraitId, ConcreteTraitLongId, FunctionId, FunctionLongId,
88    GenericArgumentId, GenericParam, Mutability, SemanticDiagnostic, TypeId, TypeLongId, semantic,
89    semantic_object_for_id,
90};
91
92#[cfg(test)]
93#[path = "imp_test.rs"]
94mod test;
95
96#[derive(Clone, Debug, Hash, PartialEq, Eq, SemanticObject)]
97pub struct ConcreteImplLongId {
98    pub impl_def_id: ImplDefId,
99    pub generic_args: Vec<GenericArgumentId>,
100}
101define_short_id!(
102    ConcreteImplId,
103    ConcreteImplLongId,
104    SemanticGroup,
105    lookup_intern_concrete_impl,
106    intern_concrete_impl
107);
108semantic_object_for_id!(
109    ConcreteImplId,
110    lookup_intern_concrete_impl,
111    intern_concrete_impl,
112    ConcreteImplLongId
113);
114impl DebugWithDb<dyn SemanticGroup> for ConcreteImplLongId {
115    fn fmt(
116        &self,
117        f: &mut std::fmt::Formatter<'_>,
118        db: &(dyn SemanticGroup + 'static),
119    ) -> std::fmt::Result {
120        write!(f, "{}", self.impl_def_id.full_path(db.upcast()))?;
121        if !self.generic_args.is_empty() {
122            write!(f, "::<")?;
123            for (i, arg) in self.generic_args.iter().enumerate() {
124                if i > 0 {
125                    write!(f, ", ")?;
126                }
127                write!(f, "{}", arg.format(db))?;
128            }
129            write!(f, ">")?;
130        }
131        Ok(())
132    }
133}
134impl ConcreteImplId {
135    pub fn impl_def_id(&self, db: &dyn SemanticGroup) -> ImplDefId {
136        self.lookup_intern(db).impl_def_id
137    }
138    pub fn get_impl_function(
139        &self,
140        db: &dyn SemanticGroup,
141        function: TraitFunctionId,
142    ) -> Maybe<Option<ImplFunctionId>> {
143        db.impl_function_by_trait_function(self.impl_def_id(db), function)
144    }
145    pub fn name(&self, db: &dyn SemanticGroup) -> SmolStr {
146        self.impl_def_id(db).name(db.upcast())
147    }
148    pub fn substitution(&self, db: &dyn SemanticGroup) -> Maybe<GenericSubstitution> {
149        Ok(GenericSubstitution::from_impl(ImplLongId::Concrete(*self).intern(db)).concat(
150            GenericSubstitution::new(
151                &db.impl_def_generic_params(self.impl_def_id(db))?,
152                &self.lookup_intern(db).generic_args,
153            ),
154        ))
155    }
156    /// Returns true if the `impl` does not depend on any generics.
157    pub fn is_fully_concrete(&self, db: &dyn SemanticGroup) -> bool {
158        self.lookup_intern(db)
159            .generic_args
160            .iter()
161            .all(|generic_argument_id| generic_argument_id.is_fully_concrete(db))
162    }
163    /// Returns true if the `impl` does not depend on impl or type variables.
164    pub fn is_var_free(&self, db: &dyn SemanticGroup) -> bool {
165        self.lookup_intern(db)
166            .generic_args
167            .iter()
168            .all(|generic_argument_id| generic_argument_id.is_var_free(db))
169    }
170}
171
172/// Represents a "callee" impl that can be referred to in the code.
173/// Traits should be resolved to this.
174#[derive(Clone, Debug, Hash, PartialEq, Eq, SemanticObject)]
175pub enum ImplLongId {
176    Concrete(ConcreteImplId),
177    GenericParameter(GenericParamId),
178    ImplVar(ImplVarId),
179    ImplImpl(ImplImplId),
180    TraitImpl(TraitImplId),
181    GeneratedImpl(GeneratedImplId),
182}
183impl ImplLongId {
184    /// Returns the [ImplHead] of an impl if available.
185    pub fn head(&self, db: &dyn SemanticGroup) -> Option<ImplHead> {
186        Some(match self {
187            ImplLongId::Concrete(concrete) => ImplHead::Concrete(concrete.impl_def_id(db)),
188            ImplLongId::GenericParameter(_)
189            | ImplLongId::ImplVar(_)
190            | ImplLongId::ImplImpl(_)
191            | ImplLongId::TraitImpl(_)
192            | ImplLongId::GeneratedImpl(_) => {
193                return None;
194            }
195        })
196    }
197    pub fn name(&self, db: &dyn SemanticGroup) -> SmolStr {
198        match self {
199            ImplLongId::Concrete(concrete_impl) => concrete_impl.name(db),
200            ImplLongId::GenericParameter(generic_param_impl) => {
201                generic_param_impl.name(db.upcast()).unwrap_or_else(|| "_".into())
202            }
203            ImplLongId::ImplVar(var) => {
204                format!("ImplVar({})", var.concrete_trait_id(db).full_path(db)).into()
205            }
206            ImplLongId::ImplImpl(impl_impl) => format!(
207                "{}::{}",
208                impl_impl.impl_id().name(db.upcast()),
209                db.impl_impl_concrete_trait(*impl_impl)
210                    .map(|trait_impl| trait_impl.full_path(db))
211                    .unwrap_or_else(|_| "_".into())
212            )
213            .into(),
214            ImplLongId::TraitImpl(trait_impl) => trait_impl.name(db.upcast()),
215            ImplLongId::GeneratedImpl(generated_impl) => {
216                format!("{:?}", generated_impl.debug(db.elongate())).into()
217            }
218        }
219    }
220    pub fn format(&self, db: &dyn SemanticGroup) -> String {
221        match self {
222            ImplLongId::Concrete(concrete_impl) => {
223                format!("{:?}", concrete_impl.debug(db.elongate()))
224            }
225            ImplLongId::GenericParameter(generic_param_impl) => {
226                generic_param_impl.format(db.upcast())
227            }
228            ImplLongId::ImplVar(var) => format!("{var:?}"),
229            ImplLongId::ImplImpl(impl_impl) => format!("{:?}", impl_impl.debug(db.elongate())),
230            ImplLongId::TraitImpl(trait_impl) => format!("{:?}", trait_impl.debug(db.elongate())),
231            ImplLongId::GeneratedImpl(generated_impl) => {
232                format!("{:?}", generated_impl.debug(db.elongate()))
233            }
234        }
235    }
236
237    /// Returns true if the `impl` does not depend on impl or type variables.
238    pub fn is_var_free(&self, db: &dyn SemanticGroup) -> bool {
239        match self {
240            ImplLongId::Concrete(concrete_impl_id) => concrete_impl_id.is_var_free(db),
241            ImplLongId::GenericParameter(_) | ImplLongId::TraitImpl(_) => true,
242            ImplLongId::ImplVar(_) => false,
243            ImplLongId::ImplImpl(impl_impl) => impl_impl.impl_id().is_var_free(db),
244            ImplLongId::GeneratedImpl(generated_impl) => {
245                generated_impl.concrete_trait(db).is_var_free(db)
246                    && generated_impl
247                        .lookup_intern(db)
248                        .impl_items
249                        .0
250                        .values()
251                        .all(|type_id| type_id.is_var_free(db))
252            }
253        }
254    }
255
256    /// Returns true if the `impl` does not depend on any generics.
257    pub fn is_fully_concrete(&self, db: &dyn SemanticGroup) -> bool {
258        match self {
259            ImplLongId::Concrete(concrete_impl_id) => concrete_impl_id.is_fully_concrete(db),
260            ImplLongId::GenericParameter(_) => false,
261            ImplLongId::ImplVar(_) => false,
262            ImplLongId::ImplImpl(_) | ImplLongId::TraitImpl(_) => false,
263            ImplLongId::GeneratedImpl(generated_impl) => {
264                generated_impl.concrete_trait(db).is_fully_concrete(db)
265                    && generated_impl
266                        .lookup_intern(db)
267                        .impl_items
268                        .0
269                        .values()
270                        .all(|type_id| type_id.is_fully_concrete(db))
271            }
272        }
273    }
274}
275impl DebugWithDb<dyn SemanticGroup> for ImplLongId {
276    fn fmt(
277        &self,
278        f: &mut std::fmt::Formatter<'_>,
279        db: &(dyn SemanticGroup + 'static),
280    ) -> std::fmt::Result {
281        match self {
282            ImplLongId::Concrete(concrete_impl_id) => write!(f, "{:?}", concrete_impl_id.debug(db)),
283            ImplLongId::GenericParameter(param) => write!(f, "{:?}", param.debug(db)),
284            ImplLongId::ImplVar(var) => write!(f, "?{}", var.lookup_intern(db).id.0),
285            ImplLongId::ImplImpl(impl_impl) => write!(f, "{:?}", impl_impl.debug(db)),
286            ImplLongId::TraitImpl(trait_impl) => write!(f, "{:?}", trait_impl.debug(db)),
287            ImplLongId::GeneratedImpl(generated_impl) => {
288                write!(f, "{:?}", generated_impl.debug(db))
289            }
290        }
291    }
292}
293
294define_short_id!(ImplId, ImplLongId, SemanticGroup, lookup_intern_impl, intern_impl);
295semantic_object_for_id!(ImplId, lookup_intern_impl, intern_impl, ImplLongId);
296impl ImplId {
297    pub fn concrete_trait(&self, db: &dyn SemanticGroup) -> Maybe<ConcreteTraitId> {
298        db.impl_concrete_trait(*self)
299    }
300
301    /// Returns true if the `impl` does not depend on any generics.
302    pub fn is_fully_concrete(&self, db: &dyn SemanticGroup) -> bool {
303        db.priv_impl_is_fully_concrete(*self)
304    }
305
306    /// Returns true if the `impl` does not depend on impl or type variables.
307    pub fn is_var_free(&self, db: &dyn SemanticGroup) -> bool {
308        db.priv_impl_is_var_free(*self)
309    }
310
311    /// Returns the [ImplHead] of an impl if available.
312    pub fn head(&self, db: &dyn SemanticGroup) -> Option<ImplHead> {
313        self.lookup_intern(db).head(db)
314    }
315
316    /// Returns the name of the impl.
317    pub fn name(&self, db: &dyn SemanticGroup) -> SmolStr {
318        self.lookup_intern(db).name(db)
319    }
320
321    pub fn format(&self, db: &dyn SemanticGroup) -> String {
322        self.lookup_intern(db).format(db)
323    }
324}
325
326define_short_id!(
327    GeneratedImplId,
328    GeneratedImplLongId,
329    SemanticGroup,
330    lookup_intern_generated_impl,
331    intern_generated_impl
332);
333semantic_object_for_id!(
334    GeneratedImplId,
335    lookup_intern_generated_impl,
336    intern_generated_impl,
337    GeneratedImplLongId
338);
339
340impl GeneratedImplId {
341    pub fn concrete_trait(self, db: &dyn SemanticGroup) -> ConcreteTraitId {
342        db.lookup_intern_generated_impl(self).concrete_trait
343    }
344
345    pub fn trait_id(&self, db: &dyn SemanticGroup) -> TraitId {
346        self.concrete_trait(db).trait_id(db)
347    }
348}
349
350/// An impl that is generated by the compiler for a specific trait.
351/// There can be only one such impl per concrete trait as otherwise there would be a
352/// MultipleImplsFound ambiguity.
353#[derive(Clone, Debug, Hash, PartialEq, Eq, SemanticObject)]
354pub struct GeneratedImplLongId {
355    pub concrete_trait: ConcreteTraitId,
356    /// The generic params required for the impl. Typically impls and negative impls.
357    /// We save the params so that we can validate negative impls.
358    pub generic_params: Vec<GenericParam>,
359    pub impl_items: GeneratedImplItems,
360}
361#[derive(Clone, Debug, Default, PartialEq, Eq, SemanticObject)]
362pub struct GeneratedImplItems(pub OrderedHashMap<TraitTypeId, TypeId>);
363impl Hash for GeneratedImplItems {
364    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
365        self.0.iter().for_each(|(trait_type_id, type_id)| {
366            trait_type_id.hash(state);
367            type_id.hash(state);
368        });
369    }
370}
371pub enum GeneratedImplAssociatedTypes {
372    /// The associated types are not yet resolved.
373    Unresolved,
374    /// The associated types are resolved.
375    Resolved(OrderedHashMap<TraitTypeId, TypeId>),
376}
377
378impl DebugWithDb<dyn SemanticGroup> for GeneratedImplLongId {
379    fn fmt(
380        &self,
381        f: &mut std::fmt::Formatter<'_>,
382        db: &(dyn SemanticGroup + 'static),
383    ) -> std::fmt::Result {
384        write!(f, "Generated {:?}", self.concrete_trait.debug(db))
385    }
386}
387
388/// An impl item of kind impl.
389#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, SemanticObject)]
390pub struct ImplImplId {
391    /// The impl the item impl is in.
392    impl_id: ImplId,
393    /// The trait impl this impl impl "implements".
394    trait_impl_id: TraitImplId,
395}
396
397impl ImplImplId {
398    /// Creates a new impl impl id. For an impl impl of a concrete impl, asserts that the
399    /// trait impl belongs to the same trait that the impl implements (panics if not).
400    pub fn new(impl_id: ImplId, trait_impl_id: TraitImplId, db: &dyn SemanticGroup) -> Self {
401        if let crate::items::imp::ImplLongId::Concrete(concrete_impl) = impl_id.lookup_intern(db) {
402            let impl_def_id = concrete_impl.impl_def_id(db);
403            assert_eq!(Ok(trait_impl_id.trait_id(db.upcast())), db.impl_def_trait(impl_def_id));
404        }
405
406        ImplImplId { impl_id, trait_impl_id }
407    }
408    pub fn impl_id(&self) -> ImplId {
409        self.impl_id
410    }
411    pub fn trait_impl_id(&self) -> TraitImplId {
412        self.trait_impl_id
413    }
414
415    pub fn concrete_trait_impl_id(&self, db: &dyn SemanticGroup) -> Maybe<ConcreteTraitImplId> {
416        Ok(ConcreteTraitImplId::new(db, self.impl_id.concrete_trait(db)?, self.trait_impl_id))
417    }
418
419    pub fn format(&self, db: &dyn SemanticGroup) -> SmolStr {
420        format!("{}::{}", self.impl_id.name(db.upcast()), self.trait_impl_id.name(db.upcast()),)
421            .into()
422    }
423}
424impl DebugWithDb<dyn SemanticGroup> for ImplImplId {
425    fn fmt(
426        &self,
427        f: &mut std::fmt::Formatter<'_>,
428        db: &(dyn SemanticGroup + 'static),
429    ) -> std::fmt::Result {
430        write!(f, "{}", self.format(db))
431    }
432}
433
434impl UnstableSalsaId for ImplId {
435    fn get_internal_id(&self) -> &salsa::InternId {
436        &self.0
437    }
438}
439
440/// Head of an impl.
441///
442/// A non-param non-variable impl has a head, which represents the kind of the root node in its tree
443/// representation. This is used for caching queries for fast lookups when the impl is not
444/// completely inferred yet.
445#[derive(Clone, Debug, Hash, PartialEq, Eq)]
446pub enum ImplHead {
447    Concrete(ImplDefId),
448}
449
450// === Impl Declaration ===
451
452#[derive(Clone, Debug, PartialEq, Eq, DebugWithDb)]
453#[debug_db(dyn SemanticGroup + 'static)]
454pub struct ImplDeclarationData {
455    diagnostics: Diagnostics<SemanticDiagnostic>,
456    generic_params: Vec<semantic::GenericParam>,
457    /// The concrete trait this impl implements, or Err if cannot be resolved.
458    concrete_trait: Maybe<ConcreteTraitId>,
459    attributes: Vec<Attribute>,
460    resolver_data: Arc<ResolverData>,
461}
462
463// --- Selectors ---
464
465/// Query implementation of [crate::db::SemanticGroup::impl_semantic_declaration_diagnostics].
466pub fn impl_semantic_declaration_diagnostics(
467    db: &dyn SemanticGroup,
468    impl_def_id: ImplDefId,
469) -> Diagnostics<SemanticDiagnostic> {
470    db.priv_impl_declaration_data(impl_def_id).map(|data| data.diagnostics).unwrap_or_default()
471}
472
473/// Query implementation of [crate::db::SemanticGroup::impl_def_generic_params_data].
474pub fn impl_def_generic_params_data(
475    db: &dyn SemanticGroup,
476    impl_def_id: ImplDefId,
477) -> Maybe<GenericParamsData> {
478    let module_file_id = impl_def_id.module_file_id(db.upcast());
479    let mut diagnostics = SemanticDiagnostics::default();
480
481    let impl_ast = db.module_impl_by_id(impl_def_id)?.to_maybe()?;
482    let inference_id =
483        InferenceId::LookupItemGenerics(LookupItemId::ModuleItem(ModuleItemId::Impl(impl_def_id)));
484
485    let mut resolver = Resolver::new(db, module_file_id, inference_id);
486    resolver.set_feature_config(&impl_def_id, &impl_ast, &mut diagnostics);
487    let generic_params = semantic_generic_params(
488        db,
489        &mut diagnostics,
490        &mut resolver,
491        module_file_id,
492        &impl_ast.generic_params(db.upcast()),
493    );
494    let inference = &mut resolver.inference();
495    inference.finalize(&mut diagnostics, impl_ast.stable_ptr().untyped());
496
497    let generic_params = inference.rewrite(generic_params).no_err();
498    let resolver_data = Arc::new(resolver.data);
499    Ok(GenericParamsData { generic_params, diagnostics: diagnostics.build(), resolver_data })
500}
501
502/// Query implementation of [crate::db::SemanticGroup::impl_def_generic_params].
503pub fn impl_def_generic_params(
504    db: &dyn SemanticGroup,
505    impl_def_id: ImplDefId,
506) -> Maybe<Vec<semantic::GenericParam>> {
507    Ok(db.impl_def_generic_params_data(impl_def_id)?.generic_params)
508}
509
510/// Query implementation of [crate::db::SemanticGroup::impl_def_resolver_data].
511pub fn impl_def_resolver_data(
512    db: &dyn SemanticGroup,
513    impl_def_id: ImplDefId,
514) -> Maybe<Arc<ResolverData>> {
515    Ok(db.priv_impl_declaration_data(impl_def_id)?.resolver_data)
516}
517
518/// Trivial cycle handler for [crate::db::SemanticGroup::impl_def_resolver_data].
519pub fn impl_def_resolver_data_cycle(
520    db: &dyn SemanticGroup,
521    _cycle: &salsa::Cycle,
522    impl_def_id: &ImplDefId,
523) -> Maybe<Arc<ResolverData>> {
524    // Forwarding (not as a query) cycle handling to `priv_impl_declaration_data` cycle handler.
525    impl_def_resolver_data(db, *impl_def_id)
526}
527
528/// Query implementation of [crate::db::SemanticGroup::impl_def_concrete_trait].
529pub fn impl_def_concrete_trait(
530    db: &dyn SemanticGroup,
531    impl_def_id: ImplDefId,
532) -> Maybe<ConcreteTraitId> {
533    db.priv_impl_declaration_data(impl_def_id)?.concrete_trait
534}
535
536/// Trivial cycle handler for [crate::db::SemanticGroup::impl_def_concrete_trait].
537pub fn impl_def_concrete_trait_cycle(
538    db: &dyn SemanticGroup,
539    _cycle: &salsa::Cycle,
540    impl_def_id: &ImplDefId,
541) -> Maybe<ConcreteTraitId> {
542    // Forwarding (not as a query) cycle handling to `priv_impl_declaration_data` cycle handler.
543    impl_def_concrete_trait(db, *impl_def_id)
544}
545
546/// Query implementation of [crate::db::SemanticGroup::impl_def_substitution].
547pub fn impl_def_substitution(
548    db: &dyn SemanticGroup,
549    impl_def_id: ImplDefId,
550) -> Maybe<Arc<GenericSubstitution>> {
551    let params = db.impl_def_generic_params(impl_def_id)?;
552    let generic_args = generic_params_to_args(&params, db);
553    Ok(Arc::new(ConcreteImplLongId { impl_def_id, generic_args }.intern(db).substitution(db)?))
554}
555
556/// Query implementation of [crate::db::SemanticGroup::impl_def_attributes].
557pub fn impl_def_attributes(
558    db: &dyn SemanticGroup,
559    impl_def_id: ImplDefId,
560) -> Maybe<Vec<Attribute>> {
561    Ok(db.priv_impl_declaration_data(impl_def_id)?.attributes)
562}
563
564/// Query implementation of [crate::db::SemanticGroup::impl_def_trait].
565pub fn impl_def_trait(db: &dyn SemanticGroup, impl_def_id: ImplDefId) -> Maybe<TraitId> {
566    let module_file_id = impl_def_id.module_file_id(db.upcast());
567    let mut diagnostics = SemanticDiagnostics::default();
568
569    let impl_ast = db.module_impl_by_id(impl_def_id)?.to_maybe()?;
570    let inference_id = InferenceId::ImplDefTrait(impl_def_id);
571
572    let mut resolver = Resolver::new(db, module_file_id, inference_id);
573    resolver.set_feature_config(&impl_def_id, &impl_ast, &mut diagnostics);
574
575    let trait_path_syntax = impl_ast.trait_path(db.upcast());
576
577    resolve_trait_path(&mut diagnostics, &mut resolver, &trait_path_syntax)
578}
579
580/// Query implementation of [crate::db::SemanticGroup::impl_concrete_trait].
581pub fn impl_concrete_trait(db: &dyn SemanticGroup, impl_id: ImplId) -> Maybe<ConcreteTraitId> {
582    match impl_id.lookup_intern(db) {
583        ImplLongId::Concrete(concrete_impl_id) => {
584            let long_impl = concrete_impl_id.lookup_intern(db);
585            let substitution = GenericSubstitution::new(
586                &db.impl_def_generic_params(long_impl.impl_def_id)?,
587                &long_impl.generic_args,
588            );
589
590            let impl_concrete_trait_id = db.impl_def_concrete_trait(long_impl.impl_def_id)?;
591            SubstitutionRewriter { db, substitution: &substitution }.rewrite(impl_concrete_trait_id)
592        }
593        ImplLongId::GenericParameter(param) => {
594            let param_impl =
595                extract_matches!(db.generic_param_semantic(param)?, GenericParam::Impl);
596            param_impl.concrete_trait
597        }
598        ImplLongId::ImplVar(var) => Ok(var.lookup_intern(db).concrete_trait_id),
599        ImplLongId::ImplImpl(impl_impl) => db.impl_impl_concrete_trait(impl_impl),
600        ImplLongId::TraitImpl(trait_impl) => db.trait_impl_concrete_trait(trait_impl),
601        ImplLongId::GeneratedImpl(generated_impl) => Ok(generated_impl.concrete_trait(db)),
602    }
603}
604
605// --- Computation ---
606
607/// Cycle handling for [crate::db::SemanticGroup::priv_impl_declaration_data].
608pub fn priv_impl_declaration_data_cycle(
609    db: &dyn SemanticGroup,
610    _cycle: &salsa::Cycle,
611    impl_def_id: &ImplDefId,
612) -> Maybe<ImplDeclarationData> {
613    priv_impl_declaration_data_inner(db, *impl_def_id, false)
614}
615
616/// Query implementation of [crate::db::SemanticGroup::priv_impl_declaration_data].
617pub fn priv_impl_declaration_data(
618    db: &dyn SemanticGroup,
619    impl_def_id: ImplDefId,
620) -> Maybe<ImplDeclarationData> {
621    priv_impl_declaration_data_inner(db, impl_def_id, true)
622}
623
624/// Shared code for the query and cycle handling.
625/// The cycle handling logic needs to pass resolve_trait=false to prevent the cycle.
626pub fn priv_impl_declaration_data_inner(
627    db: &dyn SemanticGroup,
628    impl_def_id: ImplDefId,
629    resolve_trait: bool,
630) -> Maybe<ImplDeclarationData> {
631    let mut diagnostics = SemanticDiagnostics::default();
632
633    // TODO(spapini): when code changes in a file, all the AST items change (as they contain a path
634    // to the green root that changes. Once ASTs are rooted on items, use a selector that picks only
635    // the item instead of all the module data.
636    let syntax_db = db.upcast();
637    let impl_ast = db.module_impl_by_id(impl_def_id)?.to_maybe()?;
638    let inference_id = InferenceId::LookupItemDeclaration(LookupItemId::ModuleItem(
639        ModuleItemId::Impl(impl_def_id),
640    ));
641
642    // Generic params.
643    let generic_params_data = db.impl_def_generic_params_data(impl_def_id)?;
644    let generic_params = generic_params_data.generic_params;
645    let mut resolver = Resolver::with_data(
646        db,
647        (*generic_params_data.resolver_data).clone_with_inference_id(db, inference_id),
648    );
649    resolver.set_feature_config(&impl_def_id, &impl_ast, &mut diagnostics);
650    diagnostics.extend(generic_params_data.diagnostics);
651    let trait_path_syntax = impl_ast.trait_path(syntax_db);
652
653    let concrete_trait = if resolve_trait {
654        match resolver.resolve_concrete_path(
655            &mut diagnostics,
656            &trait_path_syntax,
657            NotFoundItemType::Trait,
658        ) {
659            Ok(resolved_item) => try_extract_matches!(resolved_item, ResolvedConcreteItem::Trait)
660                .ok_or_else(|| diagnostics.report(&trait_path_syntax, NotATrait)),
661            Err(err) => Err(err),
662        }
663    } else {
664        Err(diagnostics.report(&trait_path_syntax, ImplRequirementCycle))
665    };
666
667    // Check for reimplementation of compilers' Traits.
668    if let Ok(concrete_trait) = concrete_trait {
669        if [
670            get_core_trait(db, CoreTraitContext::MetaProgramming, "TypeEqual".into()),
671            fn_trait(db),
672            fn_once_trait(db),
673        ]
674        .contains(&concrete_trait.trait_id(db))
675            && impl_def_id.parent_module(db.upcast()).owning_crate(db.upcast()) != core_crate(db)
676        {
677            diagnostics.report(&trait_path_syntax, CompilerTraitReImplementation {
678                trait_id: concrete_trait.trait_id(db),
679            });
680        }
681    }
682
683    // Check fully resolved.
684    let inference = &mut resolver.inference();
685    inference.finalize(&mut diagnostics, impl_ast.stable_ptr().untyped());
686
687    let concrete_trait: Result<ConcreteTraitId, DiagnosticAdded> =
688        inference.rewrite(concrete_trait).no_err();
689    let generic_params: Vec<GenericParam> = inference.rewrite(generic_params).no_err();
690
691    let attributes = impl_ast.attributes(syntax_db).structurize(syntax_db);
692    let mut resolver_data = resolver.data;
693    resolver_data.trait_or_impl_ctx = TraitOrImplContext::Impl(impl_def_id);
694    Ok(ImplDeclarationData {
695        diagnostics: diagnostics.build(),
696        generic_params,
697        concrete_trait,
698        attributes,
699        resolver_data: Arc::new(resolver_data),
700    })
701}
702
703// === Impl Definition ===
704
705#[derive(Clone, Debug, PartialEq, Eq, DebugWithDb)]
706#[debug_db(dyn SemanticGroup + 'static)]
707pub struct ImplDefinitionData {
708    /// The diagnostics here are "flat" - that is, only the diagnostics found on the impl level
709    /// itself, and don't include the diagnostics of its items. The reason it's this way is that
710    /// computing the items' diagnostics require a query about their impl, forming a cycle of
711    /// queries. Adding the items' diagnostics only after the whole computation breaks this cycle.
712    diagnostics: Diagnostics<SemanticDiagnostic>,
713
714    // AST maps.
715    function_asts: OrderedHashMap<ImplFunctionId, ast::FunctionWithBody>,
716    item_type_asts: Arc<OrderedHashMap<ImplTypeDefId, ast::ItemTypeAlias>>,
717    item_constant_asts: Arc<OrderedHashMap<ImplConstantDefId, ast::ItemConstant>>,
718    item_impl_asts: Arc<OrderedHashMap<ImplImplDefId, ast::ItemImplAlias>>,
719
720    /// Mapping of item names to their IDs. All the IDs should appear in one of the AST maps above.
721    item_id_by_name: Arc<OrderedHashMap<SmolStr, ImplItemId>>,
722
723    /// Mapping of missing impl names item names to the trait id.
724    implicit_impls_id_by_name: Arc<OrderedHashMap<SmolStr, TraitImplId>>,
725}
726
727// --- Selectors ---
728
729/// Query implementation of [crate::db::SemanticGroup::impl_semantic_definition_diagnostics].
730pub fn impl_semantic_definition_diagnostics(
731    db: &dyn SemanticGroup,
732    impl_def_id: ImplDefId,
733) -> Diagnostics<SemanticDiagnostic> {
734    let mut diagnostics = DiagnosticsBuilder::default();
735
736    let Ok(data) = db.priv_impl_definition_data(impl_def_id) else {
737        return Diagnostics::default();
738    };
739
740    // The diagnostics from `priv_impl_definition_data` are only the diagnostics from the impl
741    // level. They should be enriched with the items' diagnostics.
742    diagnostics.extend(data.diagnostics);
743    for impl_function_id in data.function_asts.keys() {
744        diagnostics.extend(db.impl_function_declaration_diagnostics(*impl_function_id));
745        diagnostics.extend(db.impl_function_body_diagnostics(*impl_function_id));
746    }
747    for impl_item_type_id in data.item_type_asts.keys() {
748        diagnostics.extend(db.impl_type_def_semantic_diagnostics(*impl_item_type_id));
749        if let Ok(ty) = db.impl_type_def_resolved_type(*impl_item_type_id) {
750            add_type_based_diagnostics(
751                db,
752                &mut diagnostics,
753                ty,
754                impl_item_type_id.stable_ptr(db.upcast()),
755            );
756        }
757    }
758    for impl_item_constant_id in data.item_constant_asts.keys() {
759        diagnostics.extend(db.impl_constant_def_semantic_diagnostics(*impl_item_constant_id));
760    }
761    for impl_item_impl_id in data.item_impl_asts.keys() {
762        diagnostics.extend(db.impl_impl_def_semantic_diagnostics(*impl_item_impl_id));
763    }
764    for implicit_impl_id in data.implicit_impls_id_by_name.values() {
765        diagnostics
766            .extend(db.implicit_impl_impl_semantic_diagnostics(impl_def_id, *implicit_impl_id));
767    }
768    // Diagnostics for special traits.
769    if diagnostics.error_count == 0 {
770        let trait_id = db
771            .priv_impl_declaration_data(impl_def_id)
772            .unwrap()
773            .concrete_trait
774            .unwrap()
775            .trait_id(db);
776        if trait_id == deref_trait(db) {
777            handle_deref_impl(db, impl_def_id, &mut diagnostics);
778        }
779    }
780    diagnostics.build()
781}
782
783/// Checks that there are no cycles of Deref impls.
784fn handle_deref_impl(
785    db: &dyn SemanticGroup,
786    mut impl_def_id: ImplDefId,
787    diagnostics: &mut DiagnosticsBuilder<SemanticDiagnostic>,
788) {
789    let mut visited_impls: OrderedHashSet<ImplDefId> = OrderedHashSet::default();
790    let deref_trait_id = deref_trait(db);
791    loop {
792        let Ok(impl_id) = get_impl_based_on_single_impl_type(db, impl_def_id, |ty| {
793            ConcreteTraitLongId {
794                trait_id: deref_trait_id,
795                generic_args: vec![GenericArgumentId::Type(ty)],
796            }
797            .intern(db)
798        }) else {
799            // Inference errors are handled when the impl is in actual use. In here we only check
800            // for cycles.
801            return;
802        };
803        impl_def_id = match impl_id.lookup_intern(db) {
804            ImplLongId::Concrete(concrete_impl_id) => concrete_impl_id.impl_def_id(db),
805            _ => return,
806        };
807
808        if !visited_impls.insert(impl_def_id) {
809            let deref_chain = visited_impls
810                .iter()
811                .map(|visited_impl| {
812                    format!(
813                        "{:?}",
814                        db.impl_def_concrete_trait(*visited_impl).unwrap().debug(db.elongate())
815                    )
816                })
817                .join(" -> ");
818            diagnostics
819                .report(impl_def_id.stable_ptr(db.upcast()), SemanticDiagnosticKind::DerefCycle {
820                    deref_chain,
821                });
822            return;
823        }
824    }
825}
826
827/// Assuming that an impl has a single impl type, extracts the type, and then infers another impl
828/// based on it. If the inference fails, returns the inference error and the impl type definition
829/// for diagnostics.
830fn get_impl_based_on_single_impl_type(
831    db: &dyn SemanticGroup,
832    impl_def_id: ImplDefId,
833    concrete_trait_id: impl FnOnce(TypeId) -> ConcreteTraitId,
834) -> Result<ImplId, (InferenceError, ImplTypeDefId)> {
835    let data = db.priv_impl_definition_data(impl_def_id).unwrap();
836    let mut types_iter = data.item_type_asts.iter();
837    let (impl_item_type_id, _) = types_iter.next().unwrap();
838    if types_iter.next().is_some() {
839        panic!(
840            "get_impl_based_on_single_impl_type called with an impl that has more than one type"
841        );
842    }
843    let ty = db.impl_type_def_resolved_type(*impl_item_type_id).unwrap();
844    let module_file_id = impl_def_id.module_file_id(db.upcast());
845    let generic_params = db.impl_def_generic_params(impl_def_id).unwrap();
846    let generic_params_ids =
847        generic_params.iter().map(|generic_param| generic_param.id()).collect();
848    let lookup_context = ImplLookupContext::new(module_file_id.0, generic_params_ids);
849    get_impl_at_context(db, lookup_context, concrete_trait_id(ty), None)
850        .map_err(|err| (err, *impl_item_type_id))
851}
852
853/// Query implementation of [crate::db::SemanticGroup::impl_functions].
854pub fn impl_functions(
855    db: &dyn SemanticGroup,
856    impl_def_id: ImplDefId,
857) -> Maybe<OrderedHashMap<SmolStr, ImplFunctionId>> {
858    Ok(db
859        .priv_impl_definition_data(impl_def_id)?
860        .function_asts
861        .keys()
862        .map(|function_id| {
863            let function_long_id = function_id.lookup_intern(db);
864            (function_long_id.name(db.upcast()), *function_id)
865        })
866        .collect())
867}
868
869/// Query implementation of [crate::db::SemanticGroup::impl_function_by_trait_function].
870pub fn impl_function_by_trait_function(
871    db: &dyn SemanticGroup,
872    impl_def_id: ImplDefId,
873    trait_function_id: TraitFunctionId,
874) -> Maybe<Option<ImplFunctionId>> {
875    let defs_db = db.upcast();
876    let name = trait_function_id.name(defs_db);
877    for impl_function_id in db.priv_impl_definition_data(impl_def_id)?.function_asts.keys() {
878        if impl_function_id.lookup_intern(db).name(defs_db) == name {
879            return Ok(Some(*impl_function_id));
880        }
881    }
882    Ok(None)
883}
884
885/// Query implementation of [crate::db::SemanticGroup::impl_item_by_name].
886pub fn impl_item_by_name(
887    db: &dyn SemanticGroup,
888    impl_def_id: ImplDefId,
889    name: SmolStr,
890) -> Maybe<Option<ImplItemId>> {
891    Ok(db.priv_impl_definition_data(impl_def_id)?.item_id_by_name.get(&name).cloned())
892}
893
894/// Query implementation of [crate::db::SemanticGroup::impl_implicit_impl_by_name].
895pub fn impl_implicit_impl_by_name(
896    db: &dyn SemanticGroup,
897    impl_def_id: ImplDefId,
898    name: SmolStr,
899) -> Maybe<Option<TraitImplId>> {
900    Ok(db.priv_impl_definition_data(impl_def_id)?.implicit_impls_id_by_name.get(&name).cloned())
901}
902
903/// Query implementation of [SemanticGroup::impl_all_used_items].
904pub fn impl_all_used_items(
905    db: &dyn SemanticGroup,
906    impl_def_id: ImplDefId,
907) -> Maybe<Arc<OrderedHashSet<LookupItemId>>> {
908    let mut all_used_items = db.impl_def_resolver_data(impl_def_id)?.used_items.clone();
909    let data = db.priv_impl_definition_data(impl_def_id)?;
910    for item in data.item_id_by_name.values() {
911        for resolver_data in get_resolver_data_options(LookupItemId::ImplItem(*item), db) {
912            all_used_items.extend(resolver_data.used_items.iter().cloned());
913        }
914    }
915    Ok(all_used_items.into())
916}
917
918/// Query implementation of [crate::db::SemanticGroup::impl_types].
919pub fn impl_types(
920    db: &dyn SemanticGroup,
921    impl_def_id: ImplDefId,
922) -> Maybe<Arc<OrderedHashMap<ImplTypeDefId, ast::ItemTypeAlias>>> {
923    Ok(db.priv_impl_definition_data(impl_def_id)?.item_type_asts)
924}
925
926/// Query implementation of [crate::db::SemanticGroup::impl_type_ids].
927pub fn impl_type_ids(
928    db: &dyn SemanticGroup,
929    impl_def_id: ImplDefId,
930) -> Maybe<Arc<[ImplTypeDefId]>> {
931    Ok(db.impl_types(impl_def_id)?.keys().copied().collect_vec().into())
932}
933
934/// Query implementation of [crate::db::SemanticGroup::impl_type_by_id].
935pub fn impl_type_by_id(
936    db: &dyn SemanticGroup,
937    impl_type_id: ImplTypeDefId,
938) -> Maybe<Option<ast::ItemTypeAlias>> {
939    let impl_types = db.impl_types(impl_type_id.impl_def_id(db.upcast()))?;
940    Ok(impl_types.get(&impl_type_id).cloned())
941}
942
943/// Query implementation of [crate::db::SemanticGroup::impl_type_by_trait_type].
944pub fn impl_type_by_trait_type(
945    db: &dyn SemanticGroup,
946    impl_def_id: ImplDefId,
947    trait_type_id: TraitTypeId,
948) -> Maybe<ImplTypeDefId> {
949    if trait_type_id.trait_id(db.upcast()) != db.impl_def_trait(impl_def_id)? {
950        unreachable!(
951            "impl_type_by_trait_type called with a trait type that does not belong to the impl's \
952             trait"
953        )
954    }
955
956    let defs_db = db.upcast();
957    let name = trait_type_id.name(defs_db);
958    // If the trait type's name is not found, then a missing item diagnostic is reported.
959    db.impl_item_by_name(impl_def_id, name).and_then(|maybe_item_id| match maybe_item_id {
960        Some(item_id) => Ok(extract_matches!(item_id, ImplItemId::Type)),
961        None => Err(skip_diagnostic()),
962    })
963}
964
965/// Query implementation of [crate::db::SemanticGroup::impl_constants].
966pub fn impl_constants(
967    db: &dyn SemanticGroup,
968    impl_def_id: ImplDefId,
969) -> Maybe<Arc<OrderedHashMap<ImplConstantDefId, ast::ItemConstant>>> {
970    Ok(db.priv_impl_definition_data(impl_def_id)?.item_constant_asts)
971}
972
973/// Query implementation of [crate::db::SemanticGroup::impl_constant_by_trait_constant].
974pub fn impl_constant_by_trait_constant(
975    db: &dyn SemanticGroup,
976    impl_def_id: ImplDefId,
977    trait_constant_id: TraitConstantId,
978) -> Maybe<ImplConstantDefId> {
979    if trait_constant_id.trait_id(db.upcast()) != db.impl_def_trait(impl_def_id)? {
980        unreachable!(
981            "impl_constant_by_trait_constant called with a trait constant that does not belong to \
982             the impl's trait"
983        )
984    }
985
986    let defs_db = db.upcast();
987    let name = trait_constant_id.name(defs_db);
988    // If the trait constant's name is not found, then a missing item diagnostic is reported.
989    db.impl_item_by_name(impl_def_id, name).and_then(|maybe_item_id| match maybe_item_id {
990        Some(item_id) => Ok(extract_matches!(item_id, ImplItemId::Constant)),
991        None => Err(skip_diagnostic()),
992    })
993}
994
995/// Query implementation of [crate::db::SemanticGroup::impl_impls].
996pub fn impl_impls(
997    db: &dyn SemanticGroup,
998    impl_def_id: ImplDefId,
999) -> Maybe<Arc<OrderedHashMap<ImplImplDefId, ast::ItemImplAlias>>> {
1000    Ok(db.priv_impl_definition_data(impl_def_id)?.item_impl_asts)
1001}
1002
1003/// Query implementation of [crate::db::SemanticGroup::impl_impl_ids].
1004pub fn impl_impl_ids(
1005    db: &dyn SemanticGroup,
1006    impl_def_id: ImplDefId,
1007) -> Maybe<Arc<[ImplImplDefId]>> {
1008    Ok(db.impl_impls(impl_def_id)?.keys().copied().collect_vec().into())
1009}
1010
1011/// Query implementation of [crate::db::SemanticGroup::impl_impl_by_id].
1012pub fn impl_impl_by_id(
1013    db: &dyn SemanticGroup,
1014    impl_impl_id: ImplImplDefId,
1015) -> Maybe<Option<ast::ItemImplAlias>> {
1016    let impl_impls = db.impl_impls(impl_impl_id.impl_def_id(db.upcast()))?;
1017    Ok(impl_impls.get(&impl_impl_id).cloned())
1018}
1019
1020/// Query implementation of [crate::db::SemanticGroup::impl_impl_by_trait_impl].
1021pub fn impl_impl_by_trait_impl(
1022    db: &dyn SemanticGroup,
1023    impl_def_id: ImplDefId,
1024    trait_impl_id: TraitImplId,
1025) -> Maybe<ImplImplDefId> {
1026    if trait_impl_id.trait_id(db.upcast()) != db.impl_def_trait(impl_def_id)? {
1027        unreachable!(
1028            "impl_impl_by_trait_impl called with a trait impl that does not belong to the impl's \
1029             trait"
1030        )
1031    }
1032
1033    let defs_db = db.upcast();
1034    let name = trait_impl_id.name(defs_db);
1035    // If the trait impl's name is not found, then a missing item diagnostic is reported.
1036    db.impl_item_by_name(impl_def_id, name).and_then(|maybe_item_id| match maybe_item_id {
1037        Some(item_id) => Ok(extract_matches!(item_id, ImplItemId::Impl)),
1038        None => Err(skip_diagnostic()),
1039    })
1040}
1041
1042/// Query implementation of [crate::db::SemanticGroup::is_implicit_impl_impl].
1043pub fn is_implicit_impl_impl(
1044    db: &dyn SemanticGroup,
1045    impl_def_id: ImplDefId,
1046    trait_impl_id: TraitImplId,
1047) -> Maybe<bool> {
1048    if trait_impl_id.trait_id(db.upcast()) != db.impl_def_trait(impl_def_id)? {
1049        unreachable!(
1050            "impl_impl_by_trait_impl called with a trait impl that does not belong to the impl's \
1051             trait"
1052        )
1053    }
1054
1055    let defs_db = db.upcast();
1056    let name = trait_impl_id.name(defs_db);
1057    // If the trait impl's name is not found, then a missing item diagnostic is reported.
1058    Ok(db.impl_implicit_impl_by_name(impl_def_id, name)?.is_some())
1059}
1060
1061// --- Computation ---
1062
1063/// Query implementation of [crate::db::SemanticGroup::priv_impl_definition_data].
1064pub fn priv_impl_definition_data(
1065    db: &dyn SemanticGroup,
1066    impl_def_id: ImplDefId,
1067) -> Maybe<ImplDefinitionData> {
1068    let syntax_db = db.upcast();
1069
1070    let module_file_id = impl_def_id.module_file_id(db.upcast());
1071    let mut diagnostics = SemanticDiagnostics::default();
1072
1073    let generic_params = db.impl_def_generic_params(impl_def_id)?;
1074    let concrete_trait = db.priv_impl_declaration_data(impl_def_id)?.concrete_trait?;
1075
1076    let impl_ast = db.module_impl_by_id(impl_def_id)?.to_maybe()?;
1077
1078    let generic_params_ids =
1079        generic_params.iter().map(|generic_param| generic_param.id()).collect();
1080    let lookup_context = ImplLookupContext::new(module_file_id.0, generic_params_ids);
1081    check_special_impls(
1082        db,
1083        &mut diagnostics,
1084        lookup_context,
1085        concrete_trait,
1086        impl_ast.stable_ptr().untyped(),
1087    )
1088    // Ignore the result.
1089    .ok();
1090
1091    let mut function_asts = OrderedHashMap::default();
1092    let mut item_type_asts = OrderedHashMap::default();
1093    let mut item_constant_asts = OrderedHashMap::default();
1094    let mut item_impl_asts = OrderedHashMap::default();
1095    let mut item_id_by_name = OrderedHashMap::default();
1096
1097    if let MaybeImplBody::Some(body) = impl_ast.body(syntax_db) {
1098        for item in body.items(syntax_db).elements(syntax_db) {
1099            match item {
1100                ImplItem::Module(module) => report_invalid_impl_item(
1101                    syntax_db,
1102                    &mut diagnostics,
1103                    module.module_kw(syntax_db),
1104                ),
1105
1106                ImplItem::Use(use_item) => report_invalid_impl_item(
1107                    syntax_db,
1108                    &mut diagnostics,
1109                    use_item.use_kw(syntax_db),
1110                ),
1111                ImplItem::ExternFunction(extern_func) => report_invalid_impl_item(
1112                    syntax_db,
1113                    &mut diagnostics,
1114                    extern_func.extern_kw(syntax_db),
1115                ),
1116                ImplItem::ExternType(extern_type) => report_invalid_impl_item(
1117                    syntax_db,
1118                    &mut diagnostics,
1119                    extern_type.extern_kw(syntax_db),
1120                ),
1121                ImplItem::Trait(trt) => {
1122                    report_invalid_impl_item(syntax_db, &mut diagnostics, trt.trait_kw(syntax_db))
1123                }
1124                ImplItem::Struct(structure) => report_invalid_impl_item(
1125                    syntax_db,
1126                    &mut diagnostics,
1127                    structure.struct_kw(syntax_db),
1128                ),
1129                ImplItem::Enum(enm) => {
1130                    report_invalid_impl_item(syntax_db, &mut diagnostics, enm.enum_kw(syntax_db))
1131                }
1132                ImplItem::Function(func) => {
1133                    let impl_function_id =
1134                        ImplFunctionLongId(module_file_id, func.stable_ptr()).intern(db);
1135                    let name_node = func.declaration(syntax_db).name(syntax_db);
1136                    let name = name_node.text(syntax_db);
1137                    if item_id_by_name
1138                        .insert(name.clone(), ImplItemId::Function(impl_function_id))
1139                        .is_some()
1140                    {
1141                        diagnostics.report(&name_node, NameDefinedMultipleTimes(name));
1142                    }
1143                    function_asts.insert(impl_function_id, func);
1144                }
1145                ImplItem::Type(ty) => {
1146                    let impl_type_id =
1147                        ImplTypeDefLongId(module_file_id, ty.stable_ptr()).intern(db);
1148                    let name_node = ty.name(syntax_db);
1149                    let name = name_node.text(syntax_db);
1150                    if item_id_by_name
1151                        .insert(name.clone(), ImplItemId::Type(impl_type_id))
1152                        .is_some()
1153                    {
1154                        diagnostics.report(&name_node, NameDefinedMultipleTimes(name));
1155                    }
1156                    item_type_asts.insert(impl_type_id, ty);
1157                }
1158                ImplItem::Constant(constant) => {
1159                    let impl_constant_id =
1160                        ImplConstantDefLongId(module_file_id, constant.stable_ptr()).intern(db);
1161                    let name_node = constant.name(syntax_db);
1162                    let name = name_node.text(syntax_db);
1163                    if item_id_by_name
1164                        .insert(name.clone(), ImplItemId::Constant(impl_constant_id))
1165                        .is_some()
1166                    {
1167                        diagnostics.report(
1168                            &name_node,
1169                            SemanticDiagnosticKind::NameDefinedMultipleTimes(name),
1170                        );
1171                    }
1172                    item_constant_asts.insert(impl_constant_id, constant);
1173                }
1174                ImplItem::Impl(imp) => {
1175                    let impl_constant_id =
1176                        ImplImplDefLongId(module_file_id, imp.stable_ptr()).intern(db);
1177                    let name_node = imp.name(syntax_db);
1178                    let name = name_node.text(syntax_db);
1179                    if item_id_by_name
1180                        .insert(name.clone(), ImplItemId::Impl(impl_constant_id))
1181                        .is_some()
1182                    {
1183                        diagnostics.report(
1184                            &name_node,
1185                            SemanticDiagnosticKind::NameDefinedMultipleTimes(name),
1186                        );
1187                    }
1188                    item_impl_asts.insert(impl_constant_id, imp);
1189                }
1190                // Report nothing, a parser diagnostic is reported.
1191                ImplItem::Missing(_) => {}
1192            }
1193        }
1194    }
1195
1196    let mut implicit_impls_id_by_name = OrderedHashMap::default();
1197
1198    let trait_id = concrete_trait.lookup_intern(db).trait_id;
1199    for trait_impl_id in db.trait_impls(trait_id)? {
1200        if item_id_by_name.contains_key(&trait_impl_id.0) {
1201            continue;
1202        }
1203        implicit_impls_id_by_name.insert(trait_impl_id.0, trait_impl_id.1);
1204    }
1205
1206    // It is later verified that all items in this impl match items from `concrete_trait`.
1207    // To ensure exact match (up to trait functions with default implementation), it is sufficient
1208    // to verify here that all items in `concrete_trait` appear in this impl.
1209    let impl_item_names: OrderedHashSet<SmolStr> = item_id_by_name.keys().cloned().collect();
1210
1211    let trait_required_item_names = db.trait_required_item_names(trait_id)?;
1212    let missing_items_in_impl =
1213        trait_required_item_names.difference(&impl_item_names).cloned().collect::<Vec<_>>();
1214    if !missing_items_in_impl.is_empty() {
1215        diagnostics.report(
1216            // TODO(yuval): change this to point to impl declaration (need to add ImplDeclaration
1217            // in cairo_spec).
1218            // TODO(TomerStarkware): make sure we do not report missing if the trait item is
1219            // unsupported in impl.
1220            &impl_ast.name(syntax_db),
1221            SemanticDiagnosticKind::MissingItemsInImpl(missing_items_in_impl),
1222        );
1223    }
1224
1225    Ok(ImplDefinitionData {
1226        diagnostics: diagnostics.build(),
1227        function_asts,
1228        item_type_asts: item_type_asts.into(),
1229        item_id_by_name: item_id_by_name.into(),
1230        item_constant_asts: item_constant_asts.into(),
1231        item_impl_asts: item_impl_asts.into(),
1232        implicit_impls_id_by_name: implicit_impls_id_by_name.into(),
1233    })
1234}
1235
1236/// An helper function to report diagnostics of items in an impl (used in
1237/// priv_impl_definition_data).
1238fn report_invalid_impl_item<Terminal: syntax::node::Terminal>(
1239    syntax_db: &dyn SyntaxGroup,
1240    diagnostics: &mut SemanticDiagnostics,
1241    kw_terminal: Terminal,
1242) {
1243    diagnostics.report(
1244        kw_terminal.as_syntax_node().stable_ptr(),
1245        InvalidImplItem(kw_terminal.text(syntax_db)),
1246    );
1247}
1248
1249/// Handle special cases such as Copy and Drop checking.
1250fn check_special_impls(
1251    db: &dyn SemanticGroup,
1252    diagnostics: &mut SemanticDiagnostics,
1253    lookup_context: ImplLookupContext,
1254    concrete_trait: ConcreteTraitId,
1255    stable_ptr: SyntaxStablePtrId,
1256) -> Maybe<()> {
1257    let ConcreteTraitLongId { trait_id, generic_args } = concrete_trait.lookup_intern(db);
1258    let copy = copy_trait(db);
1259    let drop = drop_trait(db);
1260
1261    if trait_id == copy {
1262        let tys = get_inner_types(db, extract_matches!(generic_args[0], GenericArgumentId::Type))?;
1263        if let Some(inference_error) = tys
1264            .into_iter()
1265            .filter_map(|ty| db.type_info(lookup_context.clone(), ty).to_option())
1266            .flat_map(|info| info.copyable.err())
1267            .next()
1268        {
1269            return Err(diagnostics.report(stable_ptr, InvalidCopyTraitImpl(inference_error)));
1270        }
1271    }
1272    if trait_id == drop {
1273        let tys = get_inner_types(db, extract_matches!(generic_args[0], GenericArgumentId::Type))?;
1274        if let Some(inference_error) = tys
1275            .into_iter()
1276            .filter_map(|ty| db.type_info(lookup_context.clone(), ty).to_option())
1277            .flat_map(|info| info.droppable.err())
1278            .next()
1279        {
1280            return Err(diagnostics.report(stable_ptr, InvalidDropTraitImpl(inference_error)));
1281        }
1282    }
1283
1284    Ok(())
1285}
1286
1287/// Retrieves all the inner types (members of a struct / tuple or variants of an enum).
1288///
1289/// These are the types that are required to implement some trait,
1290/// in order for the original type to be able to implement this trait.
1291///
1292/// For example, a struct containing a type T can implement Drop only if T implements Drop.
1293fn get_inner_types(db: &dyn SemanticGroup, ty: TypeId) -> Maybe<Vec<TypeId>> {
1294    Ok(match ty.lookup_intern(db) {
1295        TypeLongId::Concrete(concrete_type_id) => {
1296            // Look for Copy and Drop trait in the defining module.
1297            match concrete_type_id {
1298                crate::ConcreteTypeId::Struct(concrete_struct_id) => db
1299                    .concrete_struct_members(concrete_struct_id)?
1300                    .values()
1301                    .map(|member| member.ty)
1302                    .collect(),
1303                crate::ConcreteTypeId::Enum(concrete_enum_id) => db
1304                    .concrete_enum_variants(concrete_enum_id)?
1305                    .into_iter()
1306                    .map(|variant| variant.ty)
1307                    .collect(),
1308                crate::ConcreteTypeId::Extern(_) => vec![],
1309            }
1310        }
1311        TypeLongId::Tuple(tys) => tys,
1312        TypeLongId::Snapshot(_) | TypeLongId::Closure(_) => vec![],
1313        TypeLongId::GenericParameter(_) => {
1314            return Err(skip_diagnostic());
1315        }
1316        TypeLongId::Var(_) | TypeLongId::TraitType(_) | TypeLongId::ImplType(_) => {
1317            panic!("Types should be fully resolved at this point.")
1318        }
1319        TypeLongId::Coupon(_) => vec![],
1320        TypeLongId::FixedSizeArray { type_id, .. } => vec![type_id],
1321        TypeLongId::Missing(diag_added) => {
1322            return Err(diag_added);
1323        }
1324    })
1325}
1326
1327// === Trait Filter ===
1328
1329/// A filter for trait lookup that is not based on current inference state. This is
1330/// used for caching queries.
1331#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1332pub struct TraitFilter {
1333    pub trait_id: TraitId,
1334    /// The filter on the generic arguments.
1335    pub generics_filter: GenericsHeadFilter,
1336}
1337
1338/// A lookup filter on generic arguments that is not based on current inference state.
1339/// This is used for caching queries.
1340#[derive(Clone, Debug, Hash, PartialEq, Eq)]
1341pub enum GenericsHeadFilter {
1342    /// No filter is applied. When nothing is known about the generics, this will lead to a
1343    /// wider search.
1344    NoFilter,
1345    /// Generics exists and the first generic parameter has a filter.
1346    /// This is usually enough to considerably reduce the number of searched items.
1347    FirstGenericFilter(GenericArgumentHead),
1348    /// Generics must not exist.
1349    NoGenerics,
1350}
1351
1352/// Query implementation of [crate::db::SemanticGroup::module_impl_ids_for_trait_filter].
1353pub fn module_impl_ids_for_trait_filter(
1354    db: &dyn SemanticGroup,
1355    module_id: ModuleId,
1356    trait_filter: TraitFilter,
1357) -> Maybe<Vec<UninferredImpl>> {
1358    // Get the impls first from the module, do not change this order.
1359    let mut uninferred_impls: OrderedHashSet<UninferredImpl> =
1360        OrderedHashSet::from_iter(module_impl_ids(db, module_id, module_id)?);
1361    for (user_module, containing_module) in &db.priv_module_use_star_modules(module_id).accessible {
1362        if let Ok(star_module_uninferred_impls) =
1363            module_impl_ids(db, *user_module, *containing_module)
1364        {
1365            uninferred_impls.extend(star_module_uninferred_impls);
1366        }
1367    }
1368    let mut res = Vec::new();
1369    for uninferred_impl in uninferred_impls {
1370        let Ok(trait_id) = uninferred_impl.trait_id(db) else { continue };
1371        if trait_id != trait_filter.trait_id {
1372            continue;
1373        }
1374        let Ok(concrete_trait_id) = uninferred_impl.concrete_trait(db) else {
1375            continue;
1376        };
1377        if let Ok(true) = concrete_trait_fits_trait_filter(db, concrete_trait_id, &trait_filter) {
1378            res.push(uninferred_impl);
1379        }
1380    }
1381    Ok(res)
1382}
1383
1384/// Returns the uninferred impls in a module.
1385fn module_impl_ids(
1386    db: &dyn SemanticGroup,
1387    user_module: ModuleId,
1388    containing_module: ModuleId,
1389) -> Maybe<Vec<UninferredImpl>> {
1390    let mut uninferred_impls = Vec::new();
1391    for item in db.priv_module_semantic_data(containing_module)?.items.values() {
1392        if !matches!(
1393            item.item_id,
1394            ModuleItemId::Impl(_) | ModuleItemId::ImplAlias(_) | ModuleItemId::Use(_)
1395        ) {
1396            continue;
1397        }
1398        if !peek_visible_in(db.upcast(), item.visibility, containing_module, user_module) {
1399            continue;
1400        }
1401        match item.item_id {
1402            ModuleItemId::Impl(impl_def_id) => {
1403                uninferred_impls.push(UninferredImpl::Def(impl_def_id));
1404            }
1405            ModuleItemId::ImplAlias(impl_alias_id) => {
1406                uninferred_impls.push(UninferredImpl::ImplAlias(impl_alias_id));
1407            }
1408            ModuleItemId::Use(use_id) => match db.use_resolved_item(use_id) {
1409                Ok(ResolvedGenericItem::Impl(impl_def_id)) => {
1410                    uninferred_impls.push(UninferredImpl::Def(impl_def_id));
1411                }
1412                Ok(ResolvedGenericItem::GenericImplAlias(impl_alias_id)) => {
1413                    uninferred_impls.push(UninferredImpl::ImplAlias(impl_alias_id));
1414                }
1415                _ => {}
1416            },
1417            _ => {}
1418        }
1419    }
1420    Ok(uninferred_impls)
1421}
1422
1423/// Cycle handling for [crate::db::SemanticGroup::module_impl_ids_for_trait_filter].
1424pub fn module_impl_ids_for_trait_filter_cycle(
1425    _db: &dyn SemanticGroup,
1426    _cycle: &salsa::Cycle,
1427    _module_id: &ModuleId,
1428    _trait_filter: &TraitFilter,
1429) -> Maybe<Vec<UninferredImpl>> {
1430    // The diagnostics will be reported from the calling function, specifically from
1431    // `priv_impl_declaration_data_inner`.
1432    Err(skip_diagnostic())
1433}
1434
1435/// Query implementation of [crate::db::SemanticGroup::impl_impl_ids_for_trait_filter].
1436pub fn impl_impl_ids_for_trait_filter(
1437    db: &dyn SemanticGroup,
1438    impl_id: ImplId,
1439    trait_filter: TraitFilter,
1440) -> Maybe<Vec<UninferredImpl>> {
1441    let mut uninferred_impls = Vec::new();
1442    for (_, trait_impl_id) in db.trait_impls(impl_id.concrete_trait(db)?.trait_id(db))?.iter() {
1443        uninferred_impls.push(UninferredImpl::ImplImpl(ImplImplId::new(
1444            impl_id,
1445            *trait_impl_id,
1446            db,
1447        )));
1448    }
1449    let mut res = Vec::new();
1450    for uninferred_impl in uninferred_impls {
1451        let Ok(trait_id) = uninferred_impl.trait_id(db) else { continue };
1452        if trait_id != trait_filter.trait_id {
1453            continue;
1454        }
1455        let Ok(concrete_trait_id) = uninferred_impl.concrete_trait(db) else {
1456            continue;
1457        };
1458        if let Ok(true) = concrete_trait_fits_trait_filter(db, concrete_trait_id, &trait_filter) {
1459            res.push(uninferred_impl);
1460        }
1461    }
1462
1463    Ok(res)
1464}
1465/// Cycle handling for [crate::db::SemanticGroup::impl_impl_ids_for_trait_filter].
1466pub fn impl_impl_ids_for_trait_filter_cycle(
1467    _db: &dyn SemanticGroup,
1468    _cycle: &salsa::Cycle,
1469    _imp: &ImplId,
1470    _trait_filter: &TraitFilter,
1471) -> Maybe<Vec<UninferredImpl>> {
1472    // The diagnostics will be reported from the calling function, specifically from
1473    // `priv_impl_declaration_data_inner`.
1474    Err(skip_diagnostic())
1475}
1476
1477/// Checks whether an [ImplDefId] passes a [TraitFilter].
1478fn concrete_trait_fits_trait_filter(
1479    db: &dyn SemanticGroup,
1480    concrete_trait_id: ConcreteTraitId,
1481    trait_filter: &TraitFilter,
1482) -> Maybe<bool> {
1483    if trait_filter.trait_id != concrete_trait_id.trait_id(db) {
1484        return Ok(false);
1485    }
1486    let generic_args = concrete_trait_id.generic_args(db);
1487    let first_generic = generic_args.first();
1488    Ok(match &trait_filter.generics_filter {
1489        GenericsHeadFilter::NoFilter => true,
1490        GenericsHeadFilter::FirstGenericFilter(constraint_head) => {
1491            let Some(first_generic) = first_generic else {
1492                return Ok(false);
1493            };
1494            let Some(first_generic_head) = first_generic.head(db) else {
1495                return Ok(true);
1496            };
1497            &first_generic_head == constraint_head
1498        }
1499        GenericsHeadFilter::NoGenerics => first_generic.is_none(),
1500    })
1501}
1502
1503#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
1504pub enum ImplOrModuleById {
1505    Impl(ImplId),
1506    Module(ModuleId),
1507}
1508impl From<ImplId> for ImplOrModuleById {
1509    fn from(impl_id: ImplId) -> Self {
1510        ImplOrModuleById::Impl(impl_id)
1511    }
1512}
1513impl From<ModuleId> for ImplOrModuleById {
1514    fn from(module_id: ModuleId) -> Self {
1515        ImplOrModuleById::Module(module_id)
1516    }
1517}
1518
1519impl Ord for ImplOrModuleById {
1520    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
1521        match (self, other) {
1522            (ImplOrModuleById::Impl(imp), ImplOrModuleById::Impl(other_impl)) => {
1523                imp.get_internal_id().cmp(other_impl.get_internal_id())
1524            }
1525            (ImplOrModuleById::Module(module), ImplOrModuleById::Module(other_module)) => {
1526                match (module, other_module) {
1527                    (ModuleId::CrateRoot(crate_id), ModuleId::CrateRoot(other_crate_id)) => {
1528                        crate_id.get_internal_id().cmp(other_crate_id.get_internal_id())
1529                    }
1530                    (ModuleId::CrateRoot(_), ModuleId::Submodule(_)) => std::cmp::Ordering::Less,
1531                    (ModuleId::Submodule(_), ModuleId::CrateRoot(_)) => std::cmp::Ordering::Greater,
1532                    (ModuleId::Submodule(module_id), ModuleId::Submodule(other_module_id)) => {
1533                        module_id.get_internal_id().cmp(other_module_id.get_internal_id())
1534                    }
1535                }
1536            }
1537            (ImplOrModuleById::Impl(_), ImplOrModuleById::Module(_)) => std::cmp::Ordering::Less,
1538            (ImplOrModuleById::Module(_), ImplOrModuleById::Impl(_)) => std::cmp::Ordering::Greater,
1539        }
1540    }
1541}
1542impl PartialOrd for ImplOrModuleById {
1543    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
1544        Some(self.cmp(other))
1545    }
1546}
1547
1548#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, DebugWithDb)]
1549#[debug_db(dyn SemanticGroup + 'static)]
1550pub struct ImplLookupContext {
1551    pub modules_and_impls: BTreeSet<ImplOrModuleById>,
1552    pub generic_params: Vec<GenericParamId>,
1553}
1554impl ImplLookupContext {
1555    pub fn new(module_id: ModuleId, generic_params: Vec<GenericParamId>) -> ImplLookupContext {
1556        Self { modules_and_impls: [ImplOrModuleById::Module(module_id)].into(), generic_params }
1557    }
1558    pub fn insert_lookup_scope(&mut self, db: &dyn SemanticGroup, imp: &UninferredImpl) {
1559        let defs_db = db.upcast();
1560        let item = match imp {
1561            UninferredImpl::Def(impl_def_id) => impl_def_id.module_file_id(defs_db).0.into(),
1562            UninferredImpl::ImplAlias(impl_alias_id) => {
1563                impl_alias_id.module_file_id(defs_db).0.into()
1564            }
1565            UninferredImpl::GenericParam(param) => param.module_file_id(defs_db).0.into(),
1566            UninferredImpl::ImplImpl(impl_impl_id) => impl_impl_id.impl_id.into(),
1567            UninferredImpl::GeneratedImpl(_) => {
1568                // GeneratedImpls do not extend the lookup context.
1569                return;
1570            }
1571        };
1572        self.modules_and_impls.insert(item);
1573    }
1574    pub fn insert_module(&mut self, module_id: ModuleId) -> bool {
1575        self.modules_and_impls.insert(ImplOrModuleById::Module(module_id))
1576    }
1577
1578    pub fn insert_impl(&mut self, impl_id: ImplId) -> bool {
1579        self.modules_and_impls.insert(ImplOrModuleById::Impl(impl_id))
1580    }
1581}
1582
1583/// A candidate impl for later inference.
1584#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, SemanticObject)]
1585pub enum UninferredImpl {
1586    Def(ImplDefId),
1587    ImplAlias(ImplAliasId),
1588    GenericParam(GenericParamId),
1589    ImplImpl(ImplImplId),
1590    GeneratedImpl(UninferredGeneratedImplId),
1591}
1592impl UninferredImpl {
1593    pub fn concrete_trait(&self, db: &dyn SemanticGroup) -> Maybe<ConcreteTraitId> {
1594        match self {
1595            UninferredImpl::Def(impl_def_id) => db.impl_def_concrete_trait(*impl_def_id),
1596            UninferredImpl::ImplAlias(impl_alias_id) => {
1597                let impl_id = db.impl_alias_resolved_impl(*impl_alias_id)?;
1598                impl_id.concrete_trait(db)
1599            }
1600            UninferredImpl::GenericParam(param) => {
1601                let param =
1602                    extract_matches!(db.generic_param_semantic(*param)?, GenericParam::Impl);
1603                param.concrete_trait
1604            }
1605            UninferredImpl::ImplImpl(impl_impl_id) => db.impl_impl_concrete_trait(*impl_impl_id),
1606            UninferredImpl::GeneratedImpl(generated_impl) => Ok(generated_impl.concrete_trait(db)),
1607        }
1608    }
1609
1610    fn trait_id(&self, db: &dyn SemanticGroup) -> Maybe<TraitId> {
1611        match self {
1612            UninferredImpl::Def(impl_def_id) => db.impl_def_trait(*impl_def_id),
1613            UninferredImpl::ImplAlias(impl_alias_id) => {
1614                let impl_def_id = db.impl_alias_impl_def(*impl_alias_id)?;
1615                db.impl_def_trait(impl_def_id)
1616            }
1617            UninferredImpl::GenericParam(param) => {
1618                let param =
1619                    extract_matches!(db.generic_param_semantic(*param)?, GenericParam::Impl);
1620                param.concrete_trait.map(|concrete_trait| concrete_trait.trait_id(db))
1621            }
1622            UninferredImpl::ImplImpl(impl_impl_id) => db
1623                .impl_impl_concrete_trait(*impl_impl_id)
1624                .map(|concrete_trait| concrete_trait.trait_id(db)),
1625            UninferredImpl::GeneratedImpl(generated_impl) => Ok(generated_impl.trait_id(db)),
1626        }
1627    }
1628
1629    pub fn lookup_scope(&self, db: &dyn SemanticGroup) -> ImplOrModuleById {
1630        let defs_db = db.upcast();
1631        match self {
1632            UninferredImpl::Def(impl_def_id) => impl_def_id.module_file_id(defs_db).0.into(),
1633            UninferredImpl::ImplAlias(impl_alias_id) => {
1634                impl_alias_id.module_file_id(defs_db).0.into()
1635            }
1636            UninferredImpl::GenericParam(param) => param.module_file_id(defs_db).0.into(),
1637            UninferredImpl::ImplImpl(impl_impl_id) => impl_impl_id.impl_id.into(),
1638            UninferredImpl::GeneratedImpl(generated_impl) => {
1639                generated_impl.concrete_trait(db).trait_id(db).module_file_id(defs_db).0.into()
1640            }
1641        }
1642    }
1643}
1644impl DebugWithDb<dyn SemanticGroup> for UninferredImpl {
1645    fn fmt(&self, f: &mut std::fmt::Formatter<'_>, db: &dyn SemanticGroup) -> std::fmt::Result {
1646        match self {
1647            UninferredImpl::Def(impl_def) => write!(f, "{:?}", impl_def.full_path(db.upcast())),
1648            UninferredImpl::ImplAlias(impl_alias) => {
1649                write!(f, "{:?}", impl_alias.full_path(db.upcast()))
1650            }
1651            UninferredImpl::GenericParam(param) => {
1652                write!(f, "generic param {}", param.name(db.upcast()).unwrap_or_else(|| "_".into()))
1653            }
1654            UninferredImpl::ImplImpl(impl_impl) => impl_impl.fmt(f, db.elongate()),
1655            UninferredImpl::GeneratedImpl(generated_impl) => generated_impl.fmt(f, db.elongate()),
1656        }
1657    }
1658}
1659
1660define_short_id!(
1661    UninferredGeneratedImplId,
1662    UninferredGeneratedImplLongId,
1663    SemanticGroup,
1664    lookup_intern_uninferred_generated_impl,
1665    intern_uninferred_generated_impl
1666);
1667semantic_object_for_id!(
1668    UninferredGeneratedImplId,
1669    lookup_intern_uninferred_generated_impl,
1670    intern_uninferred_generated_impl,
1671    UninferredGeneratedImplLongId
1672);
1673
1674impl UninferredGeneratedImplId {
1675    pub fn concrete_trait(self, db: &dyn SemanticGroup) -> ConcreteTraitId {
1676        db.lookup_intern_uninferred_generated_impl(self).concrete_trait
1677    }
1678
1679    pub fn trait_id(&self, db: &dyn SemanticGroup) -> TraitId {
1680        self.concrete_trait(db).trait_id(db)
1681    }
1682}
1683
1684/// Generated impls before inference, see GeneratedImplLongId for more details.
1685#[derive(Clone, Debug, Hash, PartialEq, Eq, SemanticObject)]
1686pub struct UninferredGeneratedImplLongId {
1687    pub concrete_trait: ConcreteTraitId,
1688    pub generic_params: Vec<GenericParam>,
1689    pub impl_items: GeneratedImplItems,
1690}
1691
1692impl DebugWithDb<dyn SemanticGroup> for UninferredGeneratedImplLongId {
1693    fn fmt(
1694        &self,
1695        f: &mut std::fmt::Formatter<'_>,
1696        db: &(dyn SemanticGroup + 'static),
1697    ) -> std::fmt::Result {
1698        write!(f, "Generated {:?}", self.concrete_trait.debug(db))
1699    }
1700}
1701
1702/// Finds all the implementations of a concrete trait, in a specific lookup context.
1703pub fn find_candidates_at_context(
1704    db: &dyn SemanticGroup,
1705    lookup_context: &ImplLookupContext,
1706    filter: &TraitFilter,
1707) -> Maybe<OrderedHashSet<UninferredImpl>> {
1708    let mut res = OrderedHashSet::default();
1709    for generic_param_id in &lookup_context.generic_params {
1710        if !matches!(generic_param_id.kind(db.upcast()), GenericKind::Impl) {
1711            continue;
1712        };
1713        let Ok(trait_id) = db.generic_impl_param_trait(*generic_param_id) else {
1714            continue;
1715        };
1716        if filter.trait_id != trait_id {
1717            continue;
1718        }
1719        let Ok(generic_param_semantic) = db.generic_param_semantic(*generic_param_id) else {
1720            continue;
1721        };
1722        let param = extract_matches!(generic_param_semantic, GenericParam::Impl);
1723        let Ok(imp_concrete_trait_id) = param.concrete_trait else { continue };
1724        let Ok(trait_fits_filter) =
1725            concrete_trait_fits_trait_filter(db, imp_concrete_trait_id, filter)
1726        else {
1727            continue;
1728        };
1729        if !trait_fits_filter {
1730            continue;
1731        }
1732        res.insert(UninferredImpl::GenericParam(*generic_param_id));
1733    }
1734    for module_or_impl_id in &lookup_context.modules_and_impls {
1735        let Ok(imps) = (match module_or_impl_id {
1736            ImplOrModuleById::Module(module_id) => {
1737                db.module_impl_ids_for_trait_filter(*module_id, filter.clone())
1738            }
1739            ImplOrModuleById::Impl(impl_id) => {
1740                db.impl_impl_ids_for_trait_filter(*impl_id, filter.clone())
1741            }
1742        }) else {
1743            continue;
1744        };
1745        for imp in imps {
1746            res.insert(imp);
1747        }
1748    }
1749    Ok(res)
1750}
1751
1752/// Finds the generated candidate for a concrete trait.
1753pub fn find_closure_generated_candidate(
1754    db: &dyn SemanticGroup,
1755    concrete_trait_id: ConcreteTraitId,
1756) -> Option<UninferredImpl> {
1757    let GenericArgumentId::Type(closure_type) = *concrete_trait_id.generic_args(db).first()? else {
1758        return None;
1759    };
1760    let TypeLongId::Closure(closure_type_long) = closure_type.lookup_intern(db) else {
1761        return None;
1762    };
1763
1764    // Handles the special cases of `Copy`, `Drop`, `Destruct` and `PanicDestruct`.
1765    let mem_trait_generic_params = |trait_id, neg_impl_trait: Option<_>| {
1766        let id = db.trait_generic_params(trait_id).unwrap().first().unwrap().id();
1767        chain!(
1768            closure_type_long.captured_types.iter().map(|ty| {
1769                GenericParam::Impl(GenericParamImpl {
1770                    id,
1771                    concrete_trait: Maybe::Ok(db.intern_concrete_trait(ConcreteTraitLongId {
1772                        trait_id,
1773                        generic_args: vec![GenericArgumentId::Type(*ty)],
1774                    })),
1775                    type_constraints: Default::default(),
1776                })
1777            }),
1778            neg_impl_trait.map(|neg_impl_trait| {
1779                GenericParam::NegImpl(GenericParamImpl {
1780                    id,
1781                    concrete_trait: Maybe::Ok(neg_impl_trait),
1782                    type_constraints: Default::default(),
1783                })
1784            })
1785        )
1786        .collect()
1787    };
1788    let handle_mem_trait = |trait_id, neg_impl_trait: Option<_>| {
1789        (concrete_trait_id, mem_trait_generic_params(trait_id, neg_impl_trait), [].into())
1790    };
1791    let (concrete_trait, generic_params, impl_items) = match concrete_trait_id.trait_id(db) {
1792        trait_id if trait_id == fn_once_trait(db) => {
1793            let concrete_trait = ConcreteTraitLongId {
1794                trait_id,
1795                generic_args: vec![
1796                    GenericArgumentId::Type(closure_type),
1797                    GenericArgumentId::Type(
1798                        TypeLongId::Tuple(closure_type_long.param_tys.clone()).intern(db),
1799                    ),
1800                ],
1801            }
1802            .intern(db);
1803            let ret_ty = db.trait_type_by_name(trait_id, "Output".into()).unwrap().unwrap();
1804
1805            let id = db.trait_generic_params(trait_id).unwrap().first().unwrap().id();
1806            // FnOnce is generated only if there is no fn trait.
1807            let param: GenericParam = GenericParam::NegImpl(GenericParamImpl {
1808                id,
1809                concrete_trait: Maybe::Ok(
1810                    ConcreteTraitLongId {
1811                        trait_id: fn_trait(db),
1812                        generic_args: vec![
1813                            GenericArgumentId::Type(closure_type),
1814                            GenericArgumentId::Type(
1815                                TypeLongId::Tuple(closure_type_long.param_tys.clone()).intern(db),
1816                            ),
1817                        ],
1818                    }
1819                    .intern(db),
1820                ),
1821                type_constraints: Default::default(),
1822            });
1823            (concrete_trait, vec![param], [(ret_ty, closure_type_long.ret_ty)].into())
1824        }
1825        trait_id if trait_id == fn_trait(db) => {
1826            let concrete_trait = ConcreteTraitLongId {
1827                trait_id,
1828                generic_args: vec![
1829                    GenericArgumentId::Type(closure_type),
1830                    GenericArgumentId::Type(
1831                        TypeLongId::Tuple(closure_type_long.param_tys.clone()).intern(db),
1832                    ),
1833                ],
1834            }
1835            .intern(db);
1836            let ret_ty = db.trait_type_by_name(trait_id, "Output".into()).unwrap().unwrap();
1837
1838            (
1839                concrete_trait,
1840                // Makes the generated impl of fn_trait available only if the closure is copyable.
1841                mem_trait_generic_params(copy_trait(db), None),
1842                [(ret_ty, closure_type_long.ret_ty)].into(),
1843            )
1844        }
1845        trait_id if trait_id == drop_trait(db) => handle_mem_trait(trait_id, None),
1846        trait_id if trait_id == destruct_trait(db) => {
1847            handle_mem_trait(trait_id, Some(concrete_drop_trait(db, closure_type)))
1848        }
1849        trait_id if trait_id == panic_destruct_trait(db) => {
1850            handle_mem_trait(trait_id, Some(concrete_destruct_trait(db, closure_type)))
1851        }
1852        trait_id if trait_id == copy_trait(db) => handle_mem_trait(trait_id, None),
1853        _ => return None,
1854    };
1855    Some(UninferredImpl::GeneratedImpl(
1856        UninferredGeneratedImplLongId {
1857            concrete_trait,
1858            generic_params,
1859            impl_items: GeneratedImplItems(impl_items),
1860        }
1861        .intern(db),
1862    ))
1863}
1864
1865/// Checks if an impl of a trait function with a given self_ty exists.
1866/// This function does not change the state of the inference context.
1867///
1868/// `inference_errors` are aggregated here but are not reported here as diagnostics.
1869/// The caller has to make sure the diagnostics are reported appropriately.
1870pub fn can_infer_impl_by_self(
1871    ctx: &ComputationContext<'_>,
1872    inference_errors: &mut Vec<(TraitFunctionId, InferenceError)>,
1873    trait_function_id: TraitFunctionId,
1874    self_ty: TypeId,
1875    stable_ptr: SyntaxStablePtrId,
1876) -> bool {
1877    let mut temp_inference_data = ctx.resolver.data.inference_data.temporary_clone();
1878    let mut temp_inference = temp_inference_data.inference(ctx.db);
1879    let lookup_context = ctx.resolver.impl_lookup_context();
1880
1881    let Some((concrete_trait_id, _)) = temp_inference.infer_concrete_trait_by_self(
1882        trait_function_id,
1883        self_ty,
1884        &lookup_context,
1885        Some(stable_ptr),
1886        |err| inference_errors.push((trait_function_id, err)),
1887    ) else {
1888        return false;
1889    };
1890    // Find impls for it.
1891    if let Err(err_set) = temp_inference.solve() {
1892        // Error is propagated and will be reported later.
1893        if let Some(err) = temp_inference.consume_error_without_reporting(err_set) {
1894            inference_errors.push((trait_function_id, err));
1895        }
1896    }
1897    match temp_inference.trait_solution_set(
1898        concrete_trait_id,
1899        ImplVarTraitItemMappings::default(),
1900        lookup_context.clone(),
1901    ) {
1902        Ok(SolutionSet::Unique(_) | SolutionSet::Ambiguous(_)) => true,
1903        Ok(SolutionSet::None) => {
1904            inference_errors
1905                .push((trait_function_id, InferenceError::NoImplsFound(concrete_trait_id)));
1906            false
1907        }
1908        Err(err_set) => {
1909            // Error is propagated and will be reported later.
1910            if let Some(err) = temp_inference.consume_error_without_reporting(err_set) {
1911                inference_errors.push((trait_function_id, err));
1912            }
1913            false
1914        }
1915    }
1916}
1917
1918/// Returns an impl of a given trait function with a given self_ty, as well as the number of
1919/// snapshots needed to be added to it.
1920pub fn infer_impl_by_self(
1921    ctx: &mut ComputationContext<'_>,
1922    trait_function_id: TraitFunctionId,
1923    self_ty: TypeId,
1924    stable_ptr: SyntaxStablePtrId,
1925    generic_args_syntax: Option<Vec<GenericArg>>,
1926) -> Maybe<(FunctionId, usize)> {
1927    let lookup_context = ctx.resolver.impl_lookup_context();
1928    let (concrete_trait_id, n_snapshots) = ctx
1929        .resolver
1930        .inference()
1931        .infer_concrete_trait_by_self(
1932            trait_function_id,
1933            self_ty,
1934            &lookup_context,
1935            Some(stable_ptr),
1936            |_| {},
1937        )
1938        .ok_or_else(skip_diagnostic)?;
1939
1940    let concrete_trait_function_id =
1941        ConcreteTraitGenericFunctionLongId::new(ctx.db, concrete_trait_id, trait_function_id)
1942            .intern(ctx.db);
1943    let trait_func_generic_params =
1944        ctx.db.concrete_trait_function_generic_params(concrete_trait_function_id).unwrap();
1945    let generic_args = ctx.resolver.resolve_generic_args(
1946        ctx.diagnostics,
1947        &trait_func_generic_params,
1948        &generic_args_syntax.unwrap_or_default(),
1949        stable_ptr,
1950    )?;
1951
1952    let impl_lookup_context = ctx.resolver.impl_lookup_context();
1953    let inference = &mut ctx.resolver.inference();
1954    let generic_function = inference.infer_trait_generic_function(
1955        concrete_trait_function_id,
1956        &impl_lookup_context,
1957        Some(stable_ptr),
1958    );
1959
1960    Ok((
1961        FunctionLongId { function: ConcreteFunction { generic_function, generic_args } }
1962            .intern(ctx.db),
1963        n_snapshots,
1964    ))
1965}
1966
1967/// Returns all the trait functions that fit the given function name, can be called on the given
1968/// `self_ty`, and have at least one implementation in context.
1969///
1970/// `inference_errors` are aggregated here but are not reported here as diagnostics.
1971/// The caller has to make sure the diagnostics are reported appropriately.
1972pub fn filter_candidate_traits(
1973    ctx: &mut ComputationContext<'_>,
1974    inference_errors: &mut Vec<(TraitFunctionId, InferenceError)>,
1975    self_ty: TypeId,
1976    candidate_traits: &[TraitId],
1977    function_name: SmolStr,
1978    stable_ptr: SyntaxStablePtrId,
1979) -> Vec<TraitFunctionId> {
1980    let mut candidates = Vec::new();
1981    for trait_id in candidate_traits.iter().copied() {
1982        let Ok(trait_functions) = ctx.db.trait_functions(trait_id) else {
1983            continue;
1984        };
1985        for (name, trait_function) in trait_functions {
1986            if name == function_name
1987                && can_infer_impl_by_self(
1988                    ctx,
1989                    inference_errors,
1990                    trait_function,
1991                    self_ty,
1992                    stable_ptr,
1993                )
1994            {
1995                candidates.push(trait_function);
1996            }
1997        }
1998    }
1999    candidates
2000}
2001
2002// === Impl Item Type definition ===
2003
2004#[derive(Clone, Debug, PartialEq, Eq, DebugWithDb)]
2005#[debug_db(dyn SemanticGroup + 'static)]
2006pub struct ImplItemTypeData {
2007    type_alias_data: TypeAliasData,
2008    trait_type_id: Maybe<TraitTypeId>,
2009    /// The diagnostics of the module type alias, including the ones for the type alias itself.
2010    diagnostics: Diagnostics<SemanticDiagnostic>,
2011}
2012
2013// --- Selectors ---
2014
2015/// Query implementation of [crate::db::SemanticGroup::impl_type_def_semantic_diagnostics].
2016pub fn impl_type_def_semantic_diagnostics(
2017    db: &dyn SemanticGroup,
2018    impl_type_def_id: ImplTypeDefId,
2019) -> Diagnostics<SemanticDiagnostic> {
2020    db.priv_impl_type_semantic_data(impl_type_def_id, false)
2021        .map(|data| data.diagnostics)
2022        .unwrap_or_default()
2023}
2024
2025/// Query implementation of [crate::db::SemanticGroup::impl_type_def_resolved_type].
2026pub fn impl_type_def_resolved_type(
2027    db: &dyn SemanticGroup,
2028    impl_type_def_id: ImplTypeDefId,
2029) -> Maybe<TypeId> {
2030    db.priv_impl_type_semantic_data(impl_type_def_id, false)?.type_alias_data.resolved_type
2031}
2032
2033/// Cycle handling for [crate::db::SemanticGroup::impl_type_def_resolved_type].
2034pub fn impl_type_def_resolved_type_cycle(
2035    db: &dyn SemanticGroup,
2036    _cycle: &salsa::Cycle,
2037    impl_type_def_id: &ImplTypeDefId,
2038) -> Maybe<TypeId> {
2039    db.priv_impl_type_semantic_data(*impl_type_def_id, true)?.type_alias_data.resolved_type
2040}
2041
2042/// Query implementation of [crate::db::SemanticGroup::impl_type_def_generic_params].
2043pub fn impl_type_def_generic_params(
2044    db: &dyn SemanticGroup,
2045    impl_type_def_id: ImplTypeDefId,
2046) -> Maybe<Vec<GenericParam>> {
2047    Ok(db.priv_impl_type_def_generic_params_data(impl_type_def_id)?.generic_params)
2048}
2049
2050/// Query implementation of [crate::db::SemanticGroup::impl_type_def_attributes].
2051pub fn impl_type_def_attributes(
2052    db: &dyn SemanticGroup,
2053    impl_type_def_id: ImplTypeDefId,
2054) -> Maybe<Vec<Attribute>> {
2055    Ok(db.priv_impl_type_semantic_data(impl_type_def_id, false)?.type_alias_data.attributes)
2056}
2057
2058/// Query implementation of [crate::db::SemanticGroup::impl_type_def_resolver_data].
2059pub fn impl_type_def_resolver_data(
2060    db: &dyn SemanticGroup,
2061    impl_type_def_id: ImplTypeDefId,
2062) -> Maybe<Arc<ResolverData>> {
2063    Ok(db.priv_impl_type_semantic_data(impl_type_def_id, false)?.type_alias_data.resolver_data)
2064}
2065
2066/// Query implementation of [crate::db::SemanticGroup::impl_type_def_trait_type].
2067pub fn impl_type_def_trait_type(
2068    db: &dyn SemanticGroup,
2069    impl_type_def_id: ImplTypeDefId,
2070) -> Maybe<TraitTypeId> {
2071    db.priv_impl_type_semantic_data(impl_type_def_id, false)?.trait_type_id
2072}
2073
2074// --- Computation ---
2075
2076/// Query implementation of [crate::db::SemanticGroup::priv_impl_type_semantic_data].
2077pub fn priv_impl_type_semantic_data(
2078    db: &dyn SemanticGroup,
2079    impl_type_def_id: ImplTypeDefId,
2080    in_cycle: bool,
2081) -> Maybe<ImplItemTypeData> {
2082    let mut diagnostics = SemanticDiagnostics::default();
2083    let impl_type_defs = db.impl_types(impl_type_def_id.impl_def_id(db.upcast()))?;
2084    let impl_type_def_ast = impl_type_defs.get(&impl_type_def_id).to_maybe()?;
2085    let generic_params_data = db.priv_impl_type_def_generic_params_data(impl_type_def_id)?;
2086    let lookup_item_id = LookupItemId::ImplItem(ImplItemId::Type(impl_type_def_id));
2087
2088    let trait_type_id =
2089        validate_impl_item_type(db, &mut diagnostics, impl_type_def_id, impl_type_def_ast);
2090
2091    if in_cycle {
2092        Ok(ImplItemTypeData {
2093            type_alias_data: type_alias_semantic_data_cycle_helper(
2094                db,
2095                &mut diagnostics,
2096                impl_type_def_ast,
2097                lookup_item_id,
2098                generic_params_data,
2099            )?,
2100            trait_type_id,
2101            diagnostics: diagnostics.build(),
2102        })
2103    } else {
2104        // TODO(yuval): resolve type aliases later, like in module type aliases, to avoid cycles in
2105        // non-cyclic chains.
2106        Ok(ImplItemTypeData {
2107            type_alias_data: type_alias_semantic_data_helper(
2108                db,
2109                &mut diagnostics,
2110                impl_type_def_ast,
2111                lookup_item_id,
2112                generic_params_data,
2113            )?,
2114            trait_type_id,
2115            diagnostics: diagnostics.build(),
2116        })
2117    }
2118}
2119
2120/// Cycle handling for [crate::db::SemanticGroup::priv_impl_type_semantic_data].
2121pub fn priv_impl_type_semantic_data_cycle(
2122    db: &dyn SemanticGroup,
2123    _cycle: &salsa::Cycle,
2124    impl_type_def_id: &ImplTypeDefId,
2125    _in_cycle: &bool,
2126) -> Maybe<ImplItemTypeData> {
2127    // Forwarding cycle handling to `priv_impl_type_semantic_data` handler.
2128    priv_impl_type_semantic_data(db, *impl_type_def_id, true)
2129}
2130
2131/// Query implementation of [crate::db::SemanticGroup::priv_impl_type_def_generic_params_data].
2132pub fn priv_impl_type_def_generic_params_data(
2133    db: &dyn SemanticGroup,
2134    impl_type_def_id: ImplTypeDefId,
2135) -> Maybe<GenericParamsData> {
2136    let defs_db = db.upcast();
2137    let module_file_id = impl_type_def_id.module_file_id(defs_db);
2138    let impl_type_def_ast = db.impl_type_by_id(impl_type_def_id)?.to_maybe()?;
2139    let lookup_item_id = LookupItemId::ImplItem(ImplItemId::Type(impl_type_def_id));
2140
2141    let impl_resolver_data = db.impl_def_resolver_data(impl_type_def_id.impl_def_id(defs_db))?;
2142    type_alias_generic_params_data_helper(
2143        db,
2144        module_file_id,
2145        &impl_type_def_ast,
2146        lookup_item_id,
2147        Some(impl_resolver_data),
2148    )
2149}
2150
2151/// Validates the impl item type, and returns the matching trait type id.
2152fn validate_impl_item_type(
2153    db: &dyn SemanticGroup,
2154    diagnostics: &mut SemanticDiagnostics,
2155    impl_type_def_id: ImplTypeDefId,
2156    impl_type_ast: &ast::ItemTypeAlias,
2157) -> Maybe<TraitTypeId> {
2158    let defs_db = db.upcast();
2159    let syntax_db = db.upcast();
2160    let impl_def_id = impl_type_def_id.impl_def_id(defs_db);
2161    let concrete_trait_id = db.impl_def_concrete_trait(impl_def_id)?;
2162    let trait_id = concrete_trait_id.trait_id(db);
2163    let type_name = impl_type_def_id.name(defs_db);
2164    let trait_type_id = db.trait_type_by_name(trait_id, type_name.clone())?.ok_or_else(|| {
2165        diagnostics.report(impl_type_ast, ImplItemNotInTrait {
2166            impl_def_id,
2167            impl_item_name: type_name,
2168            trait_id,
2169            item_kind: "type".into(),
2170        })
2171    })?;
2172
2173    // TODO(yuval): add validations for generic parameters, then remove this.
2174    // Generic parameters are not yet supported, make sure there are none.
2175    let generic_params_node = impl_type_ast.generic_params(syntax_db);
2176    if !generic_params_node.is_empty(syntax_db) {
2177        diagnostics.report(&generic_params_node, GenericsNotSupportedInItem {
2178            scope: "Impl".into(),
2179            item_kind: "type".into(),
2180        });
2181    }
2182
2183    Ok(trait_type_id)
2184}
2185
2186// === Impl Type ===
2187
2188/// Query implementation of [crate::db::SemanticGroup::impl_type_concrete_implized].
2189pub fn impl_type_concrete_implized(
2190    db: &dyn SemanticGroup,
2191    impl_type_id: ImplTypeId,
2192) -> Maybe<TypeId> {
2193    let concrete_impl = match impl_type_id.impl_id().lookup_intern(db) {
2194        ImplLongId::Concrete(concrete_impl) => concrete_impl,
2195        ImplLongId::ImplImpl(imp_impl_id) => {
2196            let ImplLongId::Concrete(concrete_impl) =
2197                db.impl_impl_concrete_implized(imp_impl_id)?.lookup_intern(db)
2198            else {
2199                return Ok(TypeLongId::ImplType(impl_type_id).intern(db));
2200            };
2201            concrete_impl
2202        }
2203        ImplLongId::GenericParameter(_) | ImplLongId::TraitImpl(_) | ImplLongId::ImplVar(_) => {
2204            return Ok(TypeLongId::ImplType(impl_type_id).intern(db));
2205        }
2206        ImplLongId::GeneratedImpl(generated) => {
2207            return Ok(*generated.lookup_intern(db).impl_items.0.get(&impl_type_id.ty()).unwrap());
2208        }
2209    };
2210
2211    let impl_def_id = concrete_impl.impl_def_id(db);
2212    let ty = db.trait_type_implized_by_context(impl_type_id.ty(), impl_def_id);
2213    let Ok(ty) = ty else {
2214        return ty;
2215    };
2216
2217    let substitution = &concrete_impl.substitution(db)?;
2218    SubstitutionRewriter { db, substitution }.rewrite(ty)
2219}
2220
2221/// Cycle handling for [crate::db::SemanticGroup::impl_type_concrete_implized].
2222pub fn impl_type_concrete_implized_cycle(
2223    db: &dyn SemanticGroup,
2224    _cycle: &salsa::Cycle,
2225    impl_type_id: &ImplTypeId,
2226) -> Maybe<TypeId> {
2227    // Forwarding cycle handling to `priv_impl_type_semantic_data` handler.
2228    impl_type_concrete_implized(db, *impl_type_id)
2229}
2230
2231// === Impl Item Constant definition ===
2232
2233#[derive(Clone, Debug, PartialEq, Eq, DebugWithDb)]
2234#[debug_db(dyn SemanticGroup + 'static)]
2235pub struct ImplItemConstantData {
2236    constant_data: ConstantData,
2237    trait_constant_id: Maybe<TraitConstantId>,
2238    /// The diagnostics of the impl constant, including the ones for the constant itself.
2239    diagnostics: Diagnostics<SemanticDiagnostic>,
2240}
2241
2242// --- Selectors ---
2243
2244/// Query implementation of [crate::db::SemanticGroup::impl_constant_def_semantic_diagnostics].
2245pub fn impl_constant_def_semantic_diagnostics(
2246    db: &dyn SemanticGroup,
2247    impl_constant_def_id: ImplConstantDefId,
2248) -> Diagnostics<SemanticDiagnostic> {
2249    db.priv_impl_constant_semantic_data(impl_constant_def_id, false)
2250        .map(|data| data.diagnostics)
2251        .unwrap_or_default()
2252}
2253
2254/// Query implementation of [crate::db::SemanticGroup::impl_constant_def_value].
2255pub fn impl_constant_def_value(
2256    db: &dyn SemanticGroup,
2257    impl_constant_def_id: ImplConstantDefId,
2258) -> Maybe<ConstValueId> {
2259    Ok(db.priv_impl_constant_semantic_data(impl_constant_def_id, false)?.constant_data.const_value)
2260}
2261
2262/// Cycle handling for [crate::db::SemanticGroup::impl_constant_def_value].
2263pub fn impl_constant_def_value_cycle(
2264    db: &dyn SemanticGroup,
2265    _cycle: &salsa::Cycle,
2266    impl_constant_def_id: &ImplConstantDefId,
2267) -> Maybe<ConstValueId> {
2268    Ok(db.priv_impl_constant_semantic_data(*impl_constant_def_id, true)?.constant_data.const_value)
2269}
2270
2271/// Query implementation of [crate::db::SemanticGroup::impl_constant_def_resolver_data].
2272pub fn impl_constant_def_resolver_data(
2273    db: &dyn SemanticGroup,
2274    impl_constant_def_id: ImplConstantDefId,
2275) -> Maybe<Arc<ResolverData>> {
2276    Ok(db
2277        .priv_impl_constant_semantic_data(impl_constant_def_id, false)?
2278        .constant_data
2279        .resolver_data)
2280}
2281
2282/// Query implementation of [crate::db::SemanticGroup::impl_constant_def_trait_constant].
2283pub fn impl_constant_def_trait_constant(
2284    db: &dyn SemanticGroup,
2285    impl_constant_def_id: ImplConstantDefId,
2286) -> Maybe<TraitConstantId> {
2287    db.priv_impl_constant_semantic_data(impl_constant_def_id, false)?.trait_constant_id
2288}
2289
2290// --- Computation ---
2291
2292/// Query implementation of [crate::db::SemanticGroup::priv_impl_constant_semantic_data].
2293pub fn priv_impl_constant_semantic_data(
2294    db: &dyn SemanticGroup,
2295    impl_constant_def_id: ImplConstantDefId,
2296    in_cycle: bool,
2297) -> Maybe<ImplItemConstantData> {
2298    let mut diagnostics = SemanticDiagnostics::default();
2299    let impl_def_id = impl_constant_def_id.impl_def_id(db.upcast());
2300    let impl_constant_defs = db.impl_constants(impl_def_id)?;
2301    let impl_constant_def_ast = impl_constant_defs.get(&impl_constant_def_id).to_maybe()?;
2302    let lookup_item_id = LookupItemId::ImplItem(ImplItemId::Constant(impl_constant_def_id));
2303
2304    let inference_id = InferenceId::LookupItemGenerics(LookupItemId::ImplItem(
2305        ImplItemId::Constant(impl_constant_def_id),
2306    ));
2307    let resolver_data = db.impl_def_resolver_data(impl_def_id)?;
2308    let mut resolver =
2309        Resolver::with_data(db, resolver_data.clone_with_inference_id(db, inference_id));
2310
2311    let trait_constant_id = validate_impl_item_constant(
2312        db,
2313        &mut diagnostics,
2314        impl_constant_def_id,
2315        impl_constant_def_ast,
2316        &mut resolver,
2317    );
2318    let mut constant_data = if in_cycle {
2319        constant_semantic_data_cycle_helper(
2320            db,
2321            impl_constant_def_ast,
2322            lookup_item_id,
2323            Some(Arc::new(resolver.data)),
2324            &impl_def_id,
2325        )?
2326    } else {
2327        constant_semantic_data_helper(
2328            db,
2329            impl_constant_def_ast,
2330            lookup_item_id,
2331            Some(Arc::new(resolver.data)),
2332            &impl_def_id,
2333        )?
2334    };
2335    diagnostics.extend(mem::take(&mut constant_data.diagnostics));
2336    Ok(ImplItemConstantData { constant_data, trait_constant_id, diagnostics: diagnostics.build() })
2337}
2338
2339/// Cycle handling for [crate::db::SemanticGroup::priv_impl_constant_semantic_data].
2340pub fn priv_impl_constant_semantic_data_cycle(
2341    db: &dyn SemanticGroup,
2342    _cycle: &salsa::Cycle,
2343    impl_constant_def_id: &ImplConstantDefId,
2344    _in_cycle: &bool,
2345) -> Maybe<ImplItemConstantData> {
2346    // Forwarding cycle handling to `priv_impl_constant_semantic_data` handler.
2347    priv_impl_constant_semantic_data(db, *impl_constant_def_id, true)
2348}
2349
2350/// Validates the impl item constant, and returns the matching trait constant id.
2351fn validate_impl_item_constant(
2352    db: &dyn SemanticGroup,
2353    diagnostics: &mut SemanticDiagnostics,
2354    impl_constant_def_id: ImplConstantDefId,
2355    impl_constant_ast: &ast::ItemConstant,
2356    resolver: &mut Resolver<'_>,
2357) -> Maybe<TraitConstantId> {
2358    let syntax_db = db.upcast();
2359    let defs_db = db.upcast();
2360    let impl_def_id = impl_constant_def_id.impl_def_id(defs_db);
2361    let concrete_trait_id = db.impl_def_concrete_trait(impl_def_id)?;
2362    let trait_id = concrete_trait_id.trait_id(db);
2363    let constant_name = impl_constant_def_id.name(defs_db);
2364
2365    let trait_constant_id =
2366        db.trait_constant_by_name(trait_id, constant_name.clone())?.ok_or_else(|| {
2367            diagnostics.report(impl_constant_ast, ImplItemNotInTrait {
2368                impl_def_id,
2369                impl_item_name: constant_name,
2370                trait_id,
2371                item_kind: "const".into(),
2372            })
2373        })?;
2374    let concrete_trait_constant =
2375        ConcreteTraitConstantId::new(db, concrete_trait_id, trait_constant_id);
2376    let concrete_trait_constant_ty = db.concrete_trait_constant_type(concrete_trait_constant)?;
2377
2378    let impl_constant_type_clause_ast = impl_constant_ast.type_clause(syntax_db);
2379
2380    let constant_ty =
2381        resolve_type(db, diagnostics, resolver, &impl_constant_type_clause_ast.ty(syntax_db));
2382
2383    let inference = &mut resolver.inference();
2384
2385    let expected_ty = inference.rewrite(concrete_trait_constant_ty).no_err();
2386    let actual_ty = inference.rewrite(constant_ty).no_err();
2387    if expected_ty != actual_ty {
2388        diagnostics.report(&impl_constant_type_clause_ast, WrongType { expected_ty, actual_ty });
2389    }
2390    Ok(trait_constant_id)
2391}
2392
2393// === Impl Constant ===
2394
2395/// Query implementation of [crate::db::SemanticGroup::impl_constant_implized_by_context].
2396pub fn impl_constant_implized_by_context(
2397    db: &dyn SemanticGroup,
2398    impl_constant_id: ImplConstantId,
2399    impl_def_id: ImplDefId,
2400) -> Maybe<ConstValueId> {
2401    let impl_constant_def_id: ImplConstantDefId =
2402        db.impl_constant_by_trait_constant(impl_def_id, impl_constant_id.trait_constant_id())?;
2403
2404    db.impl_constant_def_value(impl_constant_def_id)
2405}
2406
2407/// Cycle handling for [crate::db::SemanticGroup::impl_constant_implized_by_context].
2408pub fn impl_constant_implized_by_context_cycle(
2409    db: &dyn SemanticGroup,
2410    _cycle: &salsa::Cycle,
2411    impl_constant_id: &ImplConstantId,
2412    impl_def_id: &ImplDefId,
2413) -> Maybe<ConstValueId> {
2414    // Forwarding cycle handling to `priv_impl_constant_semantic_data` handler.
2415    impl_constant_implized_by_context(db, *impl_constant_id, *impl_def_id)
2416}
2417
2418/// Query implementation of [crate::db::SemanticGroup::impl_constant_concrete_implized_value].
2419pub fn impl_constant_concrete_implized_value(
2420    db: &dyn SemanticGroup,
2421    impl_constant_id: ImplConstantId,
2422) -> Maybe<ConstValueId> {
2423    if let ImplLongId::Concrete(concrete_impl) = impl_constant_id.impl_id().lookup_intern(db) {
2424        let impl_def_id = concrete_impl.impl_def_id(db);
2425        let constant = db.impl_constant_implized_by_context(impl_constant_id, impl_def_id)?;
2426        let substitution: &GenericSubstitution = &concrete_impl.substitution(db)?;
2427        return SubstitutionRewriter { db, substitution }.rewrite(constant);
2428    }
2429    let substitution = &GenericSubstitution::from_impl(impl_constant_id.impl_id());
2430
2431    Ok(ConstValue::ImplConstant(
2432        SubstitutionRewriter { db, substitution }.rewrite(impl_constant_id)?,
2433    )
2434    .intern(db))
2435}
2436
2437/// Cycle handling for [crate::db::SemanticGroup::impl_constant_concrete_implized_value].
2438pub fn impl_constant_concrete_implized_value_cycle(
2439    db: &dyn SemanticGroup,
2440    _cycle: &salsa::Cycle,
2441    impl_constant_id: &ImplConstantId,
2442) -> Maybe<ConstValueId> {
2443    // Forwarding cycle handling to `priv_impl_const_semantic_data` handler.
2444    impl_constant_concrete_implized_value(db, *impl_constant_id)
2445}
2446
2447/// Query implementation of [crate::db::SemanticGroup::impl_constant_concrete_implized_type].
2448pub fn impl_constant_concrete_implized_type(
2449    db: &dyn SemanticGroup,
2450    impl_constant_id: ImplConstantId,
2451) -> Maybe<TypeId> {
2452    let concrete_trait_id = match impl_constant_id.impl_id().lookup_intern(db) {
2453        ImplLongId::Concrete(concrete_impl) => {
2454            let impl_def_id = concrete_impl.impl_def_id(db);
2455            let ty = db.impl_constant_implized_by_context(impl_constant_id, impl_def_id)?.ty(db)?;
2456            let substitution = &concrete_impl.substitution(db)?;
2457            return SubstitutionRewriter { db, substitution }.rewrite(ty);
2458        }
2459        ImplLongId::GenericParameter(param) => {
2460            let param_impl =
2461                extract_matches!(db.generic_param_semantic(param)?, GenericParam::Impl);
2462            param_impl.concrete_trait?
2463        }
2464        ImplLongId::ImplVar(var) => var.lookup_intern(db).concrete_trait_id,
2465        ImplLongId::ImplImpl(impl_impl) => db.impl_impl_concrete_trait(impl_impl)?,
2466        ImplLongId::TraitImpl(trait_impl) => db.trait_impl_concrete_trait(trait_impl)?,
2467        ImplLongId::GeneratedImpl(generated_impl) => generated_impl.concrete_trait(db),
2468    };
2469
2470    let ty = db.concrete_trait_constant_type(ConcreteTraitConstantId::new(
2471        db,
2472        concrete_trait_id,
2473        impl_constant_id.trait_constant_id(),
2474    ))?;
2475    let substitution = &GenericSubstitution::from_impl(impl_constant_id.impl_id());
2476    SubstitutionRewriter { db, substitution }.rewrite(ty)
2477}
2478
2479/// Cycle handling for [crate::db::SemanticGroup::impl_constant_concrete_implized_type].
2480pub fn impl_constant_concrete_implized_type_cycle(
2481    db: &dyn SemanticGroup,
2482    _cycle: &salsa::Cycle,
2483    impl_constant_id: &ImplConstantId,
2484) -> Maybe<TypeId> {
2485    // Forwarding cycle handling to `priv_impl_const_semantic_data` handler.
2486    impl_constant_concrete_implized_type(db, *impl_constant_id)
2487}
2488
2489// === Impl Item Impl definition ===
2490
2491#[derive(Clone, Debug, PartialEq, Eq, DebugWithDb)]
2492#[debug_db(dyn SemanticGroup + 'static)]
2493pub struct ImplItemImplData {
2494    impl_data: ImplAliasData,
2495    trait_impl_id: Maybe<TraitImplId>,
2496    /// The diagnostics of the impl impl, including the ones for the impl itself.
2497    diagnostics: Diagnostics<SemanticDiagnostic>,
2498}
2499
2500// --- Selectors ---
2501
2502/// Query implementation of [crate::db::SemanticGroup::impl_impl_def_semantic_diagnostics].
2503pub fn impl_impl_def_semantic_diagnostics(
2504    db: &dyn SemanticGroup,
2505    impl_impl_def_id: ImplImplDefId,
2506) -> Diagnostics<SemanticDiagnostic> {
2507    db.priv_impl_impl_semantic_data(impl_impl_def_id, false)
2508        .map(|data| data.diagnostics)
2509        .unwrap_or_default()
2510}
2511
2512/// Query implementation of [crate::db::SemanticGroup::impl_impl_def_resolver_data].
2513pub fn impl_impl_def_resolver_data(
2514    db: &dyn SemanticGroup,
2515    impl_impl_def_id: ImplImplDefId,
2516) -> Maybe<Arc<ResolverData>> {
2517    Ok(db.priv_impl_impl_semantic_data(impl_impl_def_id, false)?.impl_data.resolver_data)
2518}
2519
2520/// Query implementation of [crate::db::SemanticGroup::impl_impl_def_trait_impl].
2521pub fn impl_impl_def_trait_impl(
2522    db: &dyn SemanticGroup,
2523    impl_impl_def_id: ImplImplDefId,
2524) -> Maybe<TraitImplId> {
2525    db.priv_impl_impl_semantic_data(impl_impl_def_id, false)?.trait_impl_id
2526}
2527
2528/// Query implementation of [crate::db::SemanticGroup::impl_impl_def_impl].
2529pub fn impl_impl_def_impl(
2530    db: &dyn SemanticGroup,
2531    impl_impl_def_id: ImplImplDefId,
2532    in_cycle: bool,
2533) -> Maybe<ImplId> {
2534    db.priv_impl_impl_semantic_data(impl_impl_def_id, in_cycle)?.impl_data.resolved_impl
2535}
2536/// Cycle handling for [crate::db::SemanticGroup::impl_impl_def_impl].
2537pub fn impl_impl_def_impl_cycle(
2538    db: &dyn SemanticGroup,
2539    _cycle: &salsa::Cycle,
2540    impl_impl_def_id: &ImplImplDefId,
2541    _in_cycle: &bool,
2542) -> Maybe<ImplId> {
2543    db.priv_impl_impl_semantic_data(*impl_impl_def_id, true)?.impl_data.resolved_impl
2544}
2545
2546// --- Computation ---
2547
2548/// Query implementation of [crate::db::SemanticGroup::priv_impl_impl_semantic_data].
2549pub fn priv_impl_impl_semantic_data(
2550    db: &dyn SemanticGroup,
2551    impl_impl_def_id: ImplImplDefId,
2552    in_cycle: bool,
2553) -> Maybe<ImplItemImplData> {
2554    let mut diagnostics = SemanticDiagnostics::default();
2555    let impl_def_id = impl_impl_def_id.impl_def_id(db.upcast());
2556    let impl_impl_defs = db.impl_impls(impl_def_id)?;
2557    let impl_impl_def_ast = impl_impl_defs.get(&impl_impl_def_id).to_maybe()?;
2558    let generic_params_data = db.priv_impl_impl_def_generic_params_data(impl_impl_def_id)?;
2559    let lookup_item_id = LookupItemId::ImplItem(ImplItemId::Impl(impl_impl_def_id));
2560
2561    let inference_id = InferenceId::LookupItemGenerics(lookup_item_id);
2562    let resolver_data = db.impl_def_resolver_data(impl_def_id)?;
2563    let mut resolver =
2564        Resolver::with_data(db, resolver_data.clone_with_inference_id(db, inference_id));
2565
2566    let mut impl_data = if in_cycle {
2567        impl_alias_semantic_data_cycle_helper(
2568            db,
2569            impl_impl_def_ast,
2570            lookup_item_id,
2571            generic_params_data,
2572        )?
2573    } else {
2574        impl_alias_semantic_data_helper(db, impl_impl_def_ast, lookup_item_id, generic_params_data)?
2575    };
2576
2577    diagnostics.extend(mem::take(&mut impl_data.diagnostics));
2578
2579    let trait_impl_id = validate_impl_item_impl(
2580        db,
2581        &mut diagnostics,
2582        impl_impl_def_id,
2583        impl_impl_def_ast,
2584        &impl_data,
2585        &mut resolver,
2586    );
2587
2588    Ok(ImplItemImplData { impl_data, trait_impl_id, diagnostics: diagnostics.build() })
2589}
2590
2591/// Cycle handling for [crate::db::SemanticGroup::priv_impl_impl_semantic_data].
2592pub fn priv_impl_impl_semantic_data_cycle(
2593    db: &dyn SemanticGroup,
2594    _cycle: &salsa::Cycle,
2595    impl_impl_def_id: &ImplImplDefId,
2596    _in_cycle: &bool,
2597) -> Maybe<ImplItemImplData> {
2598    // Forwarding cycle handling to `priv_impl_impl_semantic_data` handler.
2599    priv_impl_impl_semantic_data(db, *impl_impl_def_id, true)
2600}
2601
2602/// Query implementation of [crate::db::SemanticGroup::priv_impl_impl_def_generic_params_data].
2603pub fn priv_impl_impl_def_generic_params_data(
2604    db: &dyn SemanticGroup,
2605    impl_impl_def_id: ImplImplDefId,
2606) -> Maybe<GenericParamsData> {
2607    let defs_db = db.upcast();
2608    let module_file_id = impl_impl_def_id.module_file_id(defs_db);
2609    let impl_impl_def_ast = db.impl_impl_by_id(impl_impl_def_id)?.to_maybe()?;
2610    let lookup_item_id = LookupItemId::ImplItem(ImplItemId::Impl(impl_impl_def_id));
2611
2612    let impl_resolver_data = db.impl_def_resolver_data(impl_impl_def_id.impl_def_id(defs_db))?;
2613    impl_alias_generic_params_data_helper(
2614        db,
2615        module_file_id,
2616        &impl_impl_def_ast,
2617        lookup_item_id,
2618        Some(impl_resolver_data),
2619    )
2620}
2621
2622/// Validates the impl item impl, and returns the matching trait impl id.
2623fn validate_impl_item_impl(
2624    db: &dyn SemanticGroup,
2625    diagnostics: &mut SemanticDiagnostics,
2626    impl_impl_def_id: ImplImplDefId,
2627    impl_impl_ast: &ast::ItemImplAlias,
2628    impl_data: &ImplAliasData,
2629    resolver: &mut Resolver<'_>,
2630) -> Maybe<TraitImplId> {
2631    let syntax_db = db.upcast();
2632    let defs_db = db.upcast();
2633    let impl_def_id = impl_impl_def_id.impl_def_id(defs_db);
2634    let concrete_trait_id = db.impl_def_concrete_trait(impl_def_id)?;
2635    let trait_id = concrete_trait_id.trait_id(db);
2636    let impl_name = impl_impl_def_id.name(defs_db);
2637    let trait_impl_id = db.trait_impl_by_name(trait_id, impl_name.clone())?.ok_or_else(|| {
2638        diagnostics.report(impl_impl_ast, ImplItemNotInTrait {
2639            impl_def_id,
2640            impl_item_name: impl_name,
2641            trait_id,
2642            item_kind: "impl".into(),
2643        })
2644    })?;
2645
2646    // TODO(TomerStarkware): add validations for generic parameters, then remove this.
2647    // Generic parameters are not yet supported, make sure there are none.
2648    let generic_params_node = impl_impl_ast.generic_params(syntax_db);
2649    if !generic_params_node.is_empty(syntax_db) {
2650        diagnostics.report(&generic_params_node, GenericsNotSupportedInItem {
2651            scope: "Impl".into(),
2652            item_kind: "impl".into(),
2653        });
2654    }
2655
2656    let concrete_trait_impl = ConcreteTraitImplId::new(db, concrete_trait_id, trait_impl_id);
2657    let impl_def_substitution = db.impl_def_substitution(impl_def_id)?;
2658
2659    let concrete_trait_impl_concrete_trait =
2660        db.concrete_trait_impl_concrete_trait(concrete_trait_impl).and_then(|concrete_trait_id| {
2661            SubstitutionRewriter { db, substitution: impl_def_substitution.as_ref() }
2662                .rewrite(concrete_trait_id)
2663        });
2664
2665    let resolved_impl_concrete_trait =
2666        impl_data.resolved_impl.and_then(|imp| imp.concrete_trait(db));
2667    // used an IIFE to allow the use of the `?` operator.
2668    let _ = (|| -> Result<(), DiagnosticAdded> {
2669        if resolver
2670            .inference()
2671            .conform_traits(resolved_impl_concrete_trait?, concrete_trait_impl_concrete_trait?)
2672            .is_err()
2673        {
2674            diagnostics.report(impl_impl_ast, TraitMismatch {
2675                expected_trt: concrete_trait_impl_concrete_trait?,
2676                actual_trt: resolved_impl_concrete_trait?,
2677            });
2678        }
2679        Ok(())
2680    })();
2681
2682    Ok(trait_impl_id)
2683}
2684
2685#[derive(Clone, Debug, PartialEq, Eq, DebugWithDb)]
2686#[debug_db(dyn SemanticGroup + 'static)]
2687pub struct ImplicitImplImplData {
2688    resolved_impl: Maybe<ImplId>,
2689    trait_impl_id: TraitImplId,
2690    diagnostics: Diagnostics<SemanticDiagnostic>,
2691}
2692
2693/// Query implementation of [crate::db::SemanticGroup::implicit_impl_impl_semantic_diagnostics].
2694pub fn implicit_impl_impl_semantic_diagnostics(
2695    db: &dyn SemanticGroup,
2696    impl_def_id: ImplDefId,
2697    trait_impl_id: TraitImplId,
2698) -> Diagnostics<SemanticDiagnostic> {
2699    db.priv_implicit_impl_impl_semantic_data(impl_def_id, trait_impl_id, false)
2700        .map(|data| data.diagnostics)
2701        .unwrap_or_default()
2702}
2703/// Query implementation of [crate::db::SemanticGroup::implicit_impl_impl_impl].
2704pub fn implicit_impl_impl_impl(
2705    db: &dyn SemanticGroup,
2706    impl_def_id: ImplDefId,
2707    trait_impl_id: TraitImplId,
2708    in_cycle: bool,
2709) -> Maybe<ImplId> {
2710    db.priv_implicit_impl_impl_semantic_data(impl_def_id, trait_impl_id, in_cycle)?.resolved_impl
2711}
2712/// Cycle handling for [crate::db::SemanticGroup::implicit_impl_impl_impl].
2713pub fn implicit_impl_impl_impl_cycle(
2714    db: &dyn SemanticGroup,
2715    _cycle: &salsa::Cycle,
2716    impl_def_id: &ImplDefId,
2717    trait_impl_id: &TraitImplId,
2718    _in_cycle: &bool,
2719) -> Maybe<ImplId> {
2720    db.priv_implicit_impl_impl_semantic_data(*impl_def_id, *trait_impl_id, true)?.resolved_impl
2721}
2722
2723/// Query implementation of [crate::db::SemanticGroup::priv_implicit_impl_impl_semantic_data].
2724pub fn priv_implicit_impl_impl_semantic_data(
2725    db: &dyn SemanticGroup,
2726    impl_def_id: ImplDefId,
2727    trait_impl_id: TraitImplId,
2728    in_cycle: bool,
2729) -> Maybe<ImplicitImplImplData> {
2730    let mut diagnostics = SemanticDiagnostics::default();
2731    if in_cycle {
2732        let err =
2733            Err(diagnostics.report(impl_def_id.stable_ptr(db.upcast()).untyped(), ImplAliasCycle));
2734        return Ok(ImplicitImplImplData {
2735            resolved_impl: err,
2736            trait_impl_id,
2737            diagnostics: diagnostics.build(),
2738        });
2739    }
2740    let lookup_item_id = LookupItemId::ModuleItem(ModuleItemId::Impl(impl_def_id));
2741
2742    let inference_id = InferenceId::LookupItemGenerics(lookup_item_id);
2743    let resolver_data = db.impl_def_resolver_data(impl_def_id)?;
2744
2745    let mut resolver =
2746        Resolver::with_data(db, resolver_data.clone_with_inference_id(db, inference_id));
2747    // We cannot use `Self` as it will always find the implicit impl.
2748    resolver.trait_or_impl_ctx = TraitOrImplContext::None;
2749
2750    let concrete_trait_impl_concrete_trait = db
2751        .impl_def_concrete_trait(impl_def_id)
2752        .and_then(|concrete_trait_id| {
2753            db.concrete_trait_impl_concrete_trait(ConcreteTraitImplId::new(
2754                db,
2755                concrete_trait_id,
2756                trait_impl_id,
2757            ))
2758        })
2759        .and_then(|concrete_trait_id| {
2760            let impl_def_substitution = db.impl_def_substitution(impl_def_id)?;
2761            SubstitutionRewriter { db, substitution: impl_def_substitution.as_ref() }
2762                .rewrite(concrete_trait_id)
2763        });
2764    let impl_lookup_context = resolver.impl_lookup_context();
2765    let resolved_impl = concrete_trait_impl_concrete_trait.and_then(|concrete_trait_id| {
2766        let imp = resolver.inference().new_impl_var(concrete_trait_id, None, impl_lookup_context);
2767        if let Err((err_set, _)) = resolver.inference().finalize_without_reporting() {
2768            diagnostics.report(
2769                impl_def_id.stable_ptr(db.upcast()).untyped(),
2770                ImplicitImplNotInferred { trait_impl_id, concrete_trait_id },
2771            );
2772            resolver.inference().report_on_pending_error(
2773                err_set,
2774                &mut diagnostics,
2775                impl_def_id.stable_ptr(db.upcast()).untyped(),
2776            );
2777        };
2778        resolver.inference().rewrite(imp).map_err(|_| skip_diagnostic())
2779    });
2780
2781    Ok(ImplicitImplImplData { resolved_impl, trait_impl_id, diagnostics: diagnostics.build() })
2782}
2783/// Cycle handling for [crate::db::SemanticGroup::priv_implicit_impl_impl_semantic_data].
2784pub fn priv_implicit_impl_impl_semantic_data_cycle(
2785    db: &dyn SemanticGroup,
2786    _cycle: &salsa::Cycle,
2787    impl_def_id: &ImplDefId,
2788    trait_impl_id: &TraitImplId,
2789    _in_cycle: &bool,
2790) -> Maybe<ImplicitImplImplData> {
2791    // Forwarding cycle handling to `priv_implicit_impl_impl_semantic_data` handler.
2792    priv_implicit_impl_impl_semantic_data(db, *impl_def_id, *trait_impl_id, true)
2793}
2794
2795// === Impl Impl ===
2796
2797/// Query implementation of [crate::db::SemanticGroup::impl_impl_implized_by_context].
2798pub fn impl_impl_implized_by_context(
2799    db: &dyn SemanticGroup,
2800    impl_impl_id: ImplImplId,
2801    impl_def_id: ImplDefId,
2802    in_cycle: bool,
2803) -> Maybe<ImplId> {
2804    if db.is_implicit_impl_impl(impl_def_id, impl_impl_id.trait_impl_id())? {
2805        return db.implicit_impl_impl_impl(impl_def_id, impl_impl_id.trait_impl_id(), in_cycle);
2806    }
2807
2808    let impl_impl_def_id = db.impl_impl_by_trait_impl(impl_def_id, impl_impl_id.trait_impl_id())?;
2809
2810    db.impl_impl_def_impl(impl_impl_def_id, in_cycle)
2811}
2812
2813/// Cycle handling for [crate::db::SemanticGroup::impl_impl_implized_by_context].
2814pub fn impl_impl_implized_by_context_cycle(
2815    db: &dyn SemanticGroup,
2816    _cycle: &salsa::Cycle,
2817    impl_impl_id: &ImplImplId,
2818    impl_def_id: &ImplDefId,
2819    _in_cycle: &bool,
2820) -> Maybe<ImplId> {
2821    // Forwarding cycle handling to `priv_impl_impl_semantic_data` handler.
2822    impl_impl_implized_by_context(db, *impl_impl_id, *impl_def_id, true)
2823}
2824
2825/// Query implementation of [crate::db::SemanticGroup::impl_impl_concrete_implized].
2826pub fn impl_impl_concrete_implized(
2827    db: &dyn SemanticGroup,
2828    impl_impl_id: ImplImplId,
2829) -> Maybe<ImplId> {
2830    impl_impl_concrete_implized_ex(db, impl_impl_id, false)
2831}
2832
2833/// Cycle handling for [crate::db::SemanticGroup::impl_impl_concrete_implized].
2834pub fn impl_impl_concrete_implized_cycle(
2835    db: &dyn SemanticGroup,
2836    _cycle: &salsa::Cycle,
2837    impl_impl_id: &ImplImplId,
2838) -> Maybe<ImplId> {
2839    impl_impl_concrete_implized_ex(db, *impl_impl_id, true)
2840}
2841
2842fn impl_impl_concrete_implized_ex(
2843    db: &dyn SemanticGroup,
2844    impl_impl_id: ImplImplId,
2845    in_cycle: bool,
2846) -> Maybe<ImplId> {
2847    if let ImplLongId::Concrete(concrete_impl) = impl_impl_id.impl_id().lookup_intern(db) {
2848        let impl_def_id = concrete_impl.impl_def_id(db);
2849        let imp = db.impl_impl_implized_by_context(impl_impl_id, impl_def_id, in_cycle)?;
2850        let substitution: &GenericSubstitution = &concrete_impl.substitution(db)?;
2851        return SubstitutionRewriter { db, substitution }.rewrite(imp);
2852    }
2853    let substitution = &GenericSubstitution::from_impl(impl_impl_id.impl_id());
2854
2855    Ok(ImplLongId::ImplImpl(SubstitutionRewriter { db, substitution }.rewrite(impl_impl_id)?)
2856        .intern(db))
2857}
2858
2859/// Query implementation of [crate::db::SemanticGroup::impl_impl_concrete_trait].
2860pub fn impl_impl_concrete_trait(
2861    db: &dyn SemanticGroup,
2862    impl_impl_id: ImplImplId,
2863) -> Maybe<ConcreteTraitId> {
2864    let concrete_trait_impl = impl_impl_id.concrete_trait_impl_id(db)?;
2865    let substitution = GenericSubstitution::from_impl(impl_impl_id.impl_id());
2866
2867    db.concrete_trait_impl_concrete_trait(concrete_trait_impl).and_then(|concrete_trait_id| {
2868        SubstitutionRewriter { db, substitution: &substitution }.rewrite(concrete_trait_id)
2869    })
2870}
2871
2872// === Impl Function Declaration ===
2873
2874#[derive(Clone, Debug, PartialEq, Eq, DebugWithDb)]
2875#[debug_db(dyn SemanticGroup + 'static)]
2876pub struct ImplFunctionDeclarationData {
2877    pub function_declaration_data: FunctionDeclarationData,
2878    trait_function_id: Maybe<TraitFunctionId>,
2879}
2880
2881// --- Selectors ---
2882
2883/// Query implementation of [crate::db::SemanticGroup::impl_function_declaration_diagnostics].
2884pub fn impl_function_declaration_diagnostics(
2885    db: &dyn SemanticGroup,
2886    impl_function_id: ImplFunctionId,
2887) -> Diagnostics<SemanticDiagnostic> {
2888    db.priv_impl_function_declaration_data(impl_function_id)
2889        .map(|data| data.function_declaration_data.diagnostics)
2890        .unwrap_or_default()
2891}
2892
2893/// Query implementation of [crate::db::SemanticGroup::impl_function_signature].
2894pub fn impl_function_signature(
2895    db: &dyn SemanticGroup,
2896    impl_function_id: ImplFunctionId,
2897) -> Maybe<semantic::Signature> {
2898    Ok(db
2899        .priv_impl_function_declaration_data(impl_function_id)?
2900        .function_declaration_data
2901        .signature)
2902}
2903
2904/// Query implementation of [crate::db::SemanticGroup::impl_function_generic_params].
2905pub fn impl_function_generic_params(
2906    db: &dyn SemanticGroup,
2907    impl_function_id: ImplFunctionId,
2908) -> Maybe<Vec<semantic::GenericParam>> {
2909    Ok(db.priv_impl_function_generic_params_data(impl_function_id)?.generic_params)
2910}
2911
2912/// Query implementation of [crate::db::SemanticGroup::priv_impl_function_generic_params_data].
2913pub fn priv_impl_function_generic_params_data(
2914    db: &dyn SemanticGroup,
2915    impl_function_id: ImplFunctionId,
2916) -> Maybe<GenericParamsData> {
2917    let module_file_id = impl_function_id.module_file_id(db.upcast());
2918    let mut diagnostics = SemanticDiagnostics::default();
2919    let impl_def_id = impl_function_id.impl_def_id(db.upcast());
2920    let data = db.priv_impl_definition_data(impl_def_id)?;
2921    let function_syntax = &data.function_asts[&impl_function_id];
2922    let syntax_db = db.upcast();
2923    let declaration = function_syntax.declaration(syntax_db);
2924    let inference_id = InferenceId::LookupItemGenerics(LookupItemId::ImplItem(
2925        ImplItemId::Function(impl_function_id),
2926    ));
2927    let resolver_data = db.impl_def_resolver_data(impl_def_id)?;
2928    let mut resolver =
2929        Resolver::with_data(db, resolver_data.clone_with_inference_id(db, inference_id));
2930    let generic_params = semantic_generic_params(
2931        db,
2932        &mut diagnostics,
2933        &mut resolver,
2934        module_file_id,
2935        &declaration.generic_params(syntax_db),
2936    );
2937    let inference = &mut resolver.inference();
2938    inference.finalize(&mut diagnostics, function_syntax.stable_ptr().untyped());
2939
2940    let generic_params = inference.rewrite(generic_params).no_err();
2941    let resolver_data = Arc::new(resolver.data);
2942    Ok(GenericParamsData { generic_params, diagnostics: diagnostics.build(), resolver_data })
2943}
2944
2945/// Query implementation of [crate::db::SemanticGroup::impl_function_attributes].
2946pub fn impl_function_attributes(
2947    db: &dyn SemanticGroup,
2948    impl_function_id: ImplFunctionId,
2949) -> Maybe<Vec<Attribute>> {
2950    Ok(db
2951        .priv_impl_function_declaration_data(impl_function_id)?
2952        .function_declaration_data
2953        .attributes)
2954}
2955
2956/// Query implementation of [crate::db::SemanticGroup::impl_function_resolver_data].
2957pub fn impl_function_resolver_data(
2958    db: &dyn SemanticGroup,
2959    impl_function_id: ImplFunctionId,
2960) -> Maybe<Arc<ResolverData>> {
2961    Ok(db
2962        .priv_impl_function_declaration_data(impl_function_id)?
2963        .function_declaration_data
2964        .resolver_data)
2965}
2966
2967/// Query implementation of [crate::db::SemanticGroup::impl_function_declaration_inline_config].
2968pub fn impl_function_declaration_inline_config(
2969    db: &dyn SemanticGroup,
2970    impl_function_id: ImplFunctionId,
2971) -> Maybe<InlineConfiguration> {
2972    Ok(db
2973        .priv_impl_function_declaration_data(impl_function_id)?
2974        .function_declaration_data
2975        .inline_config)
2976}
2977
2978/// Query implementation of [SemanticGroup::impl_function_declaration_implicit_precedence].
2979pub fn impl_function_declaration_implicit_precedence(
2980    db: &dyn SemanticGroup,
2981    impl_function_id: ImplFunctionId,
2982) -> Maybe<ImplicitPrecedence> {
2983    Ok(db
2984        .priv_impl_function_declaration_data(impl_function_id)?
2985        .function_declaration_data
2986        .implicit_precedence)
2987}
2988
2989/// Query implementation of [crate::db::SemanticGroup::impl_function_declaration_implicits].
2990pub fn impl_function_declaration_implicits(
2991    db: &dyn SemanticGroup,
2992    impl_function_id: ImplFunctionId,
2993) -> Maybe<Vec<TypeId>> {
2994    Ok(db
2995        .priv_impl_function_declaration_data(impl_function_id)?
2996        .function_declaration_data
2997        .signature
2998        .implicits)
2999}
3000
3001/// Query implementation of [crate::db::SemanticGroup::impl_function_trait_function].
3002pub fn impl_function_trait_function(
3003    db: &dyn SemanticGroup,
3004    impl_function_id: ImplFunctionId,
3005) -> Maybe<TraitFunctionId> {
3006    db.priv_impl_function_declaration_data(impl_function_id)?.trait_function_id
3007}
3008
3009// --- Computation ---
3010
3011/// Query implementation of [crate::db::SemanticGroup::priv_impl_function_declaration_data].
3012pub fn priv_impl_function_declaration_data(
3013    db: &dyn SemanticGroup,
3014    impl_function_id: ImplFunctionId,
3015) -> Maybe<ImplFunctionDeclarationData> {
3016    let mut diagnostics = SemanticDiagnostics::default();
3017    let impl_def_id = impl_function_id.impl_def_id(db.upcast());
3018    let data = db.priv_impl_definition_data(impl_def_id)?;
3019    let function_syntax = &data.function_asts[&impl_function_id];
3020    let syntax_db = db.upcast();
3021    let declaration = function_syntax.declaration(syntax_db);
3022
3023    let generic_params_data = db.priv_impl_function_generic_params_data(impl_function_id)?;
3024    let generic_params = generic_params_data.generic_params;
3025    let lookup_item_id = LookupItemId::ImplItem(ImplItemId::Function(impl_function_id));
3026    let inference_id = InferenceId::LookupItemGenerics(lookup_item_id);
3027    let mut resolver = Resolver::with_data(
3028        db,
3029        (*generic_params_data.resolver_data).clone_with_inference_id(db, inference_id),
3030    );
3031    diagnostics.extend(generic_params_data.diagnostics);
3032    resolver.set_feature_config(&impl_function_id, function_syntax, &mut diagnostics);
3033
3034    let signature_syntax = declaration.signature(syntax_db);
3035
3036    let mut environment = Environment::empty();
3037    let signature = semantic::Signature::from_ast(
3038        &mut diagnostics,
3039        db,
3040        &mut resolver,
3041        &signature_syntax,
3042        FunctionTitleId::Impl(impl_function_id),
3043        &mut environment,
3044    );
3045
3046    let attributes = function_syntax.attributes(syntax_db).structurize(syntax_db);
3047    let (implicit_precedence, _) =
3048        get_implicit_precedence(&mut diagnostics, &mut resolver, &attributes);
3049
3050    let inference = &mut resolver.inference();
3051    // Check fully resolved.
3052    inference.finalize(&mut diagnostics, function_syntax.stable_ptr().untyped());
3053    let trait_function_id = validate_impl_function_signature(
3054        db,
3055        &mut diagnostics,
3056        inference,
3057        ValidateImplFunctionSignatureParams {
3058            impl_function_id,
3059            signature_syntax: &signature_syntax,
3060            signature: &signature,
3061            impl_function_syntax: function_syntax,
3062            impl_func_generics: &generic_params,
3063        },
3064    );
3065
3066    let inline_config = get_inline_config(db, &mut diagnostics, &attributes)?;
3067
3068    forbid_inline_always_with_impl_generic_param(&mut diagnostics, &generic_params, &inline_config);
3069
3070    let signature = inference.rewrite(signature).no_err();
3071    let generic_params = inference.rewrite(generic_params).no_err();
3072
3073    let resolver_data = Arc::new(resolver.data);
3074    Ok(ImplFunctionDeclarationData {
3075        function_declaration_data: FunctionDeclarationData {
3076            diagnostics: diagnostics.build(),
3077            signature,
3078            generic_params,
3079            environment,
3080            attributes,
3081            resolver_data,
3082            inline_config,
3083            implicit_precedence,
3084        },
3085        trait_function_id,
3086    })
3087}
3088
3089/// Struct for the parameters of [validate_impl_function_signature].
3090struct ValidateImplFunctionSignatureParams<'a> {
3091    /// The impl function to validate the signature of.
3092    impl_function_id: ImplFunctionId,
3093    /// The signature syntax.
3094    signature_syntax: &'a ast::FunctionSignature,
3095    // The semantic signature.
3096    signature: &'a semantic::Signature,
3097    /// The impl function syntax.
3098    impl_function_syntax: &'a ast::FunctionWithBody,
3099    /// The generic parameters of the impl function.
3100    impl_func_generics: &'a [GenericParam],
3101}
3102
3103/// Validates the impl function, and returns the matching trait function id.
3104fn validate_impl_function_signature(
3105    db: &dyn SemanticGroup,
3106    diagnostics: &mut SemanticDiagnostics,
3107    inference: &mut Inference<'_>,
3108    ValidateImplFunctionSignatureParams {
3109        impl_function_id,
3110        signature_syntax,
3111        signature,
3112        impl_function_syntax,
3113        impl_func_generics,
3114    }: ValidateImplFunctionSignatureParams<'_>,
3115) -> Maybe<TraitFunctionId> {
3116    let syntax_db = db.upcast();
3117    let defs_db = db.upcast();
3118    let impl_def_id = impl_function_id.impl_def_id(defs_db);
3119    let concrete_trait_id = db.impl_def_concrete_trait(impl_def_id)?;
3120    let trait_id = concrete_trait_id.trait_id(db);
3121    let function_name = impl_function_id.name(defs_db);
3122    let trait_function_id =
3123        db.trait_function_by_name(trait_id, function_name.clone())?.ok_or_else(|| {
3124            diagnostics.report(impl_function_syntax, ImplItemNotInTrait {
3125                impl_def_id,
3126                impl_item_name: function_name,
3127                trait_id,
3128                item_kind: "function".into(),
3129            })
3130        })?;
3131    let concrete_trait_function =
3132        ConcreteTraitGenericFunctionId::new(db, concrete_trait_id, trait_function_id);
3133    let concrete_trait_signature = db.concrete_trait_function_signature(concrete_trait_function)?;
3134
3135    // Match generics of the function.
3136    // TODO(spapini): Compare the actual kinds and traits for the generic params.
3137
3138    let func_generics = db.concrete_trait_function_generic_params(concrete_trait_function)?;
3139    if impl_func_generics.len() != func_generics.len() {
3140        diagnostics.report(
3141            &impl_function_syntax.declaration(syntax_db).name(syntax_db),
3142            WrongNumberOfGenericParamsForImplFunction {
3143                expected: func_generics.len(),
3144                actual: impl_func_generics.len(),
3145            },
3146        );
3147        return Ok(trait_function_id);
3148    }
3149    let substitution =
3150        GenericSubstitution::new(&func_generics, &generic_params_to_args(impl_func_generics, db));
3151    let concrete_trait_signature = SubstitutionRewriter { db, substitution: &substitution }
3152        .rewrite(concrete_trait_signature)?;
3153
3154    if signature.params.len() != concrete_trait_signature.params.len() {
3155        diagnostics.report(&signature_syntax.parameters(syntax_db), WrongNumberOfParameters {
3156            impl_def_id,
3157            impl_function_id,
3158            trait_id,
3159            expected: concrete_trait_signature.params.len(),
3160            actual: signature.params.len(),
3161        });
3162    }
3163    let impl_def_substitution = db.impl_def_substitution(impl_def_id)?;
3164    let concrete_trait_signature =
3165        SubstitutionRewriter { db, substitution: impl_def_substitution.as_ref() }
3166            .rewrite(concrete_trait_signature)?;
3167    for (idx, (param, trait_param)) in
3168        izip!(signature.params.iter(), concrete_trait_signature.params.iter()).enumerate()
3169    {
3170        let expected_ty = inference.rewrite(trait_param.ty).no_err();
3171        let actual_ty = inference.rewrite(param.ty).no_err();
3172
3173        if expected_ty != actual_ty && !expected_ty.is_missing(db) && !actual_ty.is_missing(db) {
3174            diagnostics.report(
3175                &extract_matches!(
3176                    signature_syntax.parameters(syntax_db).elements(syntax_db)[idx]
3177                        .type_clause(syntax_db),
3178                    OptionTypeClause::TypeClause
3179                )
3180                .ty(syntax_db),
3181                WrongParameterType {
3182                    impl_def_id,
3183                    impl_function_id,
3184                    trait_id,
3185                    expected_ty,
3186                    actual_ty,
3187                },
3188            );
3189        }
3190
3191        if trait_param.mutability != param.mutability {
3192            if trait_param.mutability == Mutability::Reference {
3193                diagnostics.report(
3194                    &signature_syntax.parameters(syntax_db).elements(syntax_db)[idx]
3195                        .modifiers(syntax_db),
3196                    ParameterShouldBeReference { impl_def_id, impl_function_id, trait_id },
3197                );
3198            }
3199
3200            if param.mutability == Mutability::Reference {
3201                diagnostics.report(
3202                    &signature_syntax.parameters(syntax_db).elements(syntax_db)[idx]
3203                        .modifiers(syntax_db),
3204                    ParameterShouldNotBeReference { impl_def_id, impl_function_id, trait_id },
3205                );
3206            }
3207        }
3208
3209        if trait_param.name != param.name {
3210            diagnostics.report(
3211                &signature_syntax.parameters(syntax_db).elements(syntax_db)[idx].name(syntax_db),
3212                WrongParameterName {
3213                    impl_def_id,
3214                    impl_function_id,
3215                    trait_id,
3216                    expected_name: trait_param.name.clone(),
3217                },
3218            );
3219        }
3220    }
3221
3222    if !concrete_trait_signature.panicable && signature.panicable {
3223        diagnostics.report(signature_syntax, PassPanicAsNopanic { impl_function_id, trait_id });
3224    }
3225
3226    let expected_ty = inference.rewrite(concrete_trait_signature.return_type).no_err();
3227    let actual_ty = inference.rewrite(signature.return_type).no_err();
3228
3229    if expected_ty != actual_ty && !expected_ty.is_missing(db) && !actual_ty.is_missing(db) {
3230        let location_ptr = match signature_syntax.ret_ty(syntax_db) {
3231            OptionReturnTypeClause::ReturnTypeClause(ret_ty) => {
3232                ret_ty.ty(syntax_db).as_syntax_node()
3233            }
3234            OptionReturnTypeClause::Empty(_) => {
3235                impl_function_syntax.body(syntax_db).lbrace(syntax_db).as_syntax_node()
3236            }
3237        }
3238        .stable_ptr();
3239        diagnostics.report(location_ptr, WrongReturnTypeForImpl {
3240            impl_def_id,
3241            impl_function_id,
3242            trait_id,
3243            expected_ty,
3244            actual_ty,
3245        });
3246    }
3247    Ok(trait_function_id)
3248}
3249
3250// === Impl Function Body ===
3251
3252// --- Selectors ---
3253
3254/// Query implementation of [crate::db::SemanticGroup::impl_function_body_diagnostics].
3255pub fn impl_function_body_diagnostics(
3256    db: &dyn SemanticGroup,
3257    impl_function_id: ImplFunctionId,
3258) -> Diagnostics<SemanticDiagnostic> {
3259    db.priv_impl_function_body_data(impl_function_id)
3260        .map(|data| data.diagnostics)
3261        .unwrap_or_default()
3262}
3263
3264/// Query implementation of [crate::db::SemanticGroup::impl_function_body].
3265pub fn impl_function_body(
3266    db: &dyn SemanticGroup,
3267    impl_function_id: ImplFunctionId,
3268) -> Maybe<Arc<FunctionBody>> {
3269    Ok(db.priv_impl_function_body_data(impl_function_id)?.body)
3270}
3271
3272/// Query implementation of [crate::db::SemanticGroup::impl_function_body_resolver_data].
3273pub fn impl_function_body_resolver_data(
3274    db: &dyn SemanticGroup,
3275    impl_function_id: ImplFunctionId,
3276) -> Maybe<Arc<ResolverData>> {
3277    Ok(db.priv_impl_function_body_data(impl_function_id)?.resolver_data)
3278}
3279
3280// --- Computation ---
3281
3282/// Query implementation of [crate::db::SemanticGroup::priv_impl_function_body_data].
3283pub fn priv_impl_function_body_data(
3284    db: &dyn SemanticGroup,
3285    impl_function_id: ImplFunctionId,
3286) -> Maybe<FunctionBodyData> {
3287    let defs_db = db.upcast();
3288    let mut diagnostics = SemanticDiagnostics::default();
3289    let impl_def_id = impl_function_id.impl_def_id(defs_db);
3290    let data = db.priv_impl_definition_data(impl_def_id)?;
3291    let function_syntax = &data.function_asts[&impl_function_id];
3292    // Compute declaration semantic.
3293    let declaration = db.priv_impl_function_declaration_data(impl_function_id)?;
3294    let parent_resolver_data = declaration.function_declaration_data.resolver_data;
3295    let inference_id = InferenceId::LookupItemDefinition(LookupItemId::ImplItem(
3296        ImplItemId::Function(impl_function_id),
3297    ));
3298    let resolver =
3299        Resolver::with_data(db, (*parent_resolver_data).clone_with_inference_id(db, inference_id));
3300    let environment: Environment = declaration.function_declaration_data.environment;
3301
3302    let function_id = (|| {
3303        let trait_function_id = db.impl_function_trait_function(impl_function_id)?;
3304        let generic_parameters = db.impl_def_generic_params(impl_def_id)?;
3305
3306        let generic_function = GenericFunctionId::Impl(ImplGenericFunctionId {
3307            impl_id: ImplLongId::Concrete(
3308                ConcreteImplLongId {
3309                    impl_def_id,
3310                    generic_args: generic_params_to_args(&generic_parameters, db),
3311                }
3312                .intern(db),
3313            )
3314            .intern(db),
3315            function: trait_function_id,
3316        });
3317
3318        Ok(FunctionLongId::from_generic(db, generic_function)?.intern(db))
3319    })();
3320    // Compute body semantic expr.
3321    let mut ctx = ComputationContext::new(
3322        db,
3323        &mut diagnostics,
3324        resolver,
3325        Some(&declaration.function_declaration_data.signature),
3326        environment,
3327        ContextFunction::Function(function_id),
3328    );
3329    let function_body = function_syntax.body(db.upcast());
3330    let return_type = declaration.function_declaration_data.signature.return_type;
3331    let body_expr = compute_root_expr(&mut ctx, &function_body, return_type)?;
3332    let ComputationContext { arenas: Arenas { exprs, patterns, statements }, resolver, .. } = ctx;
3333
3334    let expr_lookup: UnorderedHashMap<_, _> =
3335        exprs.iter().map(|(expr_id, expr)| (expr.stable_ptr(), expr_id)).collect();
3336    let pattern_lookup: UnorderedHashMap<_, _> =
3337        patterns.iter().map(|(pattern_id, pattern)| (pattern.stable_ptr(), pattern_id)).collect();
3338    let resolver_data = Arc::new(resolver.data);
3339    Ok(FunctionBodyData {
3340        diagnostics: diagnostics.build(),
3341        expr_lookup,
3342        pattern_lookup,
3343        resolver_data,
3344        body: Arc::new(FunctionBody { arenas: Arenas { exprs, patterns, statements }, body_expr }),
3345    })
3346}
3347
3348pub fn priv_impl_is_fully_concrete(db: &dyn SemanticGroup, impl_id: ImplId) -> bool {
3349    impl_id.lookup_intern(db).is_fully_concrete(db)
3350}
3351
3352pub fn priv_impl_is_var_free(db: &dyn SemanticGroup, impl_id: ImplId) -> bool {
3353    impl_id.lookup_intern(db).is_var_free(db)
3354}