Skip to main content

hir/
lib.rs

1//! HIR (previously known as descriptors) provides a high-level object-oriented
2//! access to Rust code.
3//!
4//! The principal difference between HIR and syntax trees is that HIR is bound
5//! to a particular crate instance. That is, it has cfg flags and features
6//! applied. So, the relation between syntax and HIR is many-to-one.
7//!
8//! HIR is the public API of the all of the compiler logic above syntax trees.
9//! It is written in "OO" style. Each type is self contained (as in, it knows its
10//! parents and full context). It should be "clean code".
11//!
12//! `hir_*` crates are the implementation of the compiler logic.
13//! They are written in "ECS" style, with relatively little abstractions.
14//! Many types are not self-contained, and explicitly use local indexes, arenas, etc.
15//!
16//! `hir` is what insulates the "we don't know how to actually write an incremental compiler"
17//! from the ide with completions, hovers, etc. It is a (soft, internal) boundary:
18//! <https://www.tedinski.com/2018/02/06/system-boundaries.html>.
19
20#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
21#![recursion_limit = "512"]
22
23extern crate ra_ap_rustc_type_ir as rustc_type_ir;
24
25mod attrs;
26mod from_id;
27mod has_source;
28mod semantics;
29mod source_analyzer;
30
31pub mod db;
32pub mod diagnostics;
33pub mod symbols;
34pub mod term_search;
35
36mod display;
37
38#[doc(hidden)]
39pub use hir_def::ModuleId;
40
41use std::{
42    borrow::Borrow,
43    fmt, iter,
44    mem::discriminant,
45    ops::{ControlFlow, Not},
46};
47
48use arrayvec::ArrayVec;
49use base_db::{CrateDisplayName, CrateOrigin, LangCrateOrigin, SourceDatabase, all_crates};
50use either::Either;
51use hir_def::{
52    AdtId, AssocItemId, AssocItemLoc, BuiltinDeriveImplId, CallableDefId, ConstId, ConstParamId,
53    DefWithBodyId, EnumId, EnumVariantId, ExpressionStoreOwnerId, ExternBlockId, ExternCrateId,
54    FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalFieldId,
55    Lookup, MacroExpander, MacroId, StaticId, StructId, SyntheticSyntax, TupleId, TypeAliasId,
56    TypeOrConstParamId, TypeParamId, UnionId,
57    attrs::AttrFlags,
58    builtin_derive::BuiltinDeriveImplMethod,
59    expr_store::{ExpressionStore, ExpressionStoreDiagnostics, ExpressionStoreSourceMap},
60    hir::{
61        BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, LabelId, Pat,
62        generics::{GenericParams, LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
63    },
64    item_tree::ImportAlias,
65    lang_item::LangItemTarget,
66    layout::{self, ReprOptions, TargetDataLayout},
67    nameres::{
68        assoc::TraitItems,
69        diagnostics::{DefDiagnostic, DefDiagnosticKind},
70    },
71    per_ns::PerNs,
72    resolver::{HasResolver, Resolver},
73    signatures::{
74        ConstSignature, EnumSignature, FunctionSignature, ImplFlags, ImplSignature, StaticFlags,
75        StaticSignature, StructFlags, StructSignature, TraitFlags, TraitSignature,
76        TypeAliasSignature, UnionSignature, VariantFields,
77    },
78    src::HasSource as _,
79    unstable_features::UnstableFeatures,
80    visibility::visibility_from_ast,
81};
82use hir_expand::{
83    AstId, MacroCallKind, RenderedExpandError, ValueResult, builtin::BuiltinDeriveExpander,
84    proc_macro::ProcMacroKind,
85};
86use hir_ty::{
87    GenericPredicates, InferBodyId, InferenceResult, ParamEnvAndCrate, TyDefId,
88    TyLoweringDiagnostic, ValueTyDefId, all_super_traits, autoderef, check_orphan_rules,
89    consteval::try_const_usize,
90    db::{
91        AnonConstId, InternedClosure, InternedClosureId, InternedCoroutineClosureId,
92        InternedCoroutineId,
93    },
94    diagnostics::BodyValidationDiagnostic,
95    direct_super_traits, known_const_to_ast,
96    layout::{Layout as TyLayout, RustcEnumVariantIdx, RustcFieldIdx, TagEncoding},
97    method_resolution::{self, InherentImpls, MethodResolutionContext},
98    mir::interpret_mir,
99    next_solver::{
100        AliasTy, AnyImplId, ClauseKind, DbInterner, EarlyBinder, ErrorGuaranteed, FnSig,
101        GenericArg, GenericArgs, ParamEnv, PolyFnSig, Region, SolverDefId, Ty, TyKind, TypingMode,
102        infer::{DbInternerInferExt, InferCtxt},
103    },
104    traits::{self, is_inherent_impl_coherent, structurally_normalize_ty},
105};
106use itertools::Itertools;
107use rustc_hash::{FxHashMap, FxHashSet};
108use rustc_type_ir::{
109    AliasTyKind, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, fast_reject,
110    inherent::{AdtDef as _, GenericArgs as _, IntoKind, SliceLike, Term as _, Ty as _},
111};
112use span::{AstIdNode, Edition, FileId};
113use stdx::{format_to, impl_from, never};
114use syntax::{
115    AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, TextRange, ToSmolStr,
116    ast::{self, HasName as _, HasVisibility as _},
117    format_smolstr,
118};
119use triomphe::Arc;
120
121use crate::db::HirDatabase;
122
123#[derive(Debug, Clone, Copy, PartialEq, Eq)]
124pub enum PredicateEvaluationStatus {
125    Holds,
126    NotProven,
127    Invalid,
128    Unsupported,
129}
130
131#[derive(Debug, Clone, PartialEq, Eq)]
132pub struct PredicateEvaluationResult {
133    pub status: PredicateEvaluationStatus,
134    pub message: String,
135}
136
137impl PredicateEvaluationResult {
138    pub fn holds(message: impl Into<String>) -> Self {
139        Self { status: PredicateEvaluationStatus::Holds, message: message.into() }
140    }
141
142    pub fn not_proven(message: impl Into<String>) -> Self {
143        Self { status: PredicateEvaluationStatus::NotProven, message: message.into() }
144    }
145
146    pub fn invalid(message: impl Into<String>) -> Self {
147        Self { status: PredicateEvaluationStatus::Invalid, message: message.into() }
148    }
149
150    pub fn unsupported(message: impl Into<String>) -> Self {
151        Self { status: PredicateEvaluationStatus::Unsupported, message: message.into() }
152    }
153}
154
155pub use crate::{
156    attrs::{AttrsWithOwner, HasAttrs, resolve_doc_path_on},
157    diagnostics::*,
158    has_source::HasSource,
159    semantics::{
160        LintAttr, PathResolution, PathResolutionPerNs, Semantics, SemanticsImpl, SemanticsScope,
161        TypeInfo, VisibleTraits,
162    },
163};
164
165// Be careful with these re-exports.
166//
167// `hir` is the boundary between the compiler and the IDE. It should try hard to
168// isolate the compiler from the ide, to allow the two to be refactored
169// independently. Re-exporting something from the compiler is the sure way to
170// breach the boundary.
171//
172// Generally, a refactoring which *removes* a name from this list is a good
173// idea!
174pub use {
175    cfg::{CfgAtom, CfgExpr, CfgOptions},
176    hir_def::{
177        Complete,
178        FindPathConfig,
179        attrs::{Docs, IsInnerDoc},
180        expr_store::Body,
181        find_path::PrefixKind,
182        import_map,
183        lang_item::{LangItemEnum as LangItem, crate_lang_items},
184        nameres::{DefMap, ModuleSource, crate_def_map},
185        per_ns::Namespace,
186        type_ref::{Mutability, TypeRef},
187        visibility::Visibility,
188        // FIXME: This is here since some queries take it as input that are used
189        // outside of hir.
190        {GenericParamId, ModuleDefId, TraitId},
191    },
192    hir_expand::{
193        EditionedFileId, ExpandResult, HirFileId, MacroCallId, MacroKind,
194        change::ChangeWithProcMacros,
195        files::{
196            FilePosition, FilePositionWrapper, FileRange, FileRangeWrapper, HirFilePosition,
197            HirFileRange, InFile, InFileWrapper, InMacroFile, InRealFile, MacroFilePosition,
198            MacroFileRange,
199        },
200        inert_attr_macro::AttributeTemplate,
201        mod_path::{ModPath, PathKind, tool_path},
202        name::{self, Name},
203        prettify_macro_expansion,
204        proc_macro::{ProcMacros, ProcMacrosBuilder},
205        tt,
206    },
207    // FIXME: Properly encapsulate mir
208    hir_ty::mir,
209    hir_ty::{
210        CastError, PointerCast, attach_db, attach_db_allow_change,
211        consteval::ConstEvalError,
212        diagnostics::UnsafetyReason,
213        display::{ClosureStyle, DisplayTarget, HirDisplay, HirDisplayError, HirWrite},
214        drop::DropGlue,
215        dyn_compatibility::{DynCompatibilityViolation, MethodViolationCode},
216        layout::LayoutError,
217        mir::{MirEvalError, MirLowerError},
218        next_solver::abi::Safety,
219        next_solver::{clear_tls_solver_cache, collect_ty_garbage},
220        setup_tracing,
221    },
222    // FIXME: These are needed for import assets, properly encapsulate them.
223    hir_ty::{method_resolution::TraitImpls, next_solver::SimplifiedType},
224    intern::{Symbol, sym},
225};
226
227// These are negative re-exports: pub using these names is forbidden, they
228// should remain private to hir internals.
229#[allow(unused)]
230use {
231    hir_def::expr_store::path::Path,
232    hir_expand::{
233        name::AsName,
234        span_map::{ExpansionSpanMap, RealSpanMap, SpanMap},
235    },
236    hir_ty::next_solver,
237};
238
239/// hir::Crate describes a single crate. It's the main interface with which
240/// a crate's dependencies interact. Mostly, it should be just a proxy for the
241/// root module.
242#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
243pub struct Crate {
244    pub(crate) id: base_db::Crate,
245}
246
247#[derive(Debug)]
248pub struct CrateDependency {
249    pub krate: Crate,
250    pub name: Name,
251}
252
253impl Crate {
254    pub fn base(self) -> base_db::Crate {
255        self.id
256    }
257
258    pub fn origin(self, db: &dyn HirDatabase) -> CrateOrigin {
259        self.id.data(db).origin.clone()
260    }
261
262    pub fn is_builtin(self, db: &dyn HirDatabase) -> bool {
263        matches!(self.origin(db), CrateOrigin::Lang(_))
264    }
265
266    pub fn dependencies(self, db: &dyn HirDatabase) -> Vec<CrateDependency> {
267        self.id
268            .data(db)
269            .dependencies
270            .iter()
271            .map(|dep| {
272                let krate = Crate { id: dep.crate_id };
273                let name = dep.as_name();
274                CrateDependency { krate, name }
275            })
276            .collect()
277    }
278
279    pub fn reverse_dependencies(self, db: &dyn HirDatabase) -> Vec<Crate> {
280        let all_crates = all_crates(db);
281        all_crates
282            .iter()
283            .copied()
284            .filter(|&krate| krate.data(db).dependencies.iter().any(|it| it.crate_id == self.id))
285            .map(|id| Crate { id })
286            .collect()
287    }
288
289    pub fn transitive_reverse_dependencies(
290        self,
291        db: &dyn HirDatabase,
292    ) -> impl Iterator<Item = Crate> {
293        self.id.transitive_rev_deps(db).into_iter().map(|id| Crate { id })
294    }
295
296    pub fn notable_traits_in_deps(self, db: &dyn HirDatabase) -> impl Iterator<Item = &TraitId> {
297        self.id
298            .transitive_deps(db)
299            .into_iter()
300            .filter_map(|krate| hir_def::crate_notable_traits(db, krate))
301            .flatten()
302    }
303
304    pub fn root_module(self, db: &dyn HirDatabase) -> Module {
305        Module { id: crate_def_map(db, self.id).root_module_id() }
306    }
307
308    pub fn modules(self, db: &dyn HirDatabase) -> Vec<Module> {
309        let def_map = crate_def_map(db, self.id);
310        def_map.modules().map(|(id, _)| id.into()).collect()
311    }
312
313    pub fn root_file(self, db: &dyn HirDatabase) -> FileId {
314        self.id.data(db).root_file_id
315    }
316
317    pub fn edition(self, db: &dyn HirDatabase) -> Edition {
318        self.id.data(db).edition
319    }
320
321    pub fn version(self, db: &dyn HirDatabase) -> Option<String> {
322        self.id.extra_data(db).version.clone()
323    }
324
325    pub fn display_name(self, db: &dyn HirDatabase) -> Option<CrateDisplayName> {
326        self.id.extra_data(db).display_name.clone()
327    }
328
329    pub fn query_external_importables(
330        self,
331        db: &dyn SourceDatabase,
332        query: import_map::Query,
333    ) -> impl Iterator<Item = (Either<ModuleDef, Macro>, Complete)> {
334        let _p = tracing::info_span!("query_external_importables").entered();
335        import_map::search_dependencies(db, self.into(), &query).into_iter().map(
336            |(item, do_not_complete)| {
337                let item = match ItemInNs::from(item) {
338                    ItemInNs::Types(mod_id) | ItemInNs::Values(mod_id) => Either::Left(mod_id),
339                    ItemInNs::Macros(mac_id) => Either::Right(mac_id),
340                };
341                (item, do_not_complete)
342            },
343        )
344    }
345
346    pub fn all(db: &dyn HirDatabase) -> Vec<Crate> {
347        all_crates(db).iter().map(|&id| Crate { id }).collect()
348    }
349
350    /// Try to get the root URL of the documentation of a crate.
351    pub fn get_html_root_url(self, db: &dyn HirDatabase) -> Option<String> {
352        // Look for #![doc(html_root_url = "...")]
353        let doc_url = AttrFlags::doc_html_root_url(db, self.id);
354        doc_url.as_ref().map(|s| s.trim_matches('"').trim_end_matches('/').to_owned() + "/")
355    }
356
357    pub fn cfg<'db>(&self, db: &'db dyn HirDatabase) -> &'db CfgOptions {
358        self.id.cfg_options(db)
359    }
360
361    pub fn potential_cfg<'db>(&self, db: &'db dyn HirDatabase) -> &'db CfgOptions {
362        let data = self.id.extra_data(db);
363        data.potential_cfg_options.as_ref().unwrap_or_else(|| self.id.cfg_options(db))
364    }
365
366    pub fn to_display_target(self, db: &dyn HirDatabase) -> DisplayTarget {
367        DisplayTarget::from_crate(db, self.id)
368    }
369
370    fn core(db: &dyn HirDatabase) -> Option<Crate> {
371        all_crates(db)
372            .iter()
373            .copied()
374            .find(|&krate| {
375                matches!(krate.data(db).origin, CrateOrigin::Lang(LangCrateOrigin::Core))
376            })
377            .map(Crate::from)
378    }
379
380    pub fn is_unstable_feature_enabled(self, db: &dyn HirDatabase, feature: &Symbol) -> bool {
381        UnstableFeatures::query(db, self.id).is_enabled(feature)
382    }
383}
384
385#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
386pub struct Module {
387    pub(crate) id: ModuleId,
388}
389
390/// The defs which can be visible in the module.
391#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
392pub enum ModuleDef {
393    Module(Module),
394    Function(Function),
395    Adt(Adt),
396    // Can't be directly declared, but can be imported.
397    EnumVariant(EnumVariant),
398    Const(Const),
399    Static(Static),
400    Trait(Trait),
401    TypeAlias(TypeAlias),
402    BuiltinType(BuiltinType),
403    Macro(Macro),
404}
405impl_from!(
406    Module,
407    Function,
408    Adt(Struct, Enum, Union),
409    EnumVariant,
410    Const,
411    Static,
412    Trait,
413    TypeAlias,
414    BuiltinType,
415    Macro
416    for ModuleDef
417);
418
419impl_from!(
420    Variant { Struct => Adt, Union => Adt, EnumVariant => EnumVariant }
421    for ModuleDef
422);
423
424impl ModuleDef {
425    pub fn module(self, db: &dyn HirDatabase) -> Option<Module> {
426        match self {
427            ModuleDef::Module(it) => it.parent(db),
428            ModuleDef::Function(it) => Some(it.module(db)),
429            ModuleDef::Adt(it) => Some(it.module(db)),
430            ModuleDef::EnumVariant(it) => Some(it.module(db)),
431            ModuleDef::Const(it) => Some(it.module(db)),
432            ModuleDef::Static(it) => Some(it.module(db)),
433            ModuleDef::Trait(it) => Some(it.module(db)),
434            ModuleDef::TypeAlias(it) => Some(it.module(db)),
435            ModuleDef::Macro(it) => Some(it.module(db)),
436            ModuleDef::BuiltinType(_) => None,
437        }
438    }
439
440    pub fn canonical_path(&self, db: &dyn HirDatabase, edition: Edition) -> Option<String> {
441        let name = self.name(db)?;
442        let segments = self.module(db)?.path_segments(db).chain(Some(name));
443        Some(segments.map(|it| it.display(db, edition).to_string()).join("::"))
444    }
445
446    pub fn canonical_module_path(
447        &self,
448        db: &dyn HirDatabase,
449    ) -> Option<impl Iterator<Item = Module>> {
450        self.module(db).map(|it| it.path_to_root(db).into_iter().rev())
451    }
452
453    pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
454        let name = match self {
455            ModuleDef::Module(it) => it.name(db)?,
456            ModuleDef::Const(it) => it.name(db)?,
457            ModuleDef::Adt(it) => it.name(db),
458            ModuleDef::Trait(it) => it.name(db),
459            ModuleDef::Function(it) => it.name(db),
460            ModuleDef::EnumVariant(it) => it.name(db),
461            ModuleDef::TypeAlias(it) => it.name(db),
462            ModuleDef::Static(it) => it.name(db),
463            ModuleDef::Macro(it) => it.name(db),
464            ModuleDef::BuiltinType(it) => it.name(),
465        };
466        Some(name)
467    }
468
469    pub fn diagnostics<'db>(
470        self,
471        db: &'db dyn HirDatabase,
472        style_lints: bool,
473    ) -> Vec<AnyDiagnostic<'db>> {
474        let id = match self {
475            ModuleDef::Adt(it) => match it {
476                Adt::Struct(it) => it.id.into(),
477                Adt::Enum(it) => it.id.into(),
478                Adt::Union(it) => it.id.into(),
479            },
480            ModuleDef::Trait(it) => it.id.into(),
481            ModuleDef::Function(it) => match it.id {
482                AnyFunctionId::FunctionId(it) => it.into(),
483                AnyFunctionId::BuiltinDeriveImplMethod { .. } => return Vec::new(),
484            },
485            ModuleDef::TypeAlias(it) => it.id.into(),
486            ModuleDef::Module(it) => it.id.into(),
487            ModuleDef::Const(it) => it.id.into(),
488            ModuleDef::Static(it) => it.id.into(),
489            ModuleDef::EnumVariant(it) => it.id.into(),
490            ModuleDef::BuiltinType(_) | ModuleDef::Macro(_) => return Vec::new(),
491        };
492
493        let mut acc = Vec::new();
494
495        match self.as_def_with_body() {
496            Some(def) => {
497                def.diagnostics(db, &mut acc, style_lints);
498            }
499            None => {
500                for diag in hir_ty::diagnostics::incorrect_case(db, id) {
501                    acc.push(diag.into())
502                }
503            }
504        }
505
506        if let Some(def) = self.as_self_generic_def() {
507            def.diagnostics(db, &mut acc);
508        }
509
510        acc
511    }
512
513    pub fn as_def_with_body(self) -> Option<DefWithBody> {
514        match self {
515            ModuleDef::Function(it) => Some(it.into()),
516            ModuleDef::Const(it) => Some(it.into()),
517            ModuleDef::Static(it) => Some(it.into()),
518            ModuleDef::EnumVariant(it) => Some(it.into()),
519
520            ModuleDef::Module(_)
521            | ModuleDef::Adt(_)
522            | ModuleDef::Trait(_)
523            | ModuleDef::TypeAlias(_)
524            | ModuleDef::Macro(_)
525            | ModuleDef::BuiltinType(_) => None,
526        }
527    }
528
529    /// Returns only defs that have generics from themselves, not their parent.
530    pub fn as_self_generic_def(self) -> Option<GenericDef> {
531        match self {
532            ModuleDef::Function(it) => Some(it.into()),
533            ModuleDef::Adt(it) => Some(it.into()),
534            ModuleDef::Trait(it) => Some(it.into()),
535            ModuleDef::TypeAlias(it) => Some(it.into()),
536            ModuleDef::Module(_)
537            | ModuleDef::EnumVariant(_)
538            | ModuleDef::Static(_)
539            | ModuleDef::Const(_)
540            | ModuleDef::BuiltinType(_)
541            | ModuleDef::Macro(_) => None,
542        }
543    }
544
545    pub fn as_generic_def(self) -> Option<GenericDef> {
546        match self {
547            ModuleDef::Function(it) => Some(it.into()),
548            ModuleDef::Adt(it) => Some(it.into()),
549            ModuleDef::Trait(it) => Some(it.into()),
550            ModuleDef::TypeAlias(it) => Some(it.into()),
551            ModuleDef::Static(it) => Some(it.into()),
552            ModuleDef::Const(it) => Some(it.into()),
553            ModuleDef::EnumVariant(_)
554            | ModuleDef::Module(_)
555            | ModuleDef::BuiltinType(_)
556            | ModuleDef::Macro(_) => None,
557        }
558    }
559
560    pub fn attrs(&self, db: &dyn HirDatabase) -> Option<AttrsWithOwner> {
561        Some(match self {
562            ModuleDef::Module(it) => it.attrs(db),
563            ModuleDef::Function(it) => HasAttrs::attrs(*it, db),
564            ModuleDef::Adt(it) => it.attrs(db),
565            ModuleDef::EnumVariant(it) => it.attrs(db),
566            ModuleDef::Const(it) => it.attrs(db),
567            ModuleDef::Static(it) => it.attrs(db),
568            ModuleDef::Trait(it) => it.attrs(db),
569            ModuleDef::TypeAlias(it) => it.attrs(db),
570            ModuleDef::Macro(it) => it.attrs(db),
571            ModuleDef::BuiltinType(_) => return None,
572        })
573    }
574}
575
576impl HasCrate for ModuleDef {
577    fn krate(&self, db: &dyn HirDatabase) -> Crate {
578        match self.module(db) {
579            Some(module) => module.krate(db),
580            None => Crate::core(db).unwrap_or_else(|| all_crates(db)[0].into()),
581        }
582    }
583}
584
585impl HasAttrs for ModuleDef {
586    fn attr_id(self, db: &dyn HirDatabase) -> attrs::AttrsOwner {
587        match self {
588            ModuleDef::Module(it) => it.attr_id(db),
589            ModuleDef::Function(it) => it.attr_id(db),
590            ModuleDef::Adt(it) => it.attr_id(db),
591            ModuleDef::EnumVariant(it) => it.attr_id(db),
592            ModuleDef::Const(it) => it.attr_id(db),
593            ModuleDef::Static(it) => it.attr_id(db),
594            ModuleDef::Trait(it) => it.attr_id(db),
595            ModuleDef::TypeAlias(it) => it.attr_id(db),
596            ModuleDef::Macro(it) => it.attr_id(db),
597            ModuleDef::BuiltinType(_) => attrs::AttrsOwner::Dummy,
598        }
599    }
600}
601
602impl HasVisibility for ModuleDef {
603    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
604        match *self {
605            ModuleDef::Module(it) => it.visibility(db),
606            ModuleDef::Function(it) => it.visibility(db),
607            ModuleDef::Adt(it) => it.visibility(db),
608            ModuleDef::Const(it) => it.visibility(db),
609            ModuleDef::Static(it) => it.visibility(db),
610            ModuleDef::Trait(it) => it.visibility(db),
611            ModuleDef::TypeAlias(it) => it.visibility(db),
612            ModuleDef::EnumVariant(it) => it.visibility(db),
613            ModuleDef::Macro(it) => it.visibility(db),
614            ModuleDef::BuiltinType(_) => Visibility::Public,
615        }
616    }
617}
618
619impl Module {
620    /// Name of this module.
621    pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
622        self.id.name(db)
623    }
624
625    /// Returns the crate this module is part of.
626    pub fn krate(self, db: &dyn HirDatabase) -> Crate {
627        Crate { id: self.id.krate(db) }
628    }
629
630    /// Topmost parent of this module. Every module has a `crate_root`, but some
631    /// might be missing `krate`. This can happen if a module's file is not included
632    /// in the module tree of any target in `Cargo.toml`.
633    pub fn crate_root(self, db: &dyn HirDatabase) -> Module {
634        let def_map = crate_def_map(db, self.id.krate(db));
635        Module { id: def_map.crate_root(db) }
636    }
637
638    pub fn is_crate_root(self, db: &dyn HirDatabase) -> bool {
639        self.crate_root(db) == self
640    }
641
642    /// Iterates over all child modules.
643    pub fn children(self, db: &dyn HirDatabase) -> impl Iterator<Item = Module> {
644        let def_map = self.id.def_map(db);
645        let children = def_map[self.id]
646            .children
647            .values()
648            .map(|module_id| Module { id: *module_id })
649            .collect::<Vec<_>>();
650        children.into_iter()
651    }
652
653    /// Finds a parent module.
654    pub fn parent(self, db: &dyn HirDatabase) -> Option<Module> {
655        let def_map = self.id.def_map(db);
656        let parent_id = def_map.containing_module(self.id)?;
657        Some(Module { id: parent_id })
658    }
659
660    /// Finds nearest non-block ancestor `Module` (`self` included).
661    pub fn nearest_non_block_module(self, db: &dyn HirDatabase) -> Module {
662        let mut id = self.id;
663        while id.is_block_module(db) {
664            id = id.containing_module(db).expect("block without parent module");
665        }
666        Module { id: unsafe { id.to_static() } }
667    }
668
669    pub fn path_to_root(self, db: &dyn HirDatabase) -> Vec<Module> {
670        let mut res = vec![self];
671        let mut curr = self;
672        while let Some(next) = curr.parent(db) {
673            res.push(next);
674            curr = next
675        }
676        res
677    }
678
679    /// Names of the modules enclosing `self`, crate root first, `self` last.
680    ///
681    /// Nameless modules — the crate root, and block modules — drop out, so this is
682    /// generally shorter than [`Module::path_to_root`]. Segments stay `Name`s rather
683    /// than rendered text because callers disagree on the edition to display with,
684    /// and some need to take the path apart rather than print it.
685    ///
686    /// [`ModuleDef::canonical_module_path`] is the same walk yielding the `Module`s
687    /// themselves, for callers that need more than the name — each module's own
688    /// edition, say.
689    pub fn path_segments(self, db: &dyn HirDatabase) -> impl Iterator<Item = Name> {
690        self.path_to_root(db).into_iter().rev().filter_map(|it| it.name(db))
691    }
692
693    pub fn modules_in_scope(&self, db: &dyn HirDatabase, pub_only: bool) -> Vec<(Name, Module)> {
694        let def_map = self.id.def_map(db);
695        let scope = &def_map[self.id].scope;
696
697        let mut res = Vec::new();
698
699        for (name, item) in scope.types() {
700            if let ModuleDefId::ModuleId(m) = item.def
701                && (!pub_only || item.vis == Visibility::Public)
702            {
703                res.push((name.clone(), Module { id: m }));
704            }
705        }
706
707        res
708    }
709
710    /// Returns a `ModuleScope`: a set of items, visible in this module.
711    pub fn scope(
712        self,
713        db: &dyn HirDatabase,
714        visible_from: Option<Module>,
715    ) -> Vec<(Name, ScopeDef<'_>)> {
716        self.id.def_map(db)[self.id]
717            .scope
718            .entries()
719            .filter_map(|(name, def)| {
720                if let Some(m) = visible_from {
721                    let filtered = def.filter_visibility(|vis| vis.is_visible_from(db, m.id));
722                    if filtered.is_none() && !def.is_none() { None } else { Some((name, filtered)) }
723                } else {
724                    Some((name, def))
725                }
726            })
727            .flat_map(|(name, def)| {
728                ScopeDef::all_items(def).into_iter().map(move |item| (name.clone(), item))
729            })
730            .collect()
731    }
732
733    pub fn resolve_mod_path(
734        &self,
735        db: &dyn HirDatabase,
736        segments: impl IntoIterator<Item = Name>,
737    ) -> Option<impl Iterator<Item = ItemInNs>> {
738        let items = self
739            .id
740            .resolver(db)
741            .resolve_module_path_in_items(db, &ModPath::from_segments(PathKind::Plain, segments));
742        Some(items.iter_items().map(|(item, _)| item.into()))
743    }
744
745    /// Fills `acc` with the module's diagnostics.
746    pub fn diagnostics<'db>(
747        self,
748        db: &'db dyn HirDatabase,
749        acc: &mut Vec<AnyDiagnostic<'db>>,
750        style_lints: bool,
751    ) {
752        let _p = tracing::info_span!("diagnostics", name = ?self.name(db)).entered();
753        let edition = self.id.krate(db).data(db).edition;
754        let def_map = self.id.def_map(db);
755        for diag in def_map.diagnostics() {
756            if diag.in_module != self.id {
757                // FIXME: This is accidentally quadratic.
758                continue;
759            }
760            emit_def_diagnostic(db, acc, diag, edition, def_map.krate());
761        }
762
763        if !self.id.is_block_module(db) {
764            // These are reported by the body of block modules
765            let scope = &def_map[self.id].scope;
766            scope.all_macro_calls().for_each(|it| macro_call_diagnostics(db, it, acc));
767        }
768
769        for def in self.declarations(db) {
770            match def {
771                ModuleDef::Module(m) => {
772                    // Only add diagnostics from inline modules
773                    if def_map[m.id].origin.is_inline() {
774                        m.diagnostics(db, acc, style_lints)
775                    }
776                    acc.extend(def.diagnostics(db, style_lints))
777                }
778                ModuleDef::Trait(t) => {
779                    let krate = t.krate(db);
780                    for diag in TraitItems::query_with_diagnostics(db, t.id).1.iter() {
781                        emit_def_diagnostic(db, acc, diag, edition, krate.id);
782                    }
783
784                    for item in t.items(db) {
785                        item.diagnostics(db, acc, style_lints);
786                    }
787
788                    t.all_macro_calls(db)
789                        .iter()
790                        .for_each(|&(_ast, call_id)| macro_call_diagnostics(db, call_id, acc));
791
792                    acc.extend(def.diagnostics(db, style_lints))
793                }
794                ModuleDef::Adt(adt) => {
795                    match adt {
796                        Adt::Struct(s) => {
797                            let source_map = &StructSignature::with_source_map(db, s.id).1;
798                            expr_store_diagnostics(db, acc, source_map);
799                            let source_map = &s.id.fields_with_source_map(db).1;
800                            expr_store_diagnostics(db, acc, source_map);
801                            push_ty_diagnostics(
802                                db,
803                                acc,
804                                db.field_types_with_diagnostics(s.id.into()).diagnostics(),
805                                source_map,
806                            );
807                        }
808                        Adt::Union(u) => {
809                            let source_map = &UnionSignature::with_source_map(db, u.id).1;
810                            expr_store_diagnostics(db, acc, source_map);
811                            let source_map = &u.id.fields_with_source_map(db).1;
812                            expr_store_diagnostics(db, acc, source_map);
813                            push_ty_diagnostics(
814                                db,
815                                acc,
816                                db.field_types_with_diagnostics(u.id.into()).diagnostics(),
817                                source_map,
818                            );
819                        }
820                        Adt::Enum(e) => {
821                            let source_map = &EnumSignature::with_source_map(db, e.id).1;
822                            expr_store_diagnostics(db, acc, source_map);
823                            let (variants, diagnostics) = e.id.enum_variants_with_diagnostics(db);
824                            let file = e.id.lookup(db).id.file_id;
825                            let ast_id_map = file.ast_id_map(db);
826                            for diag in diagnostics {
827                                acc.push(
828                                    InactiveCode {
829                                        node: InFile::new(
830                                            file,
831                                            ast_id_map.get(diag.ast_id).syntax_node_ptr(),
832                                        ),
833                                        cfg: diag.cfg.clone(),
834                                        opts: diag.opts.clone(),
835                                    }
836                                    .into(),
837                                );
838                            }
839                            for &(v, _) in variants.variants.values() {
840                                let source_map = &v.fields_with_source_map(db).1;
841                                push_ty_diagnostics(
842                                    db,
843                                    acc,
844                                    db.field_types_with_diagnostics(v.into()).diagnostics(),
845                                    source_map,
846                                );
847                                expr_store_diagnostics(db, acc, source_map);
848                            }
849                        }
850                    }
851                    acc.extend(def.diagnostics(db, style_lints))
852                }
853                ModuleDef::Macro(m) => emit_macro_def_diagnostics(db, acc, m),
854                ModuleDef::TypeAlias(type_alias) => {
855                    let source_map = &TypeAliasSignature::with_source_map(db, type_alias.id).1;
856                    expr_store_diagnostics(db, acc, source_map);
857                    push_ty_diagnostics(
858                        db,
859                        acc,
860                        db.type_for_type_alias_with_diagnostics(type_alias.id).diagnostics(),
861                        source_map,
862                    );
863                    acc.extend(def.diagnostics(db, style_lints));
864                }
865                _ => acc.extend(def.diagnostics(db, style_lints)),
866            }
867        }
868        self.legacy_macros(db).into_iter().for_each(|m| emit_macro_def_diagnostics(db, acc, m));
869
870        let interner = DbInterner::new_with(db, self.id.krate(db));
871        let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
872
873        let mut impl_assoc_items_scratch = vec![];
874        for impl_def in self.impl_defs(db) {
875            GenericDef::Impl(impl_def).diagnostics(db, acc);
876
877            let AnyImplId::ImplId(impl_id) = impl_def.id else {
878                continue;
879            };
880            let loc = impl_id.lookup(db);
881            let (impl_signature, source_map) = ImplSignature::with_source_map(db, impl_id);
882            expr_store_diagnostics(db, acc, source_map);
883
884            let file_id = loc.id.file_id;
885            if file_id.macro_file().is_some_and(|it| it.kind(db) == MacroKind::DeriveBuiltIn) {
886                // these expansion come from us, diagnosing them is a waste of resources
887                // FIXME: Once we diagnose the inputs to builtin derives, we should at least extract those diagnostics somehow
888                continue;
889            }
890            impl_def
891                .all_macro_calls(db)
892                .iter()
893                .for_each(|&(_ast, call_id)| macro_call_diagnostics(db, call_id, acc));
894
895            let ast_id_map = file_id.ast_id_map(db);
896
897            for diag in impl_id.impl_items_with_diagnostics(db).1.iter() {
898                emit_def_diagnostic(db, acc, diag, edition, loc.container.krate(db));
899            }
900
901            let trait_impl = impl_signature.target_trait.is_some();
902            if !trait_impl && !is_inherent_impl_coherent(db, def_map, impl_id) {
903                acc.push(IncoherentImpl { impl_: ast_id_map.get(loc.id.value), file_id }.into())
904            }
905
906            if trait_impl && !impl_def.check_orphan_rules(db) {
907                acc.push(TraitImplOrphan { impl_: ast_id_map.get(loc.id.value), file_id }.into())
908            }
909
910            let trait_ = trait_impl.then(|| impl_def.trait_(db)).flatten();
911            let mut trait_is_unsafe = trait_.is_some_and(|t| t.is_unsafe(db));
912            let impl_is_negative = impl_def.is_negative(db);
913            let impl_is_unsafe = impl_def.is_unsafe(db);
914
915            let trait_is_unresolved = trait_.is_none() && trait_impl;
916            if trait_is_unresolved {
917                // Ignore trait safety errors when the trait is unresolved, as otherwise we'll treat it as safe,
918                // which may not be correct.
919                trait_is_unsafe = impl_is_unsafe;
920            }
921
922            let drop_maybe_dangle = (|| {
923                let trait_ = trait_?;
924                let drop_trait = interner.lang_items().Drop?;
925                if drop_trait != trait_.into() {
926                    return None;
927                }
928                let parent = impl_id.into();
929                let (lifetimes_attrs, type_and_consts_attrs) =
930                    AttrFlags::query_generic_params(db, parent);
931                let res = lifetimes_attrs.values().any(|it| it.contains(AttrFlags::MAY_DANGLE))
932                    || type_and_consts_attrs.values().any(|it| it.contains(AttrFlags::MAY_DANGLE));
933                Some(res)
934            })()
935            .unwrap_or(false);
936
937            match (impl_is_unsafe, trait_is_unsafe, impl_is_negative, drop_maybe_dangle) {
938                // unsafe negative impl
939                (true, _, true, _) |
940                // unsafe impl for safe trait
941                (true, false, _, false) => acc.push(TraitImplIncorrectSafety { impl_: ast_id_map.get(loc.id.value), file_id, should_be_safe: true }.into()),
942                // safe impl for unsafe trait
943                (false, true, false, _) |
944                // safe impl of dangling drop
945                (false, false, _, true) => acc.push(TraitImplIncorrectSafety { impl_: ast_id_map.get(loc.id.value), file_id, should_be_safe: false }.into()),
946                _ => (),
947            };
948
949            // Negative impls can't have items, don't emit missing items diagnostic for them
950            if let (false, Some(trait_)) = (impl_is_negative, trait_) {
951                let items = &trait_.id.trait_items(db).items;
952                let required_items = items.iter().filter(|&(_, assoc)| match *assoc {
953                    AssocItemId::FunctionId(it) => !FunctionSignature::of(db, it).has_body(),
954                    AssocItemId::ConstId(id) => !ConstSignature::of(db, id).has_body(),
955                    AssocItemId::TypeAliasId(it) => TypeAliasSignature::of(db, it).ty.is_none(),
956                });
957                impl_assoc_items_scratch.extend(impl_id.impl_items(db).items.iter().cloned());
958
959                let redundant = impl_assoc_items_scratch
960                    .iter()
961                    .filter(|(name, id)| {
962                        !items.iter().any(|(impl_name, impl_item)| {
963                            discriminant(impl_item) == discriminant(id) && impl_name == name
964                        })
965                    })
966                    .map(|(name, item)| (name.clone(), AssocItem::from(*item)));
967                for (name, assoc_item) in redundant {
968                    acc.push(
969                        TraitImplRedundantAssocItems {
970                            trait_,
971                            file_id,
972                            impl_: ast_id_map.get(loc.id.value),
973                            assoc_item: (name, assoc_item),
974                        }
975                        .into(),
976                    )
977                }
978
979                let mut missing: Vec<_> = required_items
980                    .filter(|(name, id)| {
981                        !impl_assoc_items_scratch.iter().any(|(impl_name, impl_item)| {
982                            discriminant(impl_item) == discriminant(id) && impl_name == name
983                        })
984                    })
985                    .map(|(name, item)| (name.clone(), AssocItem::from(*item)))
986                    .collect();
987
988                if !missing.is_empty() {
989                    let env = ParamEnvAndCrate {
990                        param_env: db.trait_environment(GenericDefId::from(impl_id)),
991                        krate: self.id.krate(db),
992                    };
993                    let self_ty = db.impl_self_ty(impl_id).instantiate_identity().skip_norm_wip();
994                    let self_ty = structurally_normalize_ty(&infcx, self_ty, env.param_env);
995                    let tail_ty = struct_tail_raw(db, interner, self_ty, |ty| {
996                        structurally_normalize_ty(&infcx, ty, env.param_env)
997                    });
998                    let self_ty_is_guaranteed_unsized = matches!(
999                        tail_ty.kind(),
1000                        TyKind::Dynamic(..) | TyKind::Slice(..) | TyKind::Str
1001                    );
1002                    if self_ty_is_guaranteed_unsized {
1003                        missing.retain(|(_, assoc_item)| {
1004                            let assoc_item = match *assoc_item {
1005                                AssocItem::Function(it) => match it.id {
1006                                    AnyFunctionId::FunctionId(id) => id.into(),
1007                                    AnyFunctionId::BuiltinDeriveImplMethod { .. } => {
1008                                        never!("should not have an `AnyFunctionId::BuiltinDeriveImplMethod` here");
1009                                        return false;
1010                                    },
1011                                },
1012                                AssocItem::Const(it) => it.id.into(),
1013                                AssocItem::TypeAlias(it) => it.id.into(),
1014                            };
1015                            !hir_ty::dyn_compatibility::generics_require_sized_self(db, assoc_item)
1016                        });
1017                    }
1018                }
1019
1020                // HACK: When specialization is enabled in the current crate, and there exists
1021                // *any* blanket impl that provides a default implementation for the missing item,
1022                // suppress the missing associated item diagnostic.
1023                // This can lead to false negatives when the impl in question does not actually
1024                // specialize that blanket impl, but determining the exact specialization
1025                // relationship here would be significantly more expensive.
1026                if !missing.is_empty() {
1027                    let krate = self.krate(db).id;
1028                    let features = UnstableFeatures::query(db, krate);
1029                    if features.specialization || features.min_specialization {
1030                        missing.retain(|(assoc_name, assoc_item)| {
1031                            let AssocItem::Function(_) = assoc_item else {
1032                                return true;
1033                            };
1034
1035                            for &impl_ in TraitImpls::for_crate(db, krate).blanket_impls(trait_.id)
1036                            {
1037                                if impl_ == impl_id {
1038                                    continue;
1039                                }
1040
1041                                for (name, item) in &impl_.impl_items(db).items {
1042                                    let AssocItemId::FunctionId(fn_) = item else {
1043                                        continue;
1044                                    };
1045                                    if name != assoc_name {
1046                                        continue;
1047                                    }
1048
1049                                    if FunctionSignature::of(db, *fn_).is_default() {
1050                                        return false;
1051                                    }
1052                                }
1053                            }
1054
1055                            true
1056                        });
1057                    }
1058                }
1059
1060                if !missing.is_empty() {
1061                    acc.push(
1062                        TraitImplMissingAssocItems {
1063                            impl_: ast_id_map.get(loc.id.value),
1064                            file_id,
1065                            missing,
1066                        }
1067                        .into(),
1068                    )
1069                }
1070                impl_assoc_items_scratch.clear();
1071            }
1072
1073            push_ty_diagnostics(
1074                db,
1075                acc,
1076                db.impl_self_ty_with_diagnostics(impl_id).diagnostics(),
1077                source_map,
1078            );
1079            if let Some(it) = db.impl_trait_with_diagnostics(impl_id) {
1080                push_ty_diagnostics(db, acc, it.diagnostics(), source_map);
1081            }
1082
1083            for &(_, item) in impl_id.impl_items(db).items.iter() {
1084                AssocItem::from(item).diagnostics(db, acc, style_lints);
1085            }
1086        }
1087    }
1088
1089    pub fn declarations(self, db: &dyn HirDatabase) -> Vec<ModuleDef> {
1090        let def_map = self.id.def_map(db);
1091        let scope = &def_map[self.id].scope;
1092        scope
1093            .declarations()
1094            .map(ModuleDef::from)
1095            .chain(scope.unnamed_consts().map(|id| ModuleDef::Const(Const::from(id))))
1096            .collect()
1097    }
1098
1099    pub fn legacy_macros(self, db: &dyn HirDatabase) -> Vec<Macro> {
1100        let def_map = self.id.def_map(db);
1101        let scope = &def_map[self.id].scope;
1102        scope.legacy_macros().flat_map(|(_, it)| it).map(|&it| it.into()).collect()
1103    }
1104
1105    pub fn impl_defs(self, db: &dyn HirDatabase) -> Vec<Impl> {
1106        let def_map = self.id.def_map(db);
1107        let scope = &def_map[self.id].scope;
1108        scope.impls().map(Impl::from).chain(scope.builtin_derive_impls().map(Impl::from)).collect()
1109    }
1110
1111    /// Finds a path that can be used to refer to the given item from within
1112    /// this module, if possible.
1113    pub fn find_path(
1114        self,
1115        db: &dyn SourceDatabase,
1116        item: impl Into<ItemInNs>,
1117        cfg: FindPathConfig,
1118    ) -> Option<ModPath> {
1119        hir_def::find_path::find_path(
1120            db,
1121            item.into().try_into().ok()?,
1122            self.into(),
1123            PrefixKind::Plain,
1124            false,
1125            cfg,
1126        )
1127    }
1128
1129    /// Finds a path that can be used to refer to the given item from within
1130    /// this module, if possible. This is used for returning import paths for use-statements.
1131    pub fn find_use_path(
1132        self,
1133        db: &dyn SourceDatabase,
1134        item: impl Into<ItemInNs>,
1135        prefix_kind: PrefixKind,
1136        cfg: FindPathConfig,
1137    ) -> Option<ModPath> {
1138        hir_def::find_path::find_path(
1139            db,
1140            item.into().try_into().ok()?,
1141            self.into(),
1142            prefix_kind,
1143            true,
1144            cfg,
1145        )
1146    }
1147
1148    #[inline]
1149    pub fn doc_keyword(self, db: &dyn HirDatabase) -> Option<Symbol> {
1150        AttrFlags::doc_keyword(db, self.id)
1151    }
1152
1153    /// Whether it has `#[path = "..."]` attribute.
1154    #[inline]
1155    pub fn has_path(&self, db: &dyn HirDatabase) -> bool {
1156        self.attrs(db).attrs.contains(AttrFlags::HAS_PATH)
1157    }
1158}
1159
1160fn macro_call_diagnostics<'db>(
1161    db: &'db dyn HirDatabase,
1162    macro_call_id: MacroCallId,
1163    acc: &mut Vec<AnyDiagnostic<'db>>,
1164) {
1165    let Some(e) = macro_call_id.parse_macro_expansion_error(db) else {
1166        return;
1167    };
1168    let ValueResult { value: parse_errors, err } = e;
1169    if let Some(err) = err {
1170        let loc = macro_call_id.loc(db);
1171        let file_id = loc.kind.file_id();
1172        let mut range = precise_macro_call_location(&loc.kind, db, loc.krate);
1173        let RenderedExpandError { message, error, kind } = err.render_to_string(db);
1174        if Some(err.span().anchor.file_id) == file_id.file_id().map(|it| it.span_file_id(db)) {
1175            range.value = err.span().range
1176                + file_id.ast_id_map(db).get_erased(err.span().anchor.ast_id).text_range().start();
1177        }
1178        acc.push(MacroError { range, message, error, kind }.into());
1179    }
1180
1181    if !parse_errors.is_empty() {
1182        let loc = macro_call_id.loc(db);
1183        let range = precise_macro_call_location(&loc.kind, db, loc.krate);
1184        acc.push(MacroExpansionParseError { range, errors: parse_errors.clone() }.into())
1185    }
1186}
1187
1188fn emit_macro_def_diagnostics<'db>(
1189    db: &'db dyn HirDatabase,
1190    acc: &mut Vec<AnyDiagnostic<'db>>,
1191    m: Macro,
1192) {
1193    let id = m.id.definition(db);
1194    let krate = id.krate;
1195    if let hir_expand::MacroDefKind::Declarative(ast, _) = id.kind
1196        && let expander = ast.decl_macro_expander(db, krate)
1197        && let Some(e) = expander.mac.err()
1198    {
1199        let edition = krate.data(db).edition;
1200        emit_def_diagnostic_(
1201            db,
1202            acc,
1203            &DefDiagnosticKind::MacroDefError { ast, message: e.to_string() },
1204            edition,
1205            krate,
1206        );
1207    }
1208}
1209
1210fn emit_def_diagnostic<'db>(
1211    db: &'db dyn HirDatabase,
1212    acc: &mut Vec<AnyDiagnostic<'db>>,
1213    diag: &DefDiagnostic,
1214    edition: Edition,
1215    krate: base_db::Crate,
1216) {
1217    emit_def_diagnostic_(db, acc, &diag.kind, edition, krate)
1218}
1219
1220fn emit_def_diagnostic_<'db>(
1221    db: &'db dyn HirDatabase,
1222    acc: &mut Vec<AnyDiagnostic<'db>>,
1223    diag: &DefDiagnosticKind,
1224    edition: Edition,
1225    krate: base_db::Crate,
1226) {
1227    match diag {
1228        DefDiagnosticKind::UnresolvedModule { ast: declaration, candidates } => {
1229            let decl = declaration.to_ptr(db);
1230            acc.push(
1231                UnresolvedModule {
1232                    decl: InFile::new(declaration.file_id, decl),
1233                    candidates: candidates.clone(),
1234                }
1235                .into(),
1236            )
1237        }
1238        DefDiagnosticKind::UnresolvedExternCrate { ast } => {
1239            let item = ast.to_ptr(db);
1240            acc.push(UnresolvedExternCrate { decl: InFile::new(ast.file_id, item) }.into());
1241        }
1242
1243        DefDiagnosticKind::MacroError { ast, path, err } => {
1244            let item = ast.to_ptr(db);
1245            let RenderedExpandError { message, error, kind } = err.render_to_string(db);
1246            acc.push(
1247                MacroError {
1248                    range: InFile::new(ast.file_id, item.text_range()),
1249                    message: format!("{}: {message}", path.display(db, edition)),
1250                    error,
1251                    kind,
1252                }
1253                .into(),
1254            )
1255        }
1256        DefDiagnosticKind::UnresolvedImport { id, index } => {
1257            let file_id = id.file_id;
1258
1259            let use_tree = hir_def::src::use_tree_to_ast(db, *id, *index);
1260            acc.push(
1261                UnresolvedImport { decl: InFile::new(file_id, AstPtr::new(&use_tree)) }.into(),
1262            );
1263        }
1264
1265        DefDiagnosticKind::UnconfiguredCode { ast_id, cfg, opts } => {
1266            let ast_id_map = ast_id.file_id.ast_id_map(db);
1267            let ptr = ast_id_map.get_erased(ast_id.value);
1268            acc.push(
1269                InactiveCode {
1270                    node: InFile::new(ast_id.file_id, ptr),
1271                    cfg: cfg.clone(),
1272                    opts: opts.clone(),
1273                }
1274                .into(),
1275            );
1276        }
1277        DefDiagnosticKind::UnresolvedMacroCall { ast, path } => {
1278            let location = precise_macro_call_location(ast, db, krate);
1279            acc.push(
1280                UnresolvedMacroCall {
1281                    range: location,
1282                    path: path.clone(),
1283                    is_bang: matches!(ast, MacroCallKind::FnLike { .. }),
1284                }
1285                .into(),
1286            );
1287        }
1288        DefDiagnosticKind::UnimplementedBuiltinMacro { ast } => {
1289            let node = ast.to_node(db);
1290            // Must have a name, otherwise we wouldn't emit it.
1291            let name = node.name().expect("unimplemented builtin macro with no name");
1292            acc.push(
1293                UnimplementedBuiltinMacro {
1294                    node: ast.with_value(SyntaxNodePtr::from(AstPtr::new(&name))),
1295                }
1296                .into(),
1297            );
1298        }
1299        DefDiagnosticKind::InvalidDeriveTarget { ast, id } => {
1300            let (_, attr) = id.find_attr_range(db, krate, *ast);
1301            let derive = attr
1302                .path()
1303                .map(|path| path.syntax().text_range())
1304                .unwrap_or_else(|| attr.syntax().text_range());
1305            acc.push(InvalidDeriveTarget { range: ast.with_value(derive) }.into());
1306        }
1307        DefDiagnosticKind::MalformedDerive { ast, id } => {
1308            let derive = id.find_attr_range(db, krate, *ast).1.syntax().text_range();
1309            acc.push(MalformedDerive { range: ast.with_value(derive) }.into());
1310        }
1311        DefDiagnosticKind::MacroDefError { ast, message } => {
1312            let node = ast.to_node(db);
1313            acc.push(
1314                MacroDefError {
1315                    node: InFile::new(ast.file_id, AstPtr::new(&node)),
1316                    name: node.name().map(|it| it.syntax().text_range()),
1317                    message: message.clone(),
1318                }
1319                .into(),
1320            );
1321        }
1322    }
1323}
1324
1325fn precise_macro_call_location(
1326    ast: &MacroCallKind,
1327    db: &dyn HirDatabase,
1328    krate: base_db::Crate,
1329) -> InFile<TextRange> {
1330    // FIXME: maybe we actually want slightly different ranges for the different macro diagnostics
1331    // - e.g. the full attribute for macro errors, but only the name for name resolution
1332    match ast {
1333        MacroCallKind::FnLike { ast_id, .. } => {
1334            let node = ast_id.to_node(db);
1335            let range = node
1336                .path()
1337                .and_then(|it| it.segment())
1338                .and_then(|it| it.name_ref())
1339                .map(|it| it.syntax().text_range());
1340            let range = range.unwrap_or_else(|| node.syntax().text_range());
1341            ast_id.with_value(range)
1342        }
1343        MacroCallKind::Derive { ast_id, derive_attr_index, derive_index, .. } => {
1344            let range = derive_attr_index.find_derive_range(db, krate, *ast_id, *derive_index);
1345            ast_id.with_value(range)
1346        }
1347        MacroCallKind::Attr { ast_id, censored_attr_ids: attr_ids, .. } => {
1348            let attr_range =
1349                attr_ids.invoc_attr().find_attr_range(db, krate, *ast_id).1.syntax().text_range();
1350            ast_id.with_value(attr_range)
1351        }
1352    }
1353}
1354
1355impl HasVisibility for Module {
1356    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
1357        let def_map = self.id.def_map(db);
1358        let module_data = &def_map[self.id];
1359        module_data.visibility
1360    }
1361}
1362
1363#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1364pub struct Field {
1365    pub(crate) parent: Variant,
1366    pub(crate) id: LocalFieldId,
1367}
1368
1369#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
1370pub struct TupleField<'db> {
1371    pub owner: InferBodyId<'db>,
1372    pub tuple: TupleId,
1373    pub index: u32,
1374}
1375
1376impl<'db> TupleField<'db> {
1377    pub fn name(&self) -> Name {
1378        Name::new_tuple_field(self.index as usize)
1379    }
1380
1381    pub fn ty(&self, db: &'db dyn HirDatabase) -> Type<'db> {
1382        let interner = DbInterner::new_no_crate(db);
1383        let ty = InferenceResult::of(db, self.owner)
1384            .tuple_field_access_type(self.tuple)
1385            .as_slice()
1386            .get(self.index as usize)
1387            .copied()
1388            .unwrap_or_else(|| Ty::new_error(interner, ErrorGuaranteed));
1389        Type::new_body(db, self.owner.expression_store_owner(db), ty)
1390    }
1391}
1392
1393#[derive(Debug, PartialEq, Eq)]
1394pub enum FieldSource {
1395    Named(ast::RecordField),
1396    Pos(ast::TupleField),
1397}
1398
1399impl AstNode for FieldSource {
1400    fn can_cast(kind: syntax::SyntaxKind) -> bool
1401    where
1402        Self: Sized,
1403    {
1404        ast::RecordField::can_cast(kind) || ast::TupleField::can_cast(kind)
1405    }
1406
1407    fn cast(syntax: SyntaxNode) -> Option<Self>
1408    where
1409        Self: Sized,
1410    {
1411        if ast::RecordField::can_cast(syntax.kind()) {
1412            <ast::RecordField as AstNode>::cast(syntax).map(FieldSource::Named)
1413        } else if ast::TupleField::can_cast(syntax.kind()) {
1414            <ast::TupleField as AstNode>::cast(syntax).map(FieldSource::Pos)
1415        } else {
1416            None
1417        }
1418    }
1419
1420    fn syntax(&self) -> &SyntaxNode {
1421        match self {
1422            FieldSource::Named(it) => it.syntax(),
1423            FieldSource::Pos(it) => it.syntax(),
1424        }
1425    }
1426}
1427
1428impl Field {
1429    pub fn name(&self, db: &dyn HirDatabase) -> Name {
1430        VariantId::from(self.parent).fields(db).fields()[self.id].name.clone()
1431    }
1432
1433    pub fn index(&self) -> usize {
1434        u32::from(self.id.into_raw()) as usize
1435    }
1436
1437    /// Returns the type as in the signature of the struct. Only use this in the
1438    /// context of the field definition.
1439    pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> Type<'db> {
1440        let var_id = self.parent.into();
1441        let ty = db.field_types(var_id)[self.id].ty().instantiate_identity().skip_norm_wip();
1442        Type::new(var_id.adt_id(db).into(), ty)
1443    }
1444
1445    pub fn layout<'db>(&self, db: &'db dyn HirDatabase) -> Result<Layout<'db>, LayoutError> {
1446        self.ty(db).layout(db)
1447    }
1448
1449    pub fn parent_def(&self, _db: &dyn HirDatabase) -> Variant {
1450        self.parent
1451    }
1452}
1453
1454impl HasVisibility for Field {
1455    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
1456        let variant_data = VariantId::from(self.parent).fields(db);
1457        let visibility = &variant_data.fields()[self.id].visibility;
1458        let parent_id: hir_def::VariantId = self.parent.into();
1459        // FIXME: RawVisibility::Public doesn't need to construct a resolver
1460        Visibility::resolve(db, &parent_id.resolver(db), visibility)
1461    }
1462}
1463
1464#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1465pub struct Struct {
1466    pub(crate) id: StructId,
1467}
1468
1469impl Struct {
1470    pub fn module(self, db: &dyn HirDatabase) -> Module {
1471        Module { id: self.id.lookup(db).container }
1472    }
1473
1474    pub fn name(self, db: &dyn HirDatabase) -> Name {
1475        StructSignature::of(db, self.id).name.clone()
1476    }
1477
1478    pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
1479        self.id
1480            .fields(db)
1481            .fields()
1482            .iter()
1483            .map(|(id, _)| Field { parent: self.into(), id })
1484            .collect()
1485    }
1486
1487    pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
1488        Type::from_def(db, self.id)
1489    }
1490
1491    pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type<'_> {
1492        Type::from_value_def(db, self.id)
1493    }
1494
1495    pub fn repr(self, db: &dyn HirDatabase) -> Option<ReprOptions> {
1496        AttrFlags::repr(db, self.id.into())
1497    }
1498
1499    pub fn kind(self, db: &dyn HirDatabase) -> StructKind {
1500        match self.variant_fields(db).shape {
1501            hir_def::item_tree::FieldsShape::Record => StructKind::Record,
1502            hir_def::item_tree::FieldsShape::Tuple => StructKind::Tuple,
1503            hir_def::item_tree::FieldsShape::Unit => StructKind::Unit,
1504        }
1505    }
1506
1507    fn variant_fields(self, db: &dyn HirDatabase) -> &VariantFields {
1508        self.id.fields(db)
1509    }
1510
1511    pub fn is_unstable(self, db: &dyn HirDatabase) -> bool {
1512        AttrFlags::query(db, self.id.into()).contains(AttrFlags::IS_UNSTABLE)
1513    }
1514}
1515
1516impl HasVisibility for Struct {
1517    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
1518        let loc = self.id.lookup(db);
1519        let source = loc.source(db);
1520        visibility_from_ast(db, self.id, source.map(|src| src.visibility()))
1521    }
1522}
1523
1524#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1525pub struct Union {
1526    pub(crate) id: UnionId,
1527}
1528
1529impl Union {
1530    pub fn name(self, db: &dyn HirDatabase) -> Name {
1531        UnionSignature::of(db, self.id).name.clone()
1532    }
1533
1534    pub fn module(self, db: &dyn HirDatabase) -> Module {
1535        Module { id: self.id.lookup(db).container }
1536    }
1537
1538    pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
1539        Type::from_def(db, self.id)
1540    }
1541
1542    pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type<'_> {
1543        Type::from_value_def(db, self.id)
1544    }
1545
1546    pub fn kind(self, db: &dyn HirDatabase) -> StructKind {
1547        match self.id.fields(db).shape {
1548            hir_def::item_tree::FieldsShape::Record => StructKind::Record,
1549            hir_def::item_tree::FieldsShape::Tuple => StructKind::Tuple,
1550            hir_def::item_tree::FieldsShape::Unit => StructKind::Unit,
1551        }
1552    }
1553
1554    pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
1555        self.id
1556            .fields(db)
1557            .fields()
1558            .iter()
1559            .map(|(id, _)| Field { parent: self.into(), id })
1560            .collect()
1561    }
1562    pub fn is_unstable(self, db: &dyn HirDatabase) -> bool {
1563        AttrFlags::query(db, self.id.into()).contains(AttrFlags::IS_UNSTABLE)
1564    }
1565}
1566
1567impl HasVisibility for Union {
1568    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
1569        let loc = self.id.lookup(db);
1570        let source = loc.source(db);
1571        visibility_from_ast(db, self.id, source.map(|src| src.visibility()))
1572    }
1573}
1574
1575#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1576pub struct Enum {
1577    pub(crate) id: EnumId,
1578}
1579
1580impl Enum {
1581    pub fn module(self, db: &dyn HirDatabase) -> Module {
1582        Module { id: self.id.lookup(db).container }
1583    }
1584
1585    pub fn name(self, db: &dyn HirDatabase) -> Name {
1586        EnumSignature::of(db, self.id).name.clone()
1587    }
1588
1589    pub fn variants(self, db: &dyn HirDatabase) -> Vec<EnumVariant> {
1590        self.id.enum_variants(db).variants.values().map(|&(id, _)| EnumVariant { id }).collect()
1591    }
1592
1593    pub fn num_variants(self, db: &dyn HirDatabase) -> usize {
1594        self.id.enum_variants(db).variants.len()
1595    }
1596
1597    pub fn repr(self, db: &dyn HirDatabase) -> Option<ReprOptions> {
1598        AttrFlags::repr(db, self.id.into())
1599    }
1600
1601    pub fn ty<'db>(self, db: &'db dyn HirDatabase) -> Type<'db> {
1602        Type::from_def(db, self.id)
1603    }
1604
1605    /// The type of the enum variant bodies.
1606    pub fn variant_body_ty<'db>(self, db: &'db dyn HirDatabase) -> Type<'db> {
1607        let interner = DbInterner::new_no_crate(db);
1608        Type::no_params(
1609            Type::builtin_type_crate(db),
1610            match EnumSignature::variant_body_type(db, self.id) {
1611                layout::IntegerType::Pointer(sign) => match sign {
1612                    true => Ty::new_int(interner, rustc_type_ir::IntTy::Isize),
1613                    false => Ty::new_uint(interner, rustc_type_ir::UintTy::Usize),
1614                },
1615                layout::IntegerType::Fixed(i, sign) => match sign {
1616                    true => Ty::new_int(
1617                        interner,
1618                        match i {
1619                            layout::Integer::I8 => rustc_type_ir::IntTy::I8,
1620                            layout::Integer::I16 => rustc_type_ir::IntTy::I16,
1621                            layout::Integer::I32 => rustc_type_ir::IntTy::I32,
1622                            layout::Integer::I64 => rustc_type_ir::IntTy::I64,
1623                            layout::Integer::I128 => rustc_type_ir::IntTy::I128,
1624                        },
1625                    ),
1626                    false => Ty::new_uint(
1627                        interner,
1628                        match i {
1629                            layout::Integer::I8 => rustc_type_ir::UintTy::U8,
1630                            layout::Integer::I16 => rustc_type_ir::UintTy::U16,
1631                            layout::Integer::I32 => rustc_type_ir::UintTy::U32,
1632                            layout::Integer::I64 => rustc_type_ir::UintTy::U64,
1633                            layout::Integer::I128 => rustc_type_ir::UintTy::U128,
1634                        },
1635                    ),
1636                },
1637            },
1638        )
1639    }
1640
1641    /// Returns true if at least one variant of this enum is a non-unit variant.
1642    pub fn is_data_carrying(self, db: &dyn HirDatabase) -> bool {
1643        self.variants(db).iter().any(|v| !matches!(v.kind(db), StructKind::Unit))
1644    }
1645
1646    pub fn layout<'db>(self, db: &'db dyn HirDatabase) -> Result<Layout<'db>, LayoutError> {
1647        Adt::from(self).layout(db)
1648    }
1649
1650    pub fn is_unstable(self, db: &dyn HirDatabase) -> bool {
1651        AttrFlags::query(db, self.id.into()).contains(AttrFlags::IS_UNSTABLE)
1652    }
1653}
1654
1655impl HasVisibility for Enum {
1656    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
1657        let loc = self.id.lookup(db);
1658        let source = loc.source(db);
1659        visibility_from_ast(db, self.id, source.map(|src| src.visibility()))
1660    }
1661}
1662
1663#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1664pub struct EnumVariant {
1665    pub(crate) id: EnumVariantId,
1666}
1667
1668impl EnumVariant {
1669    pub fn module(self, db: &dyn HirDatabase) -> Module {
1670        Module { id: self.id.module(db) }
1671    }
1672
1673    pub fn parent_enum(self, db: &dyn HirDatabase) -> Enum {
1674        self.id.lookup(db).parent.into()
1675    }
1676
1677    pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type<'_> {
1678        Type::from_value_def(db, self.id)
1679    }
1680
1681    pub fn name(self, db: &dyn HirDatabase) -> Name {
1682        self.id.lookup(db).name.clone()
1683    }
1684
1685    pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
1686        self.id
1687            .fields(db)
1688            .fields()
1689            .iter()
1690            .map(|(id, _)| Field { parent: self.into(), id })
1691            .collect()
1692    }
1693
1694    pub fn kind(self, db: &dyn HirDatabase) -> StructKind {
1695        match self.id.fields(db).shape {
1696            hir_def::item_tree::FieldsShape::Record => StructKind::Record,
1697            hir_def::item_tree::FieldsShape::Tuple => StructKind::Tuple,
1698            hir_def::item_tree::FieldsShape::Unit => StructKind::Unit,
1699        }
1700    }
1701
1702    pub fn value(self, db: &dyn HirDatabase) -> Option<ast::Expr> {
1703        self.source(db)?.value.const_arg()?.expr()
1704    }
1705
1706    pub fn eval(self, db: &dyn HirDatabase) -> Result<i128, ConstEvalError<'_>> {
1707        db.const_eval_discriminant(self.into())
1708    }
1709
1710    pub fn layout<'db>(&self, db: &'db dyn HirDatabase) -> Result<Layout<'db>, LayoutError> {
1711        let parent_enum = self.parent_enum(db);
1712        let parent_layout = parent_enum.layout(db)?;
1713        Ok(match &parent_layout.0.variants {
1714            layout::Variants::Multiple { variants, .. } => Layout(
1715                {
1716                    let lookup = self.id.lookup(db);
1717                    let rustc_enum_variant_idx = RustcEnumVariantIdx(lookup.index(db));
1718                    Arc::new(variants[rustc_enum_variant_idx].clone())
1719                },
1720                db.target_data_layout(parent_enum.krate(db).into()).unwrap(),
1721            ),
1722            _ => parent_layout,
1723        })
1724    }
1725
1726    pub fn is_unstable(self, db: &dyn HirDatabase) -> bool {
1727        AttrFlags::query(db, self.id.into()).contains(AttrFlags::IS_UNSTABLE)
1728    }
1729}
1730
1731#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1732pub enum StructKind {
1733    Record,
1734    Tuple,
1735    Unit,
1736}
1737
1738/// Variants inherit visibility from the parent enum.
1739impl HasVisibility for EnumVariant {
1740    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
1741        self.parent_enum(db).visibility(db)
1742    }
1743}
1744
1745/// A Data Type
1746#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1747pub enum Adt {
1748    Struct(Struct),
1749    Union(Union),
1750    Enum(Enum),
1751}
1752impl_from!(Struct, Union, Enum for Adt);
1753
1754impl Adt {
1755    pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
1756        has_non_default_type_params(db, self.into())
1757    }
1758
1759    pub fn layout<'db>(self, db: &'db dyn HirDatabase) -> Result<Layout<'db>, LayoutError> {
1760        let interner = DbInterner::new_no_crate(db);
1761        let adt_id = AdtId::from(self);
1762        let args = GenericArgs::for_item_with_defaults(interner, adt_id.into(), |_, id, _| {
1763            GenericArg::error_from_id(interner, id)
1764        });
1765        db.layout_of_adt(adt_id, args.store(), param_env_from_has_crate(db, adt_id).store())
1766            .map(|layout| Layout(layout, db.target_data_layout(self.krate(db).id).unwrap()))
1767    }
1768
1769    /// Turns this ADT into a type. Any type parameters of the ADT will be
1770    /// turned into unknown types, which is good for e.g. finding the most
1771    /// general set of completions, but will not look very nice when printed.
1772    pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
1773        let id = AdtId::from(self);
1774        Type::from_def(db, id)
1775    }
1776
1777    pub fn module(self, db: &dyn HirDatabase) -> Module {
1778        match self {
1779            Adt::Struct(s) => s.module(db),
1780            Adt::Union(s) => s.module(db),
1781            Adt::Enum(e) => e.module(db),
1782        }
1783    }
1784
1785    pub fn name(self, db: &dyn HirDatabase) -> Name {
1786        match self {
1787            Adt::Struct(s) => s.name(db),
1788            Adt::Union(u) => u.name(db),
1789            Adt::Enum(e) => e.name(db),
1790        }
1791    }
1792
1793    /// Returns the lifetime of the DataType
1794    pub fn lifetime(&self, db: &dyn HirDatabase) -> Option<LifetimeParamData> {
1795        let resolver = match self {
1796            Adt::Struct(s) => s.id.resolver(db),
1797            Adt::Union(u) => u.id.resolver(db),
1798            Adt::Enum(e) => e.id.resolver(db),
1799        };
1800        resolver
1801            .generic_params()
1802            .and_then(|gp| {
1803                gp.iter_early_bound_lt()
1804                    // there should only be a single lifetime
1805                    // but `Arena` requires to use an iterator
1806                    .nth(0)
1807            })
1808            .map(|arena| arena.1.clone())
1809    }
1810
1811    pub fn as_struct(&self) -> Option<Struct> {
1812        if let Self::Struct(v) = self { Some(*v) } else { None }
1813    }
1814
1815    pub fn as_enum(&self) -> Option<Enum> {
1816        if let Self::Enum(v) = self { Some(*v) } else { None }
1817    }
1818}
1819
1820impl HasVisibility for Adt {
1821    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
1822        match self {
1823            Adt::Struct(it) => it.visibility(db),
1824            Adt::Union(it) => it.visibility(db),
1825            Adt::Enum(it) => it.visibility(db),
1826        }
1827    }
1828}
1829
1830#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1831pub enum Variant {
1832    Struct(Struct),
1833    Union(Union),
1834    EnumVariant(EnumVariant),
1835}
1836impl_from!(Struct, Union, EnumVariant for Variant);
1837
1838impl Variant {
1839    pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
1840        match self {
1841            Variant::Struct(it) => it.fields(db),
1842            Variant::Union(it) => it.fields(db),
1843            Variant::EnumVariant(it) => it.fields(db),
1844        }
1845    }
1846
1847    pub fn module(self, db: &dyn HirDatabase) -> Module {
1848        match self {
1849            Variant::Struct(it) => it.module(db),
1850            Variant::Union(it) => it.module(db),
1851            Variant::EnumVariant(it) => it.module(db),
1852        }
1853    }
1854
1855    pub fn name(&self, db: &dyn HirDatabase) -> Name {
1856        match self {
1857            Variant::Struct(s) => (*s).name(db),
1858            Variant::Union(u) => (*u).name(db),
1859            Variant::EnumVariant(e) => (*e).name(db),
1860        }
1861    }
1862
1863    pub fn adt(&self, db: &dyn HirDatabase) -> Adt {
1864        match *self {
1865            Variant::Struct(it) => it.into(),
1866            Variant::Union(it) => it.into(),
1867            Variant::EnumVariant(it) => it.parent_enum(db).into(),
1868        }
1869    }
1870}
1871
1872#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1873pub struct AnonConst<'db> {
1874    id: AnonConstId<'db>,
1875}
1876
1877impl<'db> AnonConst<'db> {
1878    pub fn owner(self, db: &dyn HirDatabase) -> ExpressionStoreOwner {
1879        self.id.loc(db).owner.into()
1880    }
1881
1882    pub fn ty(self, db: &'db dyn HirDatabase) -> Type<'db> {
1883        let loc = self.id.loc(db);
1884        Type { owner: self.id.into(), ty: loc.ty.get() }
1885    }
1886
1887    pub fn eval(
1888        self,
1889        db: &'db dyn HirDatabase,
1890    ) -> Result<EvaluatedConst<'db>, ConstEvalError<'db>> {
1891        let interner = DbInterner::new_no_crate(db);
1892        let ty = self.id.loc(db).ty.get().instantiate_identity().skip_norm_wip();
1893        db.anon_const_eval(self.id, GenericArgs::empty(interner), None).map(|it| EvaluatedConst {
1894            allocation: it,
1895            def: self.id.into(),
1896            ty,
1897        })
1898    }
1899}
1900
1901#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1902pub enum InferBody<'db> {
1903    Body(DefWithBody),
1904    AnonConst(AnonConst<'db>),
1905}
1906
1907#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1908pub enum ExpressionStoreOwner {
1909    Body(DefWithBody),
1910    Signature(GenericDef),
1911    VariantFields(Variant),
1912}
1913
1914impl From<GenericDef> for ExpressionStoreOwner {
1915    fn from(v: GenericDef) -> Self {
1916        Self::Signature(v)
1917    }
1918}
1919
1920impl From<DefWithBody> for ExpressionStoreOwner {
1921    fn from(v: DefWithBody) -> Self {
1922        Self::Body(v)
1923    }
1924}
1925
1926impl_from!(
1927    ExpressionStoreOwnerId {
1928        Signature => Signature,
1929        Body => Body,
1930        VariantFields => VariantFields,
1931    }
1932    for ExpressionStoreOwner
1933);
1934
1935impl ExpressionStoreOwner {
1936    pub fn module(self, db: &dyn HirDatabase) -> Module {
1937        match self {
1938            Self::Body(body) => body.module(db),
1939            Self::Signature(generic_def) => generic_def.module(db),
1940            Self::VariantFields(variant) => variant.module(db),
1941        }
1942    }
1943}
1944
1945/// The defs which have a body.
1946#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1947pub enum DefWithBody {
1948    Function(Function),
1949    Static(Static),
1950    Const(Const),
1951    EnumVariant(EnumVariant),
1952}
1953impl_from!(Function, Const, Static, EnumVariant for DefWithBody);
1954
1955impl DefWithBody {
1956    pub fn module(self, db: &dyn HirDatabase) -> Module {
1957        match self {
1958            DefWithBody::Const(c) => c.module(db),
1959            DefWithBody::Function(f) => f.module(db),
1960            DefWithBody::Static(s) => s.module(db),
1961            DefWithBody::EnumVariant(v) => v.module(db),
1962        }
1963    }
1964
1965    pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
1966        match self {
1967            DefWithBody::Function(f) => Some(f.name(db)),
1968            DefWithBody::Static(s) => Some(s.name(db)),
1969            DefWithBody::Const(c) => c.name(db),
1970            DefWithBody::EnumVariant(v) => Some(v.name(db)),
1971        }
1972    }
1973
1974    /// Returns the type this def's body has to evaluate to.
1975    pub fn body_type(self, db: &dyn HirDatabase) -> Type<'_> {
1976        match self {
1977            DefWithBody::Function(it) => it.ret_type(db),
1978            DefWithBody::Static(it) => it.ty(db),
1979            DefWithBody::Const(it) => it.ty(db),
1980            DefWithBody::EnumVariant(it) => it.parent_enum(db).variant_body_ty(db),
1981        }
1982    }
1983
1984    fn id(&self) -> Option<DefWithBodyId> {
1985        Some(match self {
1986            DefWithBody::Function(it) => match it.id {
1987                AnyFunctionId::FunctionId(id) => id.into(),
1988                AnyFunctionId::BuiltinDeriveImplMethod { .. } => return None,
1989            },
1990            DefWithBody::Static(it) => it.id.into(),
1991            DefWithBody::Const(it) => it.id.into(),
1992            DefWithBody::EnumVariant(it) => it.id.into(),
1993        })
1994    }
1995
1996    #[deprecated = "you should really not use this, this is exported for analysis-stats only"]
1997    pub fn run_mir_body(self, db: &dyn HirDatabase) -> Result<(), MirLowerError<'_>> {
1998        let Some(id) = self.id() else { return Ok(()) };
1999        db.mir_body(id.into()).map(drop)
2000    }
2001
2002    /// A textual representation of the HIR of this def's body for debugging purposes.
2003    pub fn debug_hir(self, db: &dyn HirDatabase) -> String {
2004        let Some(id) = self.id() else {
2005            return String::new();
2006        };
2007        let body = Body::of(db, id);
2008        body.pretty_print(db, id, Edition::CURRENT)
2009    }
2010
2011    /// A textual representation of the MIR of this def's body for debugging purposes.
2012    pub fn debug_mir(self, db: &dyn HirDatabase) -> String {
2013        let Some(id) = self.id() else {
2014            return String::new();
2015        };
2016        let body = db.mir_body(id.into());
2017        match body {
2018            Ok(body) => body.pretty_print(db, self.module(db).krate(db).to_display_target(db)),
2019            Err(e) => format!("error:\n{e:?}"),
2020        }
2021    }
2022
2023    pub fn diagnostics<'db>(
2024        self,
2025        db: &'db dyn HirDatabase,
2026        acc: &mut Vec<AnyDiagnostic<'db>>,
2027        style_lints: bool,
2028    ) {
2029        let Ok(id) = self.try_into() else {
2030            return;
2031        };
2032
2033        let (body, source_map) = Body::with_source_map(db, id);
2034        let sig_source_map = match self {
2035            DefWithBody::Function(id) => match id.id {
2036                AnyFunctionId::FunctionId(id) => &FunctionSignature::with_source_map(db, id).1,
2037                AnyFunctionId::BuiltinDeriveImplMethod { .. } => return,
2038            },
2039            DefWithBody::Static(id) => &StaticSignature::with_source_map(db, id.into()).1,
2040            DefWithBody::Const(id) => &ConstSignature::with_source_map(db, id.into()).1,
2041            DefWithBody::EnumVariant(variant) => {
2042                let enum_id = variant.parent_enum(db).id;
2043                &EnumSignature::with_source_map(db, enum_id).1
2044            }
2045        };
2046
2047        for (_, def_map) in body.blocks(db) {
2048            Module { id: def_map.root_module_id() }.diagnostics(db, acc, style_lints);
2049        }
2050
2051        expr_store_diagnostics(db, acc, source_map);
2052
2053        let infer = InferenceResult::of(db, id);
2054        let type_owner = id.generic_def(db).into();
2055        for d in infer.diagnostics() {
2056            acc.extend(AnyDiagnostic::inference_diagnostic(
2057                db,
2058                id,
2059                d,
2060                source_map,
2061                sig_source_map,
2062                type_owner,
2063            ));
2064        }
2065
2066        let missing_unsafe = hir_ty::diagnostics::missing_unsafe(db, id);
2067        for (node, reason) in missing_unsafe.unsafe_exprs {
2068            match source_map.expr_or_pat_syntax(node) {
2069                Ok(node) => acc.push(
2070                    MissingUnsafe {
2071                        node,
2072                        lint: if missing_unsafe.fn_is_unsafe {
2073                            UnsafeLint::UnsafeOpInUnsafeFn
2074                        } else {
2075                            UnsafeLint::HardError
2076                        },
2077                        reason,
2078                    }
2079                    .into(),
2080                ),
2081                Err(SyntheticSyntax) => {
2082                    // FIXME: Here and elsewhere in this file, the `expr` was
2083                    // desugared, report or assert that this doesn't happen.
2084                }
2085            }
2086        }
2087        for node in missing_unsafe.deprecated_safe_calls {
2088            match source_map.expr_syntax(node) {
2089                Ok(node) => acc.push(
2090                    MissingUnsafe {
2091                        node,
2092                        lint: UnsafeLint::DeprecatedSafe2024,
2093                        reason: UnsafetyReason::UnsafeFnCall,
2094                    }
2095                    .into(),
2096                ),
2097                Err(SyntheticSyntax) => never!("synthetic DeprecatedSafe2024"),
2098            }
2099        }
2100
2101        if let Ok(borrowck_results) = InferBodyId::from(id).borrowck(db) {
2102            for borrowck_result in borrowck_results {
2103                let mir_body = borrowck_result.mir_body(db);
2104                for moof in &borrowck_result.moved_out_of_ref {
2105                    let span: InFile<SyntaxNodePtr> = match moof.span {
2106                        mir::MirSpan::ExprId(e) => match source_map.expr_syntax(e) {
2107                            Ok(s) => s.map(|it| it.into()),
2108                            Err(_) => continue,
2109                        },
2110                        mir::MirSpan::PatId(p) => match source_map.pat_syntax(p) {
2111                            Ok(s) => s.map(|it| it.into()),
2112                            Err(_) => continue,
2113                        },
2114                        mir::MirSpan::SelfParam => match source_map.self_param_syntax() {
2115                            Some(s) => s.map(|it| it.into()),
2116                            None => continue,
2117                        },
2118                        mir::MirSpan::BindingId(b) => {
2119                            match source_map
2120                                .patterns_for_binding(b)
2121                                .iter()
2122                                .find_map(|p| source_map.pat_syntax(*p).ok())
2123                            {
2124                                Some(s) => s.map(|it| it.into()),
2125                                None => continue,
2126                            }
2127                        }
2128                        mir::MirSpan::Unknown => continue,
2129                    };
2130                    acc.push(
2131                        MovedOutOfRef {
2132                            ty: Type { owner: type_owner, ty: EarlyBinder::bind(moof.ty.as_ref()) },
2133                            span,
2134                        }
2135                        .into(),
2136                    )
2137                }
2138                let mol = &borrowck_result.mutability_of_locals;
2139                for (binding_id, binding_data) in body.bindings() {
2140                    if binding_data.problems.is_some() {
2141                        // We should report specific diagnostics for these problems, not `need-mut` and `unused-mut`.
2142                        continue;
2143                    }
2144                    let Some(&local) = mir_body.binding_locals.get(binding_id) else {
2145                        continue;
2146                    };
2147                    if source_map
2148                        .patterns_for_binding(binding_id)
2149                        .iter()
2150                        .any(|&pat| source_map.pat_syntax(pat).is_err())
2151                    {
2152                        // Skip synthetic bindings
2153                        continue;
2154                    }
2155                    let mut need_mut = &mol[local];
2156                    if body[binding_id].name == sym::self_
2157                        && need_mut == &mir::MutabilityReason::Unused
2158                    {
2159                        need_mut = &mir::MutabilityReason::Not;
2160                    }
2161                    let local =
2162                        Local { parent: id.into(), parent_infer: mir_body.owner, binding_id };
2163                    let is_mut = body[binding_id].mode == BindingAnnotation::Mutable;
2164
2165                    match (need_mut, is_mut) {
2166                        (mir::MutabilityReason::Unused, _) => {
2167                            let should_ignore = body[binding_id].name.as_str().starts_with('_');
2168                            if !should_ignore {
2169                                acc.push(UnusedVariable { local }.into())
2170                            }
2171                        }
2172                        (mir::MutabilityReason::Mut { .. }, true)
2173                        | (mir::MutabilityReason::Not, false) => (),
2174                        (mir::MutabilityReason::Mut { spans }, false) => {
2175                            for span in spans {
2176                                let span: InFile<SyntaxNodePtr> = match span {
2177                                    mir::MirSpan::ExprId(e) => match source_map.expr_syntax(*e) {
2178                                        Ok(s) => s.map(|it| it.into()),
2179                                        Err(_) => continue,
2180                                    },
2181                                    mir::MirSpan::PatId(p) => match source_map.pat_syntax(*p) {
2182                                        Ok(s) => s.map(|it| it.into()),
2183                                        Err(_) => continue,
2184                                    },
2185                                    mir::MirSpan::BindingId(b) => {
2186                                        match source_map
2187                                            .patterns_for_binding(*b)
2188                                            .iter()
2189                                            .find_map(|p| source_map.pat_syntax(*p).ok())
2190                                        {
2191                                            Some(s) => s.map(|it| it.into()),
2192                                            None => continue,
2193                                        }
2194                                    }
2195                                    mir::MirSpan::SelfParam => match source_map.self_param_syntax()
2196                                    {
2197                                        Some(s) => s.map(|it| it.into()),
2198                                        None => continue,
2199                                    },
2200                                    mir::MirSpan::Unknown => continue,
2201                                };
2202                                acc.push(NeedMut { local, span }.into());
2203                            }
2204                        }
2205                        (mir::MutabilityReason::Not, true) => {
2206                            let should_ignore = body[binding_id].name.as_str().starts_with('_');
2207                            if !should_ignore {
2208                                acc.push(UnusedMut { local }.into())
2209                            }
2210                        }
2211                    }
2212                }
2213            }
2214        }
2215
2216        for diagnostic in BodyValidationDiagnostic::collect(db, id, style_lints) {
2217            acc.extend(AnyDiagnostic::body_validation_diagnostic(db, diagnostic, source_map));
2218        }
2219
2220        for diag in hir_ty::diagnostics::incorrect_case(db, id.into()) {
2221            acc.push(diag.into())
2222        }
2223    }
2224
2225    /// Returns an iterator over the inferred types of all expressions in this body.
2226    pub fn expression_types<'db>(
2227        self,
2228        db: &'db dyn HirDatabase,
2229    ) -> impl Iterator<Item = Type<'db>> {
2230        self.id().into_iter().flat_map(move |def_id| {
2231            let infer = InferenceResult::of(db, def_id);
2232            let def_id = def_id.generic_def(db);
2233
2234            infer.expression_types().map(move |(_, ty)| Type::new(def_id, ty))
2235        })
2236    }
2237
2238    /// Returns an iterator over the inferred types of all patterns in this body.
2239    pub fn pattern_types<'db>(self, db: &'db dyn HirDatabase) -> impl Iterator<Item = Type<'db>> {
2240        self.id().into_iter().flat_map(move |def_id| {
2241            let infer = InferenceResult::of(db, def_id);
2242            let def_id = def_id.generic_def(db);
2243
2244            infer.pattern_types().map(move |(_, ty)| Type::new(def_id, ty))
2245        })
2246    }
2247
2248    /// Returns an iterator over the inferred types of all bindings in this body.
2249    pub fn binding_types<'db>(self, db: &'db dyn HirDatabase) -> impl Iterator<Item = Type<'db>> {
2250        self.id().into_iter().flat_map(move |def_id| {
2251            let infer = InferenceResult::of(db, def_id);
2252            let def_id = def_id.generic_def(db);
2253
2254            infer.binding_types().map(move |(_, ty)| Type::new(def_id, ty))
2255        })
2256    }
2257}
2258
2259fn expr_store_diagnostics<'db>(
2260    db: &'db dyn HirDatabase,
2261    acc: &mut Vec<AnyDiagnostic<'db>>,
2262    source_map: &ExpressionStoreSourceMap,
2263) {
2264    for diag in source_map.diagnostics() {
2265        acc.push(match diag {
2266            ExpressionStoreDiagnostics::InactiveCode { node, cfg, opts } => {
2267                InactiveCode { node: *node, cfg: cfg.clone(), opts: opts.clone() }.into()
2268            }
2269            ExpressionStoreDiagnostics::UnresolvedMacroCall { node, path } => UnresolvedMacroCall {
2270                range: node.map(|ptr| ptr.text_range()),
2271                path: path.clone(),
2272                is_bang: true,
2273            }
2274            .into(),
2275            ExpressionStoreDiagnostics::AwaitOutsideOfAsync { node, location } => {
2276                AwaitOutsideOfAsync { node: *node, location: location.clone() }.into()
2277            }
2278            ExpressionStoreDiagnostics::UnreachableLabel { node, name } => {
2279                UnreachableLabel { node: *node, name: name.clone() }.into()
2280            }
2281            ExpressionStoreDiagnostics::UndeclaredLabel { node, name } => {
2282                UndeclaredLabel { node: *node, name: name.clone() }.into()
2283            }
2284            ExpressionStoreDiagnostics::PatternArgInExternFn { node } => {
2285                PatternArgInExternFn { node: *node }.into()
2286            }
2287            ExpressionStoreDiagnostics::FruInDestructuringAssignment { node } => {
2288                FruInDestructuringAssignment { node: *node }.into()
2289            }
2290        });
2291    }
2292
2293    source_map
2294        .macro_calls()
2295        .for_each(|(_ast_id, call_id)| macro_call_diagnostics(db, call_id, acc));
2296}
2297
2298#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2299enum AnyFunctionId {
2300    FunctionId(FunctionId),
2301    BuiltinDeriveImplMethod { method: BuiltinDeriveImplMethod, impl_: BuiltinDeriveImplId },
2302}
2303
2304#[derive(Clone, Copy, PartialEq, Eq, Hash)]
2305pub struct Function {
2306    pub(crate) id: AnyFunctionId,
2307}
2308
2309impl fmt::Debug for Function {
2310    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2311        fmt::Debug::fmt(&self.id, f)
2312    }
2313}
2314
2315impl Function {
2316    pub fn lang(db: &dyn HirDatabase, krate: Crate, lang_item: LangItem) -> Option<Function> {
2317        let lang_items = hir_def::lang_item::lang_items(db, krate.id);
2318        match lang_item.from_lang_items(lang_items)? {
2319            LangItemTarget::FunctionId(it) => Some(it.into()),
2320            _ => None,
2321        }
2322    }
2323
2324    pub fn module(self, db: &dyn HirDatabase) -> Module {
2325        match self.id {
2326            AnyFunctionId::FunctionId(id) => id.module(db).into(),
2327            AnyFunctionId::BuiltinDeriveImplMethod { impl_, .. } => impl_.module(db).into(),
2328        }
2329    }
2330
2331    pub fn name(self, db: &dyn HirDatabase) -> Name {
2332        match self.id {
2333            AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).name.clone(),
2334            AnyFunctionId::BuiltinDeriveImplMethod { method, .. } => {
2335                Name::new_symbol_root(method.name())
2336            }
2337        }
2338    }
2339
2340    pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
2341        match self.id {
2342            AnyFunctionId::FunctionId(id) => Type::from_value_def(db, id),
2343            AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ } => {
2344                // Get the type for the trait function, as we can't get the type for the impl function
2345                // because it has not `CallableDefId`.
2346                // FIXME: This does not account for replacing `Self`. Do we really need that?
2347                let Some(trait_method) = method.trait_method(db, impl_) else {
2348                    return Type::unknown();
2349                };
2350                Function::from(trait_method).ty(db)
2351            }
2352        }
2353    }
2354
2355    pub fn fn_ptr_type(self, db: &dyn HirDatabase) -> Type<'_> {
2356        match self.id {
2357            AnyFunctionId::FunctionId(id) => {
2358                let interner = DbInterner::new_no_crate(db);
2359                let callable_sig =
2360                    db.callable_item_signature(id.into()).instantiate_identity().skip_norm_wip();
2361                let ty = Ty::new_fn_ptr(interner, callable_sig);
2362                Type::new(id.into(), ty)
2363            }
2364            AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ } => {
2365                // Get the type for the trait function, as we can't get the type for the impl function
2366                // because it has not `CallableDefId`.
2367                // FIXME: This does not account for replacing `Self`. Do we really need that?
2368                let Some(trait_method) = method.trait_method(db, impl_) else {
2369                    return Type::unknown();
2370                };
2371                Function::from(trait_method).fn_ptr_type(db)
2372            }
2373        }
2374    }
2375
2376    fn fn_sig<'db>(self, db: &'db dyn HirDatabase) -> (TypeOwnerId<'db>, PolyFnSig<'db>) {
2377        let fn_ptr = self.fn_ptr_type(db);
2378        let TyKind::FnPtr(sig_tys, hdr) = fn_ptr.ty.skip_binder().kind() else {
2379            unreachable!();
2380        };
2381        (fn_ptr.owner, sig_tys.with(hdr))
2382    }
2383
2384    fn erased_fn_sig<'db>(self, db: &'db dyn HirDatabase) -> (TypeOwnerId<'db>, FnSig<'db>) {
2385        let (owner, sig) = self.fn_sig(db);
2386        let sig = DbInterner::new_no_crate(db).instantiate_bound_regions_with_erased(sig);
2387        (owner, sig)
2388    }
2389
2390    /// Get this function's return type
2391    pub fn ret_type(self, db: &dyn HirDatabase) -> Type<'_> {
2392        let (owner, sig) = self.erased_fn_sig(db);
2393        Type { owner, ty: EarlyBinder::bind(sig.output()) }
2394    }
2395
2396    pub fn async_ret_type<'db>(self, db: &'db dyn HirDatabase) -> Option<Type<'db>> {
2397        let AnyFunctionId::FunctionId(id) = self.id else {
2398            return None;
2399        };
2400        if !self.is_async(db) {
2401            return None;
2402        }
2403        let interner = DbInterner::new_no_crate(db);
2404        let sig = db.callable_item_signature(id.into()).instantiate_identity().skip_norm_wip();
2405        let ret_ty = interner.instantiate_bound_regions_with_erased(sig).output();
2406        for pred in ret_ty.impl_trait_bounds(db).into_iter().flatten() {
2407            let clause = interner.instantiate_bound_regions_with_erased(pred.kind());
2408            if let ClauseKind::Projection(projection) = clause
2409                && let Some(output_ty) = projection.term.as_type()
2410            {
2411                return Some(Type::new(id.into(), output_ty));
2412            }
2413        }
2414        None
2415    }
2416
2417    pub fn has_self_param(self, db: &dyn HirDatabase) -> bool {
2418        match self.id {
2419            AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).has_self_param(),
2420            AnyFunctionId::BuiltinDeriveImplMethod { method, .. } => match method {
2421                BuiltinDeriveImplMethod::clone
2422                | BuiltinDeriveImplMethod::fmt
2423                | BuiltinDeriveImplMethod::hash
2424                | BuiltinDeriveImplMethod::cmp
2425                | BuiltinDeriveImplMethod::partial_cmp
2426                | BuiltinDeriveImplMethod::eq => true,
2427                BuiltinDeriveImplMethod::default => false,
2428            },
2429        }
2430    }
2431
2432    pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> {
2433        self.has_self_param(db).then_some(SelfParam { func: self })
2434    }
2435
2436    pub fn assoc_fn_params(self, db: &dyn HirDatabase) -> Vec<Param<'_>> {
2437        let (owner, sig) = self.erased_fn_sig(db);
2438        let func = match self.id {
2439            AnyFunctionId::FunctionId(id) => Callee::Def(CallableDefId::FunctionId(id)),
2440            AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ } => {
2441                Callee::BuiltinDeriveImplMethod { method, impl_ }
2442            }
2443        };
2444        sig.inputs()
2445            .iter()
2446            .enumerate()
2447            .map(|(idx, &ty)| Param {
2448                func: func.clone(),
2449                ty: Type { owner, ty: EarlyBinder::bind(ty) },
2450                idx,
2451            })
2452            .collect()
2453    }
2454
2455    pub fn num_params(self, db: &dyn HirDatabase) -> usize {
2456        match self.id {
2457            AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).params.len(),
2458            AnyFunctionId::BuiltinDeriveImplMethod { .. } => {
2459                self.fn_sig(db).1.skip_binder().inputs().len()
2460            }
2461        }
2462    }
2463
2464    pub fn method_params(self, db: &dyn HirDatabase) -> Option<Vec<Param<'_>>> {
2465        self.self_param(db)?;
2466        Some(self.params_without_self(db))
2467    }
2468
2469    pub fn params_without_self(self, db: &dyn HirDatabase) -> Vec<Param<'_>> {
2470        let mut params = self.assoc_fn_params(db);
2471        if self.has_self_param(db) {
2472            params.remove(0);
2473        }
2474        params
2475    }
2476
2477    pub fn is_const(self, db: &dyn HirDatabase) -> bool {
2478        match self.id {
2479            AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).is_const(),
2480            AnyFunctionId::BuiltinDeriveImplMethod { .. } => false,
2481        }
2482    }
2483
2484    pub fn is_async(self, db: &dyn HirDatabase) -> bool {
2485        match self.id {
2486            AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).is_async(),
2487            AnyFunctionId::BuiltinDeriveImplMethod { .. } => false,
2488        }
2489    }
2490
2491    pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool {
2492        match self.id {
2493            AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).is_unsafe(),
2494            AnyFunctionId::BuiltinDeriveImplMethod { .. } => false,
2495        }
2496    }
2497
2498    pub fn is_varargs(self, db: &dyn HirDatabase) -> bool {
2499        match self.id {
2500            AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).is_varargs(),
2501            AnyFunctionId::BuiltinDeriveImplMethod { .. } => false,
2502        }
2503    }
2504
2505    pub fn extern_block(self, db: &dyn HirDatabase) -> Option<ExternBlock> {
2506        match self.id {
2507            AnyFunctionId::FunctionId(id) => match id.lookup(db).container {
2508                ItemContainerId::ExternBlockId(id) => Some(ExternBlock { id }),
2509                _ => None,
2510            },
2511            AnyFunctionId::BuiltinDeriveImplMethod { .. } => None,
2512        }
2513    }
2514
2515    pub fn returns_impl_future(self, db: &dyn HirDatabase) -> bool {
2516        if self.is_async(db) {
2517            return true;
2518        }
2519
2520        let ret_type = self.ret_type(db);
2521        let Some(impl_traits) = ret_type.as_impl_traits(db) else { return false };
2522        let lang_items = hir_def::lang_item::lang_items(db, self.krate(db).id);
2523        let Some(future_trait_id) = lang_items.Future else {
2524            return false;
2525        };
2526        let Some(sized_trait_id) = lang_items.Sized else {
2527            return false;
2528        };
2529
2530        let mut has_impl_future = false;
2531        impl_traits
2532            .filter(|t| {
2533                let fut = t.id == future_trait_id;
2534                has_impl_future |= fut;
2535                !fut && t.id != sized_trait_id
2536            })
2537            // all traits but the future trait must be auto traits
2538            .all(|t| t.is_auto(db))
2539            && has_impl_future
2540    }
2541
2542    /// Does this function have `#[test]` attribute?
2543    pub fn is_test(self, db: &dyn HirDatabase) -> bool {
2544        self.attrs(db).contains(AttrFlags::IS_TEST)
2545    }
2546
2547    /// is this a `fn main` or a function with an `export_name` of `main`?
2548    pub fn is_main(self, db: &dyn HirDatabase) -> bool {
2549        match self.id {
2550            AnyFunctionId::FunctionId(id) => {
2551                self.exported_main(db)
2552                    || self.module(db).is_crate_root(db)
2553                        && FunctionSignature::of(db, id).name == sym::main
2554            }
2555            AnyFunctionId::BuiltinDeriveImplMethod { .. } => false,
2556        }
2557    }
2558
2559    fn attrs(self, db: &dyn HirDatabase) -> AttrFlags {
2560        match self.id {
2561            AnyFunctionId::FunctionId(id) => AttrFlags::query(db, id.into()),
2562            AnyFunctionId::BuiltinDeriveImplMethod { .. } => AttrFlags::empty(),
2563        }
2564    }
2565
2566    /// Is this a function with an `export_name` of `main`?
2567    pub fn exported_main(self, db: &dyn HirDatabase) -> bool {
2568        self.attrs(db).contains(AttrFlags::IS_EXPORT_NAME_MAIN)
2569    }
2570
2571    /// Does this function have the ignore attribute?
2572    pub fn is_ignore(self, db: &dyn HirDatabase) -> bool {
2573        self.attrs(db).contains(AttrFlags::IS_IGNORE)
2574    }
2575
2576    /// Does this function have `#[bench]` attribute?
2577    pub fn is_bench(self, db: &dyn HirDatabase) -> bool {
2578        self.attrs(db).contains(AttrFlags::IS_BENCH)
2579    }
2580
2581    /// Is this function marked as unstable with `#[feature]` attribute?
2582    pub fn is_unstable(self, db: &dyn HirDatabase) -> bool {
2583        self.attrs(db).contains(AttrFlags::IS_UNSTABLE)
2584    }
2585
2586    pub fn is_unsafe_to_call(
2587        self,
2588        db: &dyn HirDatabase,
2589        caller: Option<Function>,
2590        call_edition: Edition,
2591    ) -> bool {
2592        let AnyFunctionId::FunctionId(id) = self.id else {
2593            return false;
2594        };
2595        let (target_features, target_feature_is_safe_in_target) = caller
2596            .map(|caller| {
2597                let target_features = match caller.id {
2598                    AnyFunctionId::FunctionId(id) => hir_ty::TargetFeatures::from_fn(db, id),
2599                    AnyFunctionId::BuiltinDeriveImplMethod { .. } => {
2600                        hir_ty::TargetFeatures::default()
2601                    }
2602                };
2603                let target_feature_is_safe_in_target =
2604                    match &caller.krate(db).id.workspace_data(db).target {
2605                        Ok(target) => hir_ty::target_feature_is_safe_in_target(target),
2606                        Err(_) => hir_ty::TargetFeatureIsSafeInTarget::No,
2607                    };
2608                (target_features, target_feature_is_safe_in_target)
2609            })
2610            .unwrap_or_else(|| {
2611                (hir_ty::TargetFeatures::default(), hir_ty::TargetFeatureIsSafeInTarget::No)
2612            });
2613        matches!(
2614            hir_ty::is_fn_unsafe_to_call(
2615                db,
2616                id,
2617                &target_features,
2618                call_edition,
2619                target_feature_is_safe_in_target
2620            ),
2621            hir_ty::Unsafety::Unsafe
2622        )
2623    }
2624
2625    /// Whether this function declaration has a definition.
2626    ///
2627    /// This is false in the case of required (not provided) trait methods.
2628    pub fn has_body(self, db: &dyn HirDatabase) -> bool {
2629        match self.id {
2630            AnyFunctionId::FunctionId(id) => FunctionSignature::of(db, id).has_body(),
2631            AnyFunctionId::BuiltinDeriveImplMethod { .. } => true,
2632        }
2633    }
2634
2635    pub fn as_proc_macro(self, db: &dyn HirDatabase) -> Option<Macro> {
2636        let AnyFunctionId::FunctionId(id) = self.id else {
2637            return None;
2638        };
2639        let def_map = crate_def_map(db, HasModule::krate(&id, db));
2640        def_map.fn_as_proc_macro(id).map(|id| Macro { id: id.into() })
2641    }
2642
2643    pub fn eval(
2644        self,
2645        db: &dyn HirDatabase,
2646        span_formatter: impl Fn(FileId, TextRange) -> String,
2647    ) -> Result<String, ConstEvalError<'_>> {
2648        let AnyFunctionId::FunctionId(id) = self.id else {
2649            return Err(ConstEvalError::MirEvalError(MirEvalError::NotSupported(
2650                "evaluation of builtin derive impl methods is not supported".to_owned(),
2651            )));
2652        };
2653        let interner = DbInterner::new_no_crate(db);
2654        let body = db.monomorphized_mir_body(
2655            id.into(),
2656            GenericArgs::empty(interner).store(),
2657            ParamEnvAndCrate {
2658                param_env: db.trait_environment(id.into()),
2659                krate: id.module(db).krate(db),
2660            }
2661            .store(),
2662        )?;
2663        let (result, output) = interpret_mir(db, body, false, None)?;
2664        let mut text = match result {
2665            Ok(_) => "pass".to_owned(),
2666            Err(e) => {
2667                let mut r = String::new();
2668                _ = e.pretty_print(
2669                    &mut r,
2670                    db,
2671                    &span_formatter,
2672                    self.krate(db).to_display_target(db),
2673                );
2674                r
2675            }
2676        };
2677        let stdout = output.stdout().into_owned();
2678        if !stdout.is_empty() {
2679            text += "\n--------- stdout ---------\n";
2680            text += &stdout;
2681        }
2682        let stderr = output.stdout().into_owned();
2683        if !stderr.is_empty() {
2684            text += "\n--------- stderr ---------\n";
2685            text += &stderr;
2686        }
2687        Ok(text)
2688    }
2689}
2690
2691// Note: logically, this belongs to `hir_ty`, but we are not using it there yet.
2692#[derive(Clone, Copy, PartialEq, Eq)]
2693pub enum Access {
2694    Shared,
2695    Exclusive,
2696    Owned,
2697}
2698
2699impl From<hir_ty::next_solver::Mutability> for Access {
2700    fn from(mutability: hir_ty::next_solver::Mutability) -> Access {
2701        match mutability {
2702            hir_ty::next_solver::Mutability::Not => Access::Shared,
2703            hir_ty::next_solver::Mutability::Mut => Access::Exclusive,
2704        }
2705    }
2706}
2707
2708#[derive(Clone, PartialEq, Eq, Hash, Debug)]
2709pub struct Param<'db> {
2710    func: Callee<'db>,
2711    /// The index in parameter list, including self parameter.
2712    idx: usize,
2713    ty: Type<'db>,
2714}
2715
2716impl<'db> Param<'db> {
2717    pub fn parent_fn(&self) -> Option<Function> {
2718        match self.func {
2719            Callee::Def(CallableDefId::FunctionId(f)) => Some(f.into()),
2720            _ => None,
2721        }
2722    }
2723
2724    // pub fn parent_closure(&self) -> Option<Closure> {
2725    //     self.func.as_ref().right().cloned()
2726    // }
2727
2728    pub fn index(&self) -> usize {
2729        self.idx
2730    }
2731
2732    pub fn ty(&self) -> &Type<'db> {
2733        &self.ty
2734    }
2735
2736    pub fn name(&self, db: &dyn HirDatabase) -> Option<Name> {
2737        Some(self.as_local(db)?.name(db))
2738    }
2739
2740    pub fn as_local(&self, db: &'db dyn HirDatabase) -> Option<Local<'db>> {
2741        match self.func {
2742            Callee::Def(CallableDefId::FunctionId(it)) => {
2743                let parent = DefWithBodyId::FunctionId(it);
2744                let body = Body::of(db, parent);
2745                if let Some(self_param) = body.self_param.filter(|_| self.idx == 0) {
2746                    Some(Local {
2747                        parent: parent.into(),
2748                        parent_infer: parent.into(),
2749                        binding_id: self_param.user_written,
2750                    })
2751                } else if let Pat::Bind { id, .. } =
2752                    &body[body.params[self.idx - body.self_param.is_some() as usize].user_written]
2753                {
2754                    Some(Local {
2755                        parent: parent.into(),
2756                        parent_infer: parent.into(),
2757                        binding_id: *id,
2758                    })
2759                } else {
2760                    None
2761                }
2762            }
2763            Callee::Closure(closure, _) => {
2764                let c = closure.loc(db);
2765                let body_infer_owner = c.owner;
2766                let body_owner = c.owner.expression_store_owner(db);
2767                let store = ExpressionStore::of(db, body_owner);
2768
2769                if let Expr::Closure { args, .. } = &store[c.expr]
2770                    && let Pat::Bind { id, .. } = &store[args[self.idx]]
2771                {
2772                    return Some(Local {
2773                        parent: body_owner,
2774                        parent_infer: body_infer_owner,
2775                        binding_id: *id,
2776                    });
2777                }
2778                None
2779            }
2780            _ => None,
2781        }
2782    }
2783
2784    pub fn pattern_source(self, db: &dyn HirDatabase) -> Option<ast::Pat> {
2785        self.source(db).and_then(|p| p.value.right()?.pat())
2786    }
2787}
2788
2789#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2790pub struct SelfParam {
2791    func: Function,
2792}
2793
2794impl SelfParam {
2795    pub fn access(self, db: &dyn HirDatabase) -> Access {
2796        match self.func.id {
2797            AnyFunctionId::FunctionId(id) => {
2798                let func_data = FunctionSignature::of(db, id);
2799                func_data
2800                    .params
2801                    .first()
2802                    .map(|&param| match &func_data.store[param] {
2803                        TypeRef::Reference(ref_) => match ref_.mutability {
2804                            hir_def::type_ref::Mutability::Shared => Access::Shared,
2805                            hir_def::type_ref::Mutability::Mut => Access::Exclusive,
2806                        },
2807                        _ => Access::Owned,
2808                    })
2809                    .unwrap_or(Access::Owned)
2810            }
2811            AnyFunctionId::BuiltinDeriveImplMethod { method, .. } => match method {
2812                BuiltinDeriveImplMethod::clone
2813                | BuiltinDeriveImplMethod::fmt
2814                | BuiltinDeriveImplMethod::hash
2815                | BuiltinDeriveImplMethod::cmp
2816                | BuiltinDeriveImplMethod::partial_cmp
2817                | BuiltinDeriveImplMethod::eq => Access::Shared,
2818                BuiltinDeriveImplMethod::default => {
2819                    unreachable!("this function does not have a self param")
2820                }
2821            },
2822        }
2823    }
2824
2825    pub fn parent_fn(&self) -> Function {
2826        self.func
2827    }
2828
2829    pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> Type<'db> {
2830        let (owner, sig) = self.func.erased_fn_sig(db);
2831        Type { owner, ty: EarlyBinder::bind(sig.inputs()[0]) }
2832    }
2833}
2834
2835impl HasVisibility for Function {
2836    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
2837        match self.id {
2838            AnyFunctionId::FunctionId(id) => AssocItemId::from(id).assoc_visibility(db),
2839            AnyFunctionId::BuiltinDeriveImplMethod { .. } => Visibility::Public,
2840        }
2841    }
2842}
2843
2844#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2845pub struct ExternCrateDecl {
2846    pub(crate) id: ExternCrateId,
2847}
2848
2849impl ExternCrateDecl {
2850    pub fn module(self, db: &dyn HirDatabase) -> Module {
2851        self.id.module(db).into()
2852    }
2853
2854    pub fn resolved_crate(self, db: &dyn HirDatabase) -> Option<Crate> {
2855        let loc = self.id.lookup(db);
2856        let krate = loc.container.krate(db);
2857        let name = self.name(db);
2858        if name == sym::self_ {
2859            Some(krate.into())
2860        } else {
2861            krate.data(db).dependencies.iter().find_map(|dep| {
2862                if dep.name.symbol() == name.symbol() { Some(dep.crate_id.into()) } else { None }
2863            })
2864        }
2865    }
2866
2867    pub fn name(self, db: &dyn HirDatabase) -> Name {
2868        let loc = self.id.lookup(db);
2869        let source = loc.source(db);
2870        as_name_opt(source.value.name_ref())
2871    }
2872
2873    pub fn alias(self, db: &dyn HirDatabase) -> Option<ImportAlias> {
2874        let loc = self.id.lookup(db);
2875        let source = loc.source(db);
2876        let rename = source.value.rename()?;
2877        if let Some(name) = rename.name() {
2878            Some(ImportAlias::Alias(name.as_name()))
2879        } else if rename.underscore_token().is_some() {
2880            Some(ImportAlias::Underscore)
2881        } else {
2882            None
2883        }
2884    }
2885
2886    /// Returns the name under which this crate is made accessible, taking `_` into account.
2887    pub fn alias_or_name(self, db: &dyn HirDatabase) -> Option<Name> {
2888        match self.alias(db) {
2889            Some(ImportAlias::Underscore) => None,
2890            Some(ImportAlias::Alias(alias)) => Some(alias),
2891            None => Some(self.name(db)),
2892        }
2893    }
2894}
2895
2896impl HasVisibility for ExternCrateDecl {
2897    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
2898        let loc = self.id.lookup(db);
2899        let source = loc.source(db);
2900        visibility_from_ast(db, self.id, source.map(|src| src.visibility()))
2901    }
2902}
2903
2904#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2905pub struct Const {
2906    pub(crate) id: ConstId,
2907}
2908
2909impl Const {
2910    pub fn module(self, db: &dyn HirDatabase) -> Module {
2911        Module { id: self.id.module(db) }
2912    }
2913
2914    pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
2915        ConstSignature::of(db, self.id).name.clone()
2916    }
2917
2918    pub fn value(self, db: &dyn HirDatabase) -> Option<ast::Expr> {
2919        self.source(db)?.value.body()
2920    }
2921
2922    pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
2923        Type::from_value_def(db, self.id)
2924    }
2925
2926    /// Evaluate the constant.
2927    pub fn eval(self, db: &dyn HirDatabase) -> Result<EvaluatedConst<'_>, ConstEvalError<'_>> {
2928        let interner = DbInterner::new_no_crate(db);
2929        let ty = db.value_ty(self.id.into()).unwrap().instantiate_identity().skip_norm_wip();
2930        db.const_eval(self.id, GenericArgs::empty(interner), None).map(|it| EvaluatedConst {
2931            allocation: it,
2932            def: self.id.into(),
2933            ty,
2934        })
2935    }
2936}
2937
2938impl HasVisibility for Const {
2939    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
2940        AssocItemId::from(self.id).assoc_visibility(db)
2941    }
2942}
2943
2944pub struct EvaluatedConst<'db> {
2945    def: InferBodyId<'db>,
2946    allocation: hir_ty::next_solver::Allocation<'db>,
2947    ty: Ty<'db>,
2948}
2949
2950impl<'db> EvaluatedConst<'db> {
2951    pub fn render(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String {
2952        format!("{}", self.allocation.display(db, display_target))
2953    }
2954
2955    pub fn render_debug(&self, db: &'db dyn HirDatabase) -> Result<String, MirEvalError<'db>> {
2956        let ty = self.allocation.ty.kind();
2957        if let TyKind::Int(_) | TyKind::Uint(_) = ty {
2958            let b = &self.allocation.memory;
2959            let value = u128::from_le_bytes(mir::pad16(b, false));
2960            let value_signed = i128::from_le_bytes(mir::pad16(b, matches!(ty, TyKind::Int(_))));
2961            let mut result =
2962                if let TyKind::Int(_) = ty { value_signed.to_string() } else { value.to_string() };
2963            if value >= 10 {
2964                format_to!(result, " ({value:#X})");
2965                return Ok(result);
2966            } else {
2967                return Ok(result);
2968            }
2969        }
2970        mir::render_const_using_debug_impl(db, self.def, self.allocation, self.ty)
2971    }
2972}
2973
2974#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2975pub struct Static {
2976    pub(crate) id: StaticId,
2977}
2978
2979impl Static {
2980    pub fn module(self, db: &dyn HirDatabase) -> Module {
2981        Module { id: self.id.module(db) }
2982    }
2983
2984    pub fn name(self, db: &dyn HirDatabase) -> Name {
2985        StaticSignature::of(db, self.id).name.clone()
2986    }
2987
2988    pub fn is_mut(self, db: &dyn HirDatabase) -> bool {
2989        StaticSignature::of(db, self.id).flags.contains(StaticFlags::MUTABLE)
2990    }
2991
2992    pub fn value(self, db: &dyn HirDatabase) -> Option<ast::Expr> {
2993        self.source(db)?.value.body()
2994    }
2995
2996    pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
2997        Type::from_value_def(db, self.id)
2998    }
2999
3000    pub fn extern_block(self, db: &dyn HirDatabase) -> Option<ExternBlock> {
3001        match self.id.lookup(db).container {
3002            ItemContainerId::ExternBlockId(id) => Some(ExternBlock { id }),
3003            _ => None,
3004        }
3005    }
3006
3007    /// Evaluate the static initializer.
3008    pub fn eval(self, db: &dyn HirDatabase) -> Result<EvaluatedConst<'_>, ConstEvalError<'_>> {
3009        let ty = db.value_ty(self.id.into()).unwrap().instantiate_identity().skip_norm_wip();
3010        db.const_eval_static(self.id).map(|it| EvaluatedConst {
3011            allocation: it,
3012            def: self.id.into(),
3013            ty,
3014        })
3015    }
3016}
3017
3018impl HasVisibility for Static {
3019    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
3020        let loc = self.id.lookup(db);
3021        let source = loc.source(db);
3022        visibility_from_ast(db, self.id, source.map(|src| src.visibility()))
3023    }
3024}
3025
3026#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3027pub struct Trait {
3028    pub(crate) id: TraitId,
3029}
3030
3031impl Trait {
3032    pub fn lang(db: &dyn HirDatabase, krate: Crate, lang_item: LangItem) -> Option<Trait> {
3033        let lang_items = hir_def::lang_item::lang_items(db, krate.id);
3034        match lang_item.from_lang_items(lang_items)? {
3035            LangItemTarget::TraitId(it) => Some(it.into()),
3036            _ => None,
3037        }
3038    }
3039
3040    pub fn module(self, db: &dyn HirDatabase) -> Module {
3041        Module { id: self.id.lookup(db).container }
3042    }
3043
3044    pub fn name(self, db: &dyn HirDatabase) -> Name {
3045        TraitSignature::of(db, self.id).name.clone()
3046    }
3047
3048    pub fn direct_supertraits(self, db: &dyn HirDatabase) -> Vec<Trait> {
3049        let traits = direct_super_traits(db, self.into());
3050        traits.iter().map(|tr| Trait::from(*tr)).collect()
3051    }
3052
3053    pub fn all_supertraits(self, db: &dyn HirDatabase) -> Vec<Trait> {
3054        let traits = all_super_traits(db, self.into());
3055        traits.iter().map(|tr| Trait::from(*tr)).collect()
3056    }
3057
3058    pub fn function(self, db: &dyn HirDatabase, name: impl PartialEq<Name>) -> Option<Function> {
3059        self.id.trait_items(db).items.iter().find(|(n, _)| name == *n).and_then(|&(_, it)| match it
3060        {
3061            AssocItemId::FunctionId(id) => Some(id.into()),
3062            _ => None,
3063        })
3064    }
3065
3066    pub fn items(self, db: &dyn HirDatabase) -> Vec<AssocItem> {
3067        self.id.trait_items(db).items.iter().map(|(_name, it)| (*it).into()).collect()
3068    }
3069
3070    pub fn items_with_supertraits(self, db: &dyn HirDatabase) -> Vec<AssocItem> {
3071        self.all_supertraits(db).into_iter().flat_map(|tr| tr.items(db)).collect()
3072    }
3073
3074    pub fn is_auto(self, db: &dyn HirDatabase) -> bool {
3075        TraitSignature::of(db, self.id).flags.contains(TraitFlags::AUTO)
3076    }
3077
3078    pub fn is_unsafe(&self, db: &dyn HirDatabase) -> bool {
3079        TraitSignature::of(db, self.id).flags.contains(TraitFlags::UNSAFE)
3080    }
3081
3082    pub fn type_or_const_param_count(
3083        &self,
3084        db: &dyn HirDatabase,
3085        count_required_only: bool,
3086    ) -> usize {
3087        GenericParams::of(db,self.id.into())
3088            .iter_type_or_consts()
3089            .filter(|(_, ty)| !matches!(ty, TypeOrConstParamData::TypeParamData(ty) if ty.provenance != TypeParamProvenance::TypeParamList))
3090            .filter(|(_, ty)| !count_required_only || !ty.has_default())
3091            .count()
3092    }
3093
3094    pub fn dyn_compatibility(&self, db: &dyn HirDatabase) -> Option<DynCompatibilityViolation> {
3095        hir_ty::dyn_compatibility::dyn_compatibility(db, self.id)
3096    }
3097
3098    pub fn dyn_compatibility_all_violations(
3099        &self,
3100        db: &dyn HirDatabase,
3101    ) -> Option<Vec<DynCompatibilityViolation>> {
3102        let mut violations = vec![];
3103        _ = hir_ty::dyn_compatibility::dyn_compatibility_with_callback(
3104            db,
3105            self.id,
3106            &mut |violation| {
3107                violations.push(violation);
3108                ControlFlow::Continue(())
3109            },
3110        );
3111        violations.is_empty().not().then_some(violations)
3112    }
3113
3114    fn all_macro_calls(&self, db: &dyn HirDatabase) -> Box<[(AstId<ast::Item>, MacroCallId)]> {
3115        self.id.trait_items(db).macro_calls.to_vec().into_boxed_slice()
3116    }
3117
3118    /// `#[rust_analyzer::completions(...)]` mode.
3119    pub fn complete(self, db: &dyn HirDatabase) -> Complete {
3120        Complete::extract(true, self.attrs(db).attrs)
3121    }
3122
3123    // Feature: Prefer Underscore Import Attribute
3124    // Crate authors can declare that their trait prefers to be imported `as _`. This can be used
3125    // for example for extension traits. To do that, a trait has to include the attribute
3126    // `#[rust_analyzer::prefer_underscore_import]`
3127    //
3128    // When a trait includes this attribute, flyimport will import it `as _`, and the quickfix
3129    // to import it will prefer to import it `as _` (but allow to import it normally as well).
3130    //
3131    // Malformed attributes will be ignored without warnings.
3132    pub fn prefer_underscore_import(self, db: &dyn HirDatabase) -> bool {
3133        AttrFlags::query(db, self.id.into()).contains(AttrFlags::PREFER_UNDERSCORE_IMPORT)
3134    }
3135}
3136
3137impl HasVisibility for Trait {
3138    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
3139        let loc = self.id.lookup(db);
3140        let source = loc.source(db);
3141        visibility_from_ast(db, self.id, source.map(|src| src.visibility()))
3142    }
3143}
3144
3145#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3146pub struct TypeAlias {
3147    pub(crate) id: TypeAliasId,
3148}
3149
3150impl TypeAlias {
3151    pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
3152        has_non_default_type_params(db, self.id.into())
3153    }
3154
3155    pub fn module(self, db: &dyn HirDatabase) -> Module {
3156        Module { id: self.id.module(db) }
3157    }
3158
3159    pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
3160        Type::from_def(db, self.id)
3161    }
3162
3163    pub fn name(self, db: &dyn HirDatabase) -> Name {
3164        TypeAliasSignature::of(db, self.id).name.clone()
3165    }
3166}
3167
3168impl HasVisibility for TypeAlias {
3169    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
3170        AssocItemId::from(self.id).assoc_visibility(db)
3171    }
3172}
3173
3174#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3175pub struct ExternBlock {
3176    pub(crate) id: ExternBlockId,
3177}
3178
3179impl ExternBlock {
3180    pub fn module(self, db: &dyn HirDatabase) -> Module {
3181        Module { id: self.id.module(db) }
3182    }
3183}
3184
3185#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3186pub struct StaticLifetime;
3187
3188impl StaticLifetime {
3189    pub fn name(self) -> Name {
3190        Name::new_symbol_root(sym::tick_static)
3191    }
3192}
3193
3194#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3195pub struct BuiltinType {
3196    pub(crate) inner: hir_def::builtin_type::BuiltinType,
3197}
3198
3199impl BuiltinType {
3200    // Constructors are added on demand, feel free to add more.
3201    pub fn str() -> BuiltinType {
3202        BuiltinType { inner: hir_def::builtin_type::BuiltinType::Str }
3203    }
3204
3205    pub fn i32() -> BuiltinType {
3206        BuiltinType {
3207            inner: hir_def::builtin_type::BuiltinType::Int(hir_ty::primitive::BuiltinInt::I32),
3208        }
3209    }
3210
3211    pub fn bool() -> BuiltinType {
3212        BuiltinType { inner: hir_def::builtin_type::BuiltinType::Bool }
3213    }
3214
3215    pub fn ty<'db>(self, db: &'db dyn HirDatabase) -> Type<'db> {
3216        let interner = DbInterner::new_no_crate(db);
3217        Type::no_params(Type::builtin_type_crate(db), Ty::from_builtin_type(interner, self.inner))
3218    }
3219
3220    pub fn name(self) -> Name {
3221        self.inner.as_name()
3222    }
3223
3224    pub fn is_int(&self) -> bool {
3225        matches!(self.inner, hir_def::builtin_type::BuiltinType::Int(_))
3226    }
3227
3228    pub fn is_uint(&self) -> bool {
3229        matches!(self.inner, hir_def::builtin_type::BuiltinType::Uint(_))
3230    }
3231
3232    pub fn is_float(&self) -> bool {
3233        matches!(self.inner, hir_def::builtin_type::BuiltinType::Float(_))
3234    }
3235
3236    pub fn is_f16(&self) -> bool {
3237        matches!(
3238            self.inner,
3239            hir_def::builtin_type::BuiltinType::Float(hir_def::builtin_type::BuiltinFloat::F16)
3240        )
3241    }
3242
3243    pub fn is_f32(&self) -> bool {
3244        matches!(
3245            self.inner,
3246            hir_def::builtin_type::BuiltinType::Float(hir_def::builtin_type::BuiltinFloat::F32)
3247        )
3248    }
3249
3250    pub fn is_f64(&self) -> bool {
3251        matches!(
3252            self.inner,
3253            hir_def::builtin_type::BuiltinType::Float(hir_def::builtin_type::BuiltinFloat::F64)
3254        )
3255    }
3256
3257    pub fn is_f128(&self) -> bool {
3258        matches!(
3259            self.inner,
3260            hir_def::builtin_type::BuiltinType::Float(hir_def::builtin_type::BuiltinFloat::F128)
3261        )
3262    }
3263
3264    pub fn is_char(&self) -> bool {
3265        matches!(self.inner, hir_def::builtin_type::BuiltinType::Char)
3266    }
3267
3268    pub fn is_bool(&self) -> bool {
3269        matches!(self.inner, hir_def::builtin_type::BuiltinType::Bool)
3270    }
3271
3272    pub fn is_str(&self) -> bool {
3273        matches!(self.inner, hir_def::builtin_type::BuiltinType::Str)
3274    }
3275}
3276
3277#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3278pub struct Macro {
3279    pub(crate) id: MacroId,
3280}
3281
3282impl Macro {
3283    pub fn module(self, db: &dyn HirDatabase) -> Module {
3284        Module { id: self.id.module(db) }
3285    }
3286
3287    pub fn name(self, db: &dyn HirDatabase) -> Name {
3288        match self.id {
3289            MacroId::Macro2Id(id) => {
3290                let loc = id.lookup(db);
3291                let source = loc.source(db);
3292                as_name_opt(source.value.name())
3293            }
3294            MacroId::MacroRulesId(id) => {
3295                let loc = id.lookup(db);
3296                let source = loc.source(db);
3297                as_name_opt(source.value.name())
3298            }
3299            MacroId::ProcMacroId(id) => {
3300                let loc = id.lookup(db);
3301                let source = loc.source(db);
3302                match loc.kind {
3303                    ProcMacroKind::CustomDerive => AttrFlags::derive_info(db, self.id).map_or_else(
3304                        || as_name_opt(source.value.name()),
3305                        |info| Name::new_symbol_root(info.trait_name.clone()),
3306                    ),
3307                    ProcMacroKind::Bang | ProcMacroKind::Attr => as_name_opt(source.value.name()),
3308                }
3309            }
3310        }
3311    }
3312
3313    pub fn is_macro_export(self, db: &dyn HirDatabase) -> bool {
3314        matches!(self.id, MacroId::MacroRulesId(_) if AttrFlags::query(db, self.id.into()).contains(AttrFlags::IS_MACRO_EXPORT))
3315    }
3316
3317    pub fn is_proc_macro(self) -> bool {
3318        matches!(self.id, MacroId::ProcMacroId(_))
3319    }
3320
3321    pub fn kind(&self, db: &dyn HirDatabase) -> MacroKind {
3322        match self.id {
3323            MacroId::Macro2Id(it) => match it.lookup(db).expander {
3324                MacroExpander::Declarative { .. } => MacroKind::Declarative,
3325                MacroExpander::BuiltIn(_) | MacroExpander::BuiltInEager(_) => {
3326                    MacroKind::DeclarativeBuiltIn
3327                }
3328                MacroExpander::BuiltInAttr(_) => MacroKind::AttrBuiltIn,
3329                MacroExpander::BuiltInDerive(_) => MacroKind::DeriveBuiltIn,
3330                MacroExpander::UnimplementedBuiltIn => MacroKind::Declarative,
3331            },
3332            MacroId::MacroRulesId(it) => match it.lookup(db).expander {
3333                MacroExpander::Declarative { .. } => MacroKind::Declarative,
3334                MacroExpander::BuiltIn(_) | MacroExpander::BuiltInEager(_) => {
3335                    MacroKind::DeclarativeBuiltIn
3336                }
3337                MacroExpander::BuiltInAttr(_) => MacroKind::AttrBuiltIn,
3338                MacroExpander::BuiltInDerive(_) => MacroKind::DeriveBuiltIn,
3339                MacroExpander::UnimplementedBuiltIn => MacroKind::Declarative,
3340            },
3341            MacroId::ProcMacroId(it) => match it.lookup(db).kind {
3342                ProcMacroKind::CustomDerive => MacroKind::Derive,
3343                ProcMacroKind::Bang => MacroKind::ProcMacro,
3344                ProcMacroKind::Attr => MacroKind::Attr,
3345            },
3346        }
3347    }
3348
3349    pub fn is_fn_like(&self, db: &dyn HirDatabase) -> bool {
3350        matches!(
3351            self.kind(db),
3352            MacroKind::Declarative | MacroKind::DeclarativeBuiltIn | MacroKind::ProcMacro
3353        )
3354    }
3355
3356    pub fn builtin_derive_kind(&self, db: &dyn HirDatabase) -> Option<BuiltinDeriveMacroKind> {
3357        let expander = match self.id {
3358            MacroId::Macro2Id(it) => it.lookup(db).expander,
3359            MacroId::MacroRulesId(it) => it.lookup(db).expander,
3360            MacroId::ProcMacroId(_) => return None,
3361        };
3362        match expander {
3363            MacroExpander::BuiltInDerive(kind) => Some(BuiltinDeriveMacroKind(kind)),
3364            _ => None,
3365        }
3366    }
3367
3368    pub fn is_env_or_option_env(&self, db: &dyn HirDatabase) -> bool {
3369        match self.id {
3370            MacroId::Macro2Id(it) => {
3371                matches!(it.lookup(db).expander, MacroExpander::BuiltInEager(eager) if eager.is_env_or_option_env())
3372            }
3373            MacroId::MacroRulesId(it) => {
3374                matches!(it.lookup(db).expander, MacroExpander::BuiltInEager(eager) if eager.is_env_or_option_env())
3375            }
3376            MacroId::ProcMacroId(_) => false,
3377        }
3378    }
3379
3380    /// Is this `asm!()`, or a variant of it (e.g. `global_asm!()`)?
3381    pub fn is_asm_like(&self, db: &dyn HirDatabase) -> bool {
3382        match self.id {
3383            MacroId::Macro2Id(it) => {
3384                matches!(it.lookup(db).expander, MacroExpander::BuiltIn(m) if m.is_asm())
3385            }
3386            MacroId::MacroRulesId(it) => {
3387                matches!(it.lookup(db).expander, MacroExpander::BuiltIn(m) if m.is_asm())
3388            }
3389            MacroId::ProcMacroId(_) => false,
3390        }
3391    }
3392
3393    pub fn is_attr(&self, db: &dyn HirDatabase) -> bool {
3394        matches!(self.kind(db), MacroKind::Attr | MacroKind::AttrBuiltIn)
3395    }
3396
3397    pub fn is_derive(&self, db: &dyn HirDatabase) -> bool {
3398        matches!(self.kind(db), MacroKind::Derive | MacroKind::DeriveBuiltIn)
3399    }
3400
3401    pub fn preferred_brace_style(&self, db: &dyn HirDatabase) -> Option<MacroBraces> {
3402        let attrs = self.attrs(db);
3403        MacroBraces::extract(attrs.attrs)
3404    }
3405}
3406
3407// Feature: Macro Brace Style Attribute
3408// Crate authors can declare the preferred brace style for their macro. This will affect how completion
3409// insert calls to it.
3410//
3411// This is only supported on function-like macros.
3412//
3413// To do that, insert the `#[rust_analyzer::macro_style(style)]` attribute on the macro (for proc macros,
3414// insert it for the macro's function). `style` can be one of:
3415//
3416//  - `braces` for `{...}` style.
3417//  - `brackets` for `[...]` style.
3418//  - `parentheses` for `(...)` style.
3419//
3420// Malformed attributes will be ignored without warnings.
3421//
3422// Note that users have no way to override this attribute, so be careful and only include things
3423// users definitely do not want to be completed!
3424
3425#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3426pub enum MacroBraces {
3427    Braces,
3428    Brackets,
3429    Parentheses,
3430}
3431
3432impl MacroBraces {
3433    fn extract(attrs: AttrFlags) -> Option<Self> {
3434        if attrs.contains(AttrFlags::MACRO_STYLE_BRACES) {
3435            Some(Self::Braces)
3436        } else if attrs.contains(AttrFlags::MACRO_STYLE_BRACKETS) {
3437            Some(Self::Brackets)
3438        } else if attrs.contains(AttrFlags::MACRO_STYLE_PARENTHESES) {
3439            Some(Self::Parentheses)
3440        } else {
3441            None
3442        }
3443    }
3444}
3445
3446#[derive(Clone, Copy, PartialEq, Eq, Hash)]
3447pub struct BuiltinDeriveMacroKind(BuiltinDeriveExpander);
3448
3449impl HasVisibility for Macro {
3450    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
3451        match self.id {
3452            MacroId::Macro2Id(id) => {
3453                let loc = id.lookup(db);
3454                let source = loc.source(db);
3455                visibility_from_ast(db, id, source.map(|src| src.visibility()))
3456            }
3457            MacroId::MacroRulesId(_) => Visibility::Public,
3458            MacroId::ProcMacroId(_) => Visibility::Public,
3459        }
3460    }
3461}
3462
3463#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
3464pub enum ItemInNs {
3465    Types(ModuleDef),
3466    Values(ModuleDef),
3467    Macros(Macro),
3468}
3469
3470impl From<Macro> for ItemInNs {
3471    fn from(it: Macro) -> Self {
3472        Self::Macros(it)
3473    }
3474}
3475
3476impl_from!(
3477    ModuleDef {
3478        Module => Types,
3479        Function => Values,
3480        Adt => Types,
3481        EnumVariant => Types,
3482        Const => Values,
3483        Static => Values,
3484        Trait => Types,
3485        TypeAlias => Types,
3486        BuiltinType => Types,
3487        Macro => Macros,
3488    }
3489    for ItemInNs
3490);
3491
3492impl ItemInNs {
3493    pub fn into_module_def(self) -> ModuleDef {
3494        match self {
3495            ItemInNs::Types(id) | ItemInNs::Values(id) => id,
3496            ItemInNs::Macros(id) => ModuleDef::Macro(id),
3497        }
3498    }
3499
3500    /// Returns the crate defining this item (or `None` if `self` is built-in).
3501    pub fn krate(&self, db: &dyn HirDatabase) -> Option<Crate> {
3502        match self {
3503            ItemInNs::Types(did) | ItemInNs::Values(did) => did.module(db).map(|m| m.krate(db)),
3504            ItemInNs::Macros(id) => Some(id.module(db).krate(db)),
3505        }
3506    }
3507
3508    pub fn attrs(&self, db: &dyn HirDatabase) -> Option<AttrsWithOwner> {
3509        match self {
3510            ItemInNs::Types(it) | ItemInNs::Values(it) => it.attrs(db),
3511            ItemInNs::Macros(it) => Some(it.attrs(db)),
3512        }
3513    }
3514}
3515
3516/// Invariant: `inner.as_extern_assoc_item(db).is_some()`
3517/// We do not actively enforce this invariant.
3518#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
3519pub enum ExternAssocItem {
3520    Function(Function),
3521    Static(Static),
3522    TypeAlias(TypeAlias),
3523}
3524
3525pub trait AsExternAssocItem {
3526    fn as_extern_assoc_item(self, db: &dyn HirDatabase) -> Option<ExternAssocItem>;
3527}
3528
3529impl AsExternAssocItem for Function {
3530    fn as_extern_assoc_item(self, db: &dyn HirDatabase) -> Option<ExternAssocItem> {
3531        let AnyFunctionId::FunctionId(id) = self.id else {
3532            return None;
3533        };
3534        as_extern_assoc_item(db, ExternAssocItem::Function, id)
3535    }
3536}
3537
3538impl AsExternAssocItem for Static {
3539    fn as_extern_assoc_item(self, db: &dyn HirDatabase) -> Option<ExternAssocItem> {
3540        as_extern_assoc_item(db, ExternAssocItem::Static, self.id)
3541    }
3542}
3543
3544impl AsExternAssocItem for TypeAlias {
3545    fn as_extern_assoc_item(self, db: &dyn HirDatabase) -> Option<ExternAssocItem> {
3546        as_extern_assoc_item(db, ExternAssocItem::TypeAlias, self.id)
3547    }
3548}
3549
3550/// Invariant: `inner.as_assoc_item(db).is_some()`
3551/// We do not actively enforce this invariant.
3552#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
3553pub enum AssocItem {
3554    Function(Function),
3555    Const(Const),
3556    TypeAlias(TypeAlias),
3557}
3558
3559impl From<method_resolution::CandidateId> for AssocItem {
3560    fn from(value: method_resolution::CandidateId) -> Self {
3561        match value {
3562            method_resolution::CandidateId::FunctionId(id) => AssocItem::Function(id.into()),
3563            method_resolution::CandidateId::ConstId(id) => AssocItem::Const(Const { id }),
3564        }
3565    }
3566}
3567
3568#[derive(Debug, Clone)]
3569pub enum AssocItemContainer {
3570    Trait(Trait),
3571    Impl(Impl),
3572}
3573
3574pub trait AsAssocItem {
3575    fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem>;
3576}
3577
3578impl AsAssocItem for Function {
3579    fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem> {
3580        match self.id {
3581            AnyFunctionId::FunctionId(id) => as_assoc_item(db, AssocItem::Function, id),
3582            AnyFunctionId::BuiltinDeriveImplMethod { .. } => Some(AssocItem::Function(self)),
3583        }
3584    }
3585}
3586
3587impl AsAssocItem for Const {
3588    fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem> {
3589        as_assoc_item(db, AssocItem::Const, self.id)
3590    }
3591}
3592
3593impl AsAssocItem for TypeAlias {
3594    fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem> {
3595        as_assoc_item(db, AssocItem::TypeAlias, self.id)
3596    }
3597}
3598
3599impl AsAssocItem for ModuleDef {
3600    fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem> {
3601        match self {
3602            ModuleDef::Function(it) => it.as_assoc_item(db),
3603            ModuleDef::Const(it) => it.as_assoc_item(db),
3604            ModuleDef::TypeAlias(it) => it.as_assoc_item(db),
3605            _ => None,
3606        }
3607    }
3608}
3609
3610impl AsAssocItem for DefWithBody {
3611    fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem> {
3612        match self {
3613            DefWithBody::Function(it) => it.as_assoc_item(db),
3614            DefWithBody::Const(it) => it.as_assoc_item(db),
3615            DefWithBody::Static(_) | DefWithBody::EnumVariant(_) => None,
3616        }
3617    }
3618}
3619
3620impl AsAssocItem for GenericDef {
3621    fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem> {
3622        match self {
3623            GenericDef::Function(it) => it.as_assoc_item(db),
3624            GenericDef::Const(it) => it.as_assoc_item(db),
3625            GenericDef::TypeAlias(it) => it.as_assoc_item(db),
3626            _ => None,
3627        }
3628    }
3629}
3630
3631fn as_assoc_item<'db, ID, DEF, LOC>(
3632    db: &(dyn HirDatabase + 'db),
3633    ctor: impl FnOnce(DEF) -> AssocItem,
3634    id: ID,
3635) -> Option<AssocItem>
3636where
3637    ID: Lookup<Data = AssocItemLoc<LOC>>,
3638    DEF: From<ID>,
3639    LOC: AstIdNode,
3640{
3641    match id.lookup(db).container {
3642        ItemContainerId::TraitId(_) | ItemContainerId::ImplId(_) => Some(ctor(DEF::from(id))),
3643        ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => None,
3644    }
3645}
3646
3647fn as_extern_assoc_item<'db, ID, DEF, LOC>(
3648    db: &(dyn HirDatabase + 'db),
3649    ctor: impl FnOnce(DEF) -> ExternAssocItem,
3650    id: ID,
3651) -> Option<ExternAssocItem>
3652where
3653    ID: Lookup<Data = AssocItemLoc<LOC>>,
3654    DEF: From<ID>,
3655    LOC: AstIdNode,
3656{
3657    match id.lookup(db).container {
3658        ItemContainerId::ExternBlockId(_) => Some(ctor(DEF::from(id))),
3659        ItemContainerId::TraitId(_) | ItemContainerId::ImplId(_) | ItemContainerId::ModuleId(_) => {
3660            None
3661        }
3662    }
3663}
3664
3665impl ExternAssocItem {
3666    pub fn name(self, db: &dyn HirDatabase) -> Name {
3667        match self {
3668            Self::Function(it) => it.name(db),
3669            Self::Static(it) => it.name(db),
3670            Self::TypeAlias(it) => it.name(db),
3671        }
3672    }
3673
3674    pub fn module(self, db: &dyn HirDatabase) -> Module {
3675        match self {
3676            Self::Function(f) => f.module(db),
3677            Self::Static(c) => c.module(db),
3678            Self::TypeAlias(t) => t.module(db),
3679        }
3680    }
3681
3682    pub fn as_function(self) -> Option<Function> {
3683        match self {
3684            Self::Function(v) => Some(v),
3685            _ => None,
3686        }
3687    }
3688
3689    pub fn as_static(self) -> Option<Static> {
3690        match self {
3691            Self::Static(v) => Some(v),
3692            _ => None,
3693        }
3694    }
3695
3696    pub fn as_type_alias(self) -> Option<TypeAlias> {
3697        match self {
3698            Self::TypeAlias(v) => Some(v),
3699            _ => None,
3700        }
3701    }
3702}
3703
3704impl AssocItem {
3705    pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
3706        match self {
3707            AssocItem::Function(it) => Some(it.name(db)),
3708            AssocItem::Const(it) => it.name(db),
3709            AssocItem::TypeAlias(it) => Some(it.name(db)),
3710        }
3711    }
3712
3713    pub fn module(self, db: &dyn HirDatabase) -> Module {
3714        match self {
3715            AssocItem::Function(f) => f.module(db),
3716            AssocItem::Const(c) => c.module(db),
3717            AssocItem::TypeAlias(t) => t.module(db),
3718        }
3719    }
3720
3721    pub fn container(self, db: &dyn HirDatabase) -> AssocItemContainer {
3722        let container = match self {
3723            AssocItem::Function(it) => match it.id {
3724                AnyFunctionId::FunctionId(id) => id.lookup(db).container,
3725                AnyFunctionId::BuiltinDeriveImplMethod { impl_, .. } => {
3726                    return AssocItemContainer::Impl(Impl {
3727                        id: AnyImplId::BuiltinDeriveImplId(impl_),
3728                    });
3729                }
3730            },
3731            AssocItem::Const(it) => it.id.lookup(db).container,
3732            AssocItem::TypeAlias(it) => it.id.lookup(db).container,
3733        };
3734        match container {
3735            ItemContainerId::TraitId(id) => AssocItemContainer::Trait(id.into()),
3736            ItemContainerId::ImplId(id) => AssocItemContainer::Impl(id.into()),
3737            ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => {
3738                panic!("invalid AssocItem")
3739            }
3740        }
3741    }
3742
3743    pub fn container_trait(self, db: &dyn HirDatabase) -> Option<Trait> {
3744        match self.container(db) {
3745            AssocItemContainer::Trait(t) => Some(t),
3746            _ => None,
3747        }
3748    }
3749
3750    pub fn implemented_trait(self, db: &dyn HirDatabase) -> Option<Trait> {
3751        match self.container(db) {
3752            AssocItemContainer::Impl(i) => i.trait_(db),
3753            _ => None,
3754        }
3755    }
3756
3757    pub fn container_or_implemented_trait(self, db: &dyn HirDatabase) -> Option<Trait> {
3758        match self.container(db) {
3759            AssocItemContainer::Trait(t) => Some(t),
3760            AssocItemContainer::Impl(i) => i.trait_(db),
3761        }
3762    }
3763
3764    pub fn implementing_ty(self, db: &dyn HirDatabase) -> Option<Type<'_>> {
3765        match self.container(db) {
3766            AssocItemContainer::Impl(i) => Some(i.self_ty(db)),
3767            _ => None,
3768        }
3769    }
3770
3771    pub fn as_function(self) -> Option<Function> {
3772        match self {
3773            Self::Function(v) => Some(v),
3774            _ => None,
3775        }
3776    }
3777
3778    pub fn as_const(self) -> Option<Const> {
3779        match self {
3780            Self::Const(v) => Some(v),
3781            _ => None,
3782        }
3783    }
3784
3785    pub fn as_type_alias(self) -> Option<TypeAlias> {
3786        match self {
3787            Self::TypeAlias(v) => Some(v),
3788            _ => None,
3789        }
3790    }
3791
3792    pub fn diagnostics<'db>(
3793        self,
3794        db: &'db dyn HirDatabase,
3795        acc: &mut Vec<AnyDiagnostic<'db>>,
3796        style_lints: bool,
3797    ) {
3798        match self {
3799            AssocItem::Function(func) => {
3800                GenericDef::Function(func).diagnostics(db, acc);
3801                DefWithBody::from(func).diagnostics(db, acc, style_lints);
3802            }
3803            AssocItem::Const(const_) => {
3804                GenericDef::Const(const_).diagnostics(db, acc);
3805                DefWithBody::from(const_).diagnostics(db, acc, style_lints);
3806            }
3807            AssocItem::TypeAlias(type_alias) => {
3808                GenericDef::TypeAlias(type_alias).diagnostics(db, acc);
3809                push_ty_diagnostics(
3810                    db,
3811                    acc,
3812                    db.type_for_type_alias_with_diagnostics(type_alias.id).diagnostics(),
3813                    &TypeAliasSignature::with_source_map(db, type_alias.id).1,
3814                );
3815                for diag in hir_ty::diagnostics::incorrect_case(db, type_alias.id.into()) {
3816                    acc.push(diag.into());
3817                }
3818            }
3819        }
3820    }
3821}
3822
3823impl HasVisibility for AssocItem {
3824    fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
3825        match self {
3826            AssocItem::Function(f) => f.visibility(db),
3827            AssocItem::Const(c) => c.visibility(db),
3828            AssocItem::TypeAlias(t) => t.visibility(db),
3829        }
3830    }
3831}
3832
3833impl_from!(AssocItem { Function, Const, TypeAlias } for ModuleDef);
3834
3835#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
3836pub enum GenericDef {
3837    Function(Function),
3838    Adt(Adt),
3839    Trait(Trait),
3840    TypeAlias(TypeAlias),
3841    Impl(Impl),
3842    // consts can have type parameters from their parents (i.e. associated consts of traits)
3843    Const(Const),
3844    Static(Static),
3845}
3846impl_from!(
3847    Function,
3848    Adt(Struct, Enum, Union),
3849    Trait,
3850    TypeAlias,
3851    Impl,
3852    Const,
3853    Static
3854    for GenericDef
3855);
3856
3857impl GenericDef {
3858    pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
3859        match self {
3860            GenericDef::Function(it) => Some(it.name(db)),
3861            GenericDef::Adt(it) => Some(it.name(db)),
3862            GenericDef::Trait(it) => Some(it.name(db)),
3863            GenericDef::TypeAlias(it) => Some(it.name(db)),
3864            GenericDef::Impl(_) => None,
3865            GenericDef::Const(it) => it.name(db),
3866            GenericDef::Static(it) => Some(it.name(db)),
3867        }
3868    }
3869
3870    pub fn module(self, db: &dyn HirDatabase) -> Module {
3871        match self {
3872            GenericDef::Function(it) => it.module(db),
3873            GenericDef::Adt(it) => it.module(db),
3874            GenericDef::Trait(it) => it.module(db),
3875            GenericDef::TypeAlias(it) => it.module(db),
3876            GenericDef::Impl(it) => it.module(db),
3877            GenericDef::Const(it) => it.module(db),
3878            GenericDef::Static(it) => it.module(db),
3879        }
3880    }
3881
3882    pub fn params(self, db: &dyn HirDatabase) -> Vec<GenericParam> {
3883        let Ok(id) = self.try_into() else {
3884            // Let's pretend builtin derive impls don't have generic parameters.
3885            return Vec::new();
3886        };
3887        let generics = GenericParams::of(db, id);
3888        let ty_params = generics.iter_type_or_consts().map(|(local_id, _)| {
3889            let toc = TypeOrConstParam { id: TypeOrConstParamId { parent: id, local_id } };
3890            match toc.split(db) {
3891                Either::Left(it) => GenericParam::ConstParam(it),
3892                Either::Right(it) => GenericParam::TypeParam(it),
3893            }
3894        });
3895        self.lifetime_params(db)
3896            .into_iter()
3897            .map(GenericParam::LifetimeParam)
3898            .chain(ty_params)
3899            .collect()
3900    }
3901
3902    pub fn lifetime_params(self, db: &dyn HirDatabase) -> Vec<LifetimeParam> {
3903        let Ok(id) = self.try_into() else {
3904            // Let's pretend builtin derive impls don't have generic parameters.
3905            return Vec::new();
3906        };
3907        let generics = GenericParams::of(db, id);
3908        generics
3909            .iter_lt()
3910            .map(|(local_id, _)| LifetimeParam { id: LifetimeParamId { parent: id, local_id } })
3911            .collect()
3912    }
3913
3914    pub fn type_or_const_params(self, db: &dyn HirDatabase) -> Vec<TypeOrConstParam> {
3915        let Ok(id) = self.try_into() else {
3916            // Let's pretend builtin derive impls don't have generic parameters.
3917            return Vec::new();
3918        };
3919        let generics = GenericParams::of(db, id);
3920        generics
3921            .iter_type_or_consts()
3922            .map(|(local_id, _)| TypeOrConstParam {
3923                id: TypeOrConstParamId { parent: id, local_id },
3924            })
3925            .collect()
3926    }
3927
3928    fn id(self) -> Option<GenericDefId> {
3929        Some(match self {
3930            GenericDef::Function(it) => match it.id {
3931                AnyFunctionId::FunctionId(it) => it.into(),
3932                AnyFunctionId::BuiltinDeriveImplMethod { .. } => return None,
3933            },
3934            GenericDef::Adt(it) => it.into(),
3935            GenericDef::Trait(it) => it.id.into(),
3936            GenericDef::TypeAlias(it) => it.id.into(),
3937            GenericDef::Impl(it) => match it.id {
3938                AnyImplId::ImplId(it) => it.into(),
3939                AnyImplId::BuiltinDeriveImplId(_) => return None,
3940            },
3941            GenericDef::Const(it) => it.id.into(),
3942            GenericDef::Static(it) => it.id.into(),
3943        })
3944    }
3945
3946    pub fn diagnostics<'db>(self, db: &'db dyn HirDatabase, acc: &mut Vec<AnyDiagnostic<'db>>) {
3947        let Some(def) = self.id() else { return };
3948
3949        let generics = GenericParams::of(db, def);
3950
3951        if generics.is_empty() && generics.has_no_predicates() {
3952            return;
3953        }
3954
3955        let source_map = match def {
3956            GenericDefId::AdtId(AdtId::EnumId(it)) => &EnumSignature::with_source_map(db, it).1,
3957            GenericDefId::AdtId(AdtId::StructId(it)) => &StructSignature::with_source_map(db, it).1,
3958            GenericDefId::AdtId(AdtId::UnionId(it)) => &UnionSignature::with_source_map(db, it).1,
3959            GenericDefId::ConstId(_) => return,
3960            GenericDefId::FunctionId(it) => &FunctionSignature::with_source_map(db, it).1,
3961            GenericDefId::ImplId(it) => &ImplSignature::with_source_map(db, it).1,
3962            GenericDefId::StaticId(_) => return,
3963            GenericDefId::TraitId(it) => &TraitSignature::with_source_map(db, it).1,
3964            GenericDefId::TypeAliasId(it) => &TypeAliasSignature::with_source_map(db, it).1,
3965        };
3966
3967        expr_store_diagnostics(db, acc, source_map);
3968        push_ty_diagnostics(
3969            db,
3970            acc,
3971            db.generic_defaults_with_diagnostics(def).diagnostics(),
3972            source_map,
3973        );
3974        push_ty_diagnostics(
3975            db,
3976            acc,
3977            GenericPredicates::query_with_diagnostics(db, def).diagnostics(),
3978            source_map,
3979        );
3980        push_ty_diagnostics(
3981            db,
3982            acc,
3983            db.const_param_types_with_diagnostics(def).diagnostics(),
3984            source_map,
3985        );
3986    }
3987
3988    /// Returns a string describing the kind of this type.
3989    #[inline]
3990    pub fn description(self) -> &'static str {
3991        match self {
3992            GenericDef::Function(_) => "function",
3993            GenericDef::Adt(Adt::Struct(_)) => "struct",
3994            GenericDef::Adt(Adt::Enum(_)) => "enum",
3995            GenericDef::Adt(Adt::Union(_)) => "union",
3996            GenericDef::Trait(_) => "trait",
3997            GenericDef::TypeAlias(_) => "type alias",
3998            GenericDef::Impl(_) => "impl",
3999            GenericDef::Const(_) => "constant",
4000            GenericDef::Static(_) => "static",
4001        }
4002    }
4003}
4004
4005// We cannot call this `Substitution` unfortunately...
4006#[derive(Debug)]
4007pub struct GenericSubstitution<'db> {
4008    owner: TypeOwnerId<'db>,
4009    def: GenericDefId,
4010    subst: GenericArgs<'db>,
4011}
4012
4013impl<'db> GenericSubstitution<'db> {
4014    fn new(def: GenericDefId, subst: GenericArgs<'db>, owner: TypeOwnerId<'db>) -> Self {
4015        Self { owner, def, subst }
4016    }
4017
4018    fn new_from_fn(
4019        def: Function,
4020        subst: GenericArgs<'db>,
4021        owner: TypeOwnerId<'db>,
4022    ) -> Option<Self> {
4023        match def.id {
4024            AnyFunctionId::FunctionId(def) => Some(Self::new(def.into(), subst, owner)),
4025            AnyFunctionId::BuiltinDeriveImplMethod { .. } => None,
4026        }
4027    }
4028
4029    pub fn types(&self, db: &'db dyn HirDatabase) -> Vec<(Symbol, Type<'db>)> {
4030        let container = match self.def {
4031            GenericDefId::ConstId(id) => Some(id.lookup(db).container),
4032            GenericDefId::FunctionId(id) => Some(id.lookup(db).container),
4033            GenericDefId::TypeAliasId(id) => Some(id.lookup(db).container),
4034            _ => None,
4035        };
4036        let container_type_params = container
4037            .and_then(|container| match container {
4038                ItemContainerId::ImplId(container) => Some(container.into()),
4039                ItemContainerId::TraitId(container) => Some(container.into()),
4040                _ => None,
4041            })
4042            .map(|container| {
4043                GenericParams::of(db, container)
4044                    .iter_type_or_consts()
4045                    .filter_map(|param| match param.1 {
4046                        TypeOrConstParamData::TypeParamData(param) => Some(param.name.clone()),
4047                        TypeOrConstParamData::ConstParamData(_) => None,
4048                    })
4049                    .collect::<Vec<_>>()
4050            });
4051        let generics = GenericParams::of(db, self.def);
4052        let type_params = generics.iter_type_or_consts().filter_map(|param| match param.1 {
4053            TypeOrConstParamData::TypeParamData(param) => Some(param.name.clone()),
4054            TypeOrConstParamData::ConstParamData(_) => None,
4055        });
4056        let parent_len = self.subst.len()
4057            - generics
4058                .iter_type_or_consts()
4059                .filter(|g| matches!(g.1, TypeOrConstParamData::TypeParamData(..)))
4060                .count();
4061        let container_params = self.subst.as_slice()[..parent_len]
4062            .iter()
4063            .filter_map(|param| param.ty())
4064            .zip(container_type_params.into_iter().flatten());
4065        let self_params = self.subst.as_slice()[parent_len..]
4066            .iter()
4067            .filter_map(|param| param.ty())
4068            .zip(type_params);
4069        container_params
4070            .chain(self_params)
4071            .filter_map(|(ty, name)| {
4072                Some((
4073                    name?.symbol().clone(),
4074                    Type { ty: EarlyBinder::bind(ty), owner: self.owner },
4075                ))
4076            })
4077            .collect()
4078    }
4079}
4080
4081/// A single local definition.
4082#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4083pub struct Local<'db> {
4084    pub(crate) parent: ExpressionStoreOwnerId,
4085    pub(crate) parent_infer: InferBodyId<'db>,
4086    pub(crate) binding_id: BindingId,
4087}
4088
4089pub struct LocalSource<'db> {
4090    pub local: Local<'db>,
4091    pub source: InFile<Either<ast::IdentPat, ast::SelfParam>>,
4092}
4093
4094impl<'db> LocalSource<'db> {
4095    pub fn as_ident_pat(&self) -> Option<&ast::IdentPat> {
4096        match &self.source.value {
4097            Either::Left(it) => Some(it),
4098            Either::Right(_) => None,
4099        }
4100    }
4101
4102    pub fn into_ident_pat(self) -> Option<ast::IdentPat> {
4103        match self.source.value {
4104            Either::Left(it) => Some(it),
4105            Either::Right(_) => None,
4106        }
4107    }
4108
4109    pub fn original_file(&self, db: &dyn HirDatabase) -> EditionedFileId {
4110        self.source.file_id.original_file(db)
4111    }
4112
4113    pub fn file(&self) -> HirFileId {
4114        self.source.file_id
4115    }
4116
4117    pub fn name(&self) -> Option<InFile<ast::Name>> {
4118        self.source.as_ref().map(|it| it.name()).transpose()
4119    }
4120
4121    pub fn syntax(&self) -> &SyntaxNode {
4122        self.source.value.syntax()
4123    }
4124
4125    pub fn syntax_ptr(self) -> InFile<SyntaxNodePtr> {
4126        self.source.map(|it| SyntaxNodePtr::new(it.syntax()))
4127    }
4128}
4129
4130impl<'db> Local<'db> {
4131    pub fn is_param(self, db: &dyn HirDatabase) -> bool {
4132        // FIXME: This parses!
4133        let src = self.primary_source(db);
4134        match src.source.value {
4135            Either::Left(pat) => pat
4136                .syntax()
4137                .ancestors()
4138                .map(|it| it.kind())
4139                .take_while(|&kind| ast::Pat::can_cast(kind) || ast::Param::can_cast(kind))
4140                .any(ast::Param::can_cast),
4141            Either::Right(_) => true,
4142        }
4143    }
4144
4145    pub fn as_self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> {
4146        match self.parent {
4147            ExpressionStoreOwnerId::Body(DefWithBodyId::FunctionId(func)) if self.is_self(db) => {
4148                Some(SelfParam { func: func.into() })
4149            }
4150            _ => None,
4151        }
4152    }
4153
4154    pub fn name(self, db: &dyn HirDatabase) -> Name {
4155        ExpressionStore::of(db, self.parent)[self.binding_id].name.clone()
4156    }
4157
4158    pub fn is_self(self, db: &dyn HirDatabase) -> bool {
4159        self.name(db) == sym::self_
4160    }
4161
4162    pub fn is_mut(self, db: &dyn HirDatabase) -> bool {
4163        ExpressionStore::of(db, self.parent)[self.binding_id].mode == BindingAnnotation::Mutable
4164    }
4165
4166    pub fn is_ref(self, db: &dyn HirDatabase) -> bool {
4167        matches!(
4168            ExpressionStore::of(db, self.parent)[self.binding_id].mode,
4169            BindingAnnotation::Ref | BindingAnnotation::RefMut
4170        )
4171    }
4172
4173    pub fn parent(self, _db: &dyn HirDatabase) -> ExpressionStoreOwner {
4174        self.parent.into()
4175    }
4176
4177    pub fn module(self, db: &dyn HirDatabase) -> Module {
4178        self.parent(db).module(db)
4179    }
4180
4181    pub fn as_id(self) -> u32 {
4182        self.binding_id.into_raw().into_u32()
4183    }
4184
4185    pub fn ty(self, db: &'db dyn HirDatabase) -> Type<'db> {
4186        let def = self.parent;
4187        let infer = InferenceResult::of(db, self.parent_infer);
4188        let ty = infer.binding_ty(self.binding_id);
4189        Type::new_body(db, def, ty)
4190    }
4191
4192    /// All definitions for this local. Example: `let (a$0, _) | (_, a$0) = it;`
4193    pub fn sources(self, db: &dyn HirDatabase) -> Vec<LocalSource<'db>> {
4194        let b;
4195        let (_, source_map) = match self.parent {
4196            ExpressionStoreOwnerId::Signature(generic_def_id) => {
4197                ExpressionStore::with_source_map(db, generic_def_id.into())
4198            }
4199            ExpressionStoreOwnerId::Body(def_with_body_id) => {
4200                b = Body::with_source_map(db, def_with_body_id);
4201                if b.0.is_any_self_param(self.binding_id)
4202                    && let Some(source) = b.1.self_param_syntax()
4203                {
4204                    let root = source.file_syntax(db);
4205                    return vec![LocalSource {
4206                        local: self,
4207                        source: source.map(|ast| Either::Right(ast.to_node(&root))),
4208                    }];
4209                }
4210                (&b.0.store, &b.1.store)
4211            }
4212            ExpressionStoreOwnerId::VariantFields(def) => {
4213                ExpressionStore::with_source_map(db, def.into())
4214            }
4215        };
4216        source_map
4217            .patterns_for_binding(self.binding_id)
4218            .iter()
4219            .map(|&definition| {
4220                let src = source_map.pat_syntax(definition).unwrap(); // Hmm...
4221                let root = src.file_syntax(db);
4222                LocalSource {
4223                    local: self,
4224                    source: src.map(|ast| match ast.to_node(&root) {
4225                        Either::Right(ast::Pat::IdentPat(it)) => Either::Left(it),
4226                        _ => unreachable!("local with non ident-pattern"),
4227                    }),
4228                }
4229            })
4230            .collect()
4231    }
4232
4233    /// The leftmost definition for this local. Example: `let (a$0, _) | (_, a) = it;`
4234    pub fn primary_source(self, db: &dyn HirDatabase) -> LocalSource<'db> {
4235        let b;
4236        let (_, source_map) = match self.parent {
4237            ExpressionStoreOwnerId::Signature(generic_def_id) => {
4238                ExpressionStore::with_source_map(db, generic_def_id.into())
4239            }
4240            ExpressionStoreOwnerId::Body(def_with_body_id) => {
4241                b = Body::with_source_map(db, def_with_body_id);
4242                if b.0.is_any_self_param(self.binding_id)
4243                    && let Some(source) = b.1.self_param_syntax()
4244                {
4245                    let root = source.file_syntax(db);
4246                    return LocalSource {
4247                        local: self,
4248                        source: source.map(|ast| Either::Right(ast.to_node(&root))),
4249                    };
4250                }
4251                (&b.0.store, &b.1.store)
4252            }
4253            ExpressionStoreOwnerId::VariantFields(def) => {
4254                ExpressionStore::with_source_map(db, def.into())
4255            }
4256        };
4257        source_map
4258            .patterns_for_binding(self.binding_id)
4259            .first()
4260            .map(|&definition| {
4261                let src = source_map.pat_syntax(definition).unwrap(); // Hmm...
4262                let root = src.file_syntax(db);
4263                LocalSource {
4264                    local: self,
4265                    source: src.map(|ast| match ast.to_node(&root) {
4266                        Either::Right(ast::Pat::IdentPat(it)) => Either::Left(it),
4267                        _ => unreachable!("local with non ident-pattern"),
4268                    }),
4269                }
4270            })
4271            .unwrap()
4272    }
4273}
4274
4275impl PartialOrd for Local<'_> {
4276    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
4277        Some(self.cmp(other))
4278    }
4279}
4280
4281impl Ord for Local<'_> {
4282    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
4283        self.binding_id.cmp(&other.binding_id)
4284    }
4285}
4286
4287#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4288pub struct DeriveHelper {
4289    pub(crate) derive: MacroId,
4290    pub(crate) idx: u32,
4291}
4292
4293impl DeriveHelper {
4294    pub fn derive(&self) -> Macro {
4295        Macro { id: self.derive }
4296    }
4297
4298    pub fn name(&self, db: &dyn HirDatabase) -> Name {
4299        AttrFlags::derive_info(db, self.derive)
4300            .and_then(|it| it.helpers.get(self.idx as usize))
4301            .map(|helper| Name::new_symbol_root(helper.clone()))
4302            .unwrap_or_else(Name::missing)
4303    }
4304}
4305
4306#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4307pub struct BuiltinAttr {
4308    idx: u32,
4309}
4310
4311impl BuiltinAttr {
4312    fn builtin(name: &str) -> Option<Self> {
4313        hir_expand::inert_attr_macro::find_builtin_attr_idx(&Symbol::intern(name))
4314            .map(|idx| BuiltinAttr { idx: idx as u32 })
4315    }
4316
4317    pub fn name(&self) -> Name {
4318        Name::new_symbol_root(Symbol::intern(
4319            hir_expand::inert_attr_macro::INERT_ATTRIBUTES[self.idx as usize].name,
4320        ))
4321    }
4322
4323    pub fn template(&self) -> Option<AttributeTemplate> {
4324        Some(hir_expand::inert_attr_macro::INERT_ATTRIBUTES[self.idx as usize].template)
4325    }
4326}
4327
4328#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4329pub struct ToolModule {
4330    krate: base_db::Crate,
4331    idx: u32,
4332}
4333
4334impl ToolModule {
4335    pub(crate) fn by_name(db: &dyn HirDatabase, krate: Crate, name: &str) -> Option<Self> {
4336        let krate = krate.id;
4337        let idx =
4338            crate_def_map(db, krate).registered_tools().iter().position(|it| it.as_str() == name)?
4339                as u32;
4340        Some(ToolModule { krate, idx })
4341    }
4342
4343    pub fn name(&self, db: &dyn HirDatabase) -> Name {
4344        Name::new_symbol_root(
4345            crate_def_map(db, self.krate).registered_tools()[self.idx as usize].clone(),
4346        )
4347    }
4348
4349    pub fn krate(&self) -> Crate {
4350        Crate { id: self.krate }
4351    }
4352}
4353
4354#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4355pub struct Label {
4356    pub(crate) parent: ExpressionStoreOwnerId,
4357    pub(crate) label_id: LabelId,
4358}
4359
4360impl Label {
4361    pub fn module(self, db: &dyn HirDatabase) -> Module {
4362        self.parent(db).module(db)
4363    }
4364
4365    pub fn parent(self, _db: &dyn HirDatabase) -> ExpressionStoreOwner {
4366        self.parent.into()
4367    }
4368
4369    pub fn name(self, db: &dyn HirDatabase) -> Name {
4370        ExpressionStore::of(db, self.parent)[self.label_id].name.clone()
4371    }
4372}
4373
4374#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4375pub enum GenericParam {
4376    TypeParam(TypeParam),
4377    ConstParam(ConstParam),
4378    LifetimeParam(LifetimeParam),
4379}
4380impl_from!(TypeParam, ConstParam, LifetimeParam for GenericParam);
4381
4382impl GenericParam {
4383    pub fn module(self, db: &dyn HirDatabase) -> Module {
4384        match self {
4385            GenericParam::TypeParam(it) => it.module(db),
4386            GenericParam::ConstParam(it) => it.module(db),
4387            GenericParam::LifetimeParam(it) => it.module(db),
4388        }
4389    }
4390
4391    pub fn name(self, db: &dyn HirDatabase) -> Name {
4392        match self {
4393            GenericParam::TypeParam(it) => it.name(db),
4394            GenericParam::ConstParam(it) => it.name(db),
4395            GenericParam::LifetimeParam(it) => it.name(db),
4396        }
4397    }
4398
4399    pub fn parent(self) -> GenericDef {
4400        match self {
4401            GenericParam::TypeParam(it) => it.id.parent().into(),
4402            GenericParam::ConstParam(it) => it.id.parent().into(),
4403            GenericParam::LifetimeParam(it) => it.id.parent.into(),
4404        }
4405    }
4406
4407    pub fn variance(self, db: &dyn HirDatabase) -> Option<Variance> {
4408        let parent = match self {
4409            GenericParam::TypeParam(it) => it.id.parent(),
4410            // const parameters are always invariant
4411            GenericParam::ConstParam(_) => return None,
4412            GenericParam::LifetimeParam(it) => it.id.parent,
4413        };
4414        let index = match self {
4415            GenericParam::TypeParam(it) => hir_ty::type_or_const_param_idx(db, it.id.into()),
4416            GenericParam::ConstParam(_) => return None,
4417            GenericParam::LifetimeParam(it) => hir_ty::lifetime_param_idx(db, it.id),
4418        };
4419        db.variances_of(parent).get(index as usize).map(Into::into)
4420    }
4421}
4422
4423#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4424pub enum Variance {
4425    Bivariant,
4426    Covariant,
4427    Contravariant,
4428    Invariant,
4429}
4430
4431impl From<rustc_type_ir::Variance> for Variance {
4432    #[inline]
4433    fn from(value: rustc_type_ir::Variance) -> Self {
4434        match value {
4435            rustc_type_ir::Variance::Covariant => Variance::Covariant,
4436            rustc_type_ir::Variance::Invariant => Variance::Invariant,
4437            rustc_type_ir::Variance::Contravariant => Variance::Contravariant,
4438            rustc_type_ir::Variance::Bivariant => Variance::Bivariant,
4439        }
4440    }
4441}
4442
4443impl fmt::Display for Variance {
4444    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4445        let description = match self {
4446            Variance::Bivariant => "bivariant",
4447            Variance::Covariant => "covariant",
4448            Variance::Contravariant => "contravariant",
4449            Variance::Invariant => "invariant",
4450        };
4451        f.pad(description)
4452    }
4453}
4454
4455#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4456pub struct TypeParam {
4457    pub(crate) id: TypeParamId,
4458}
4459
4460impl TypeParam {
4461    pub fn merge(self) -> TypeOrConstParam {
4462        TypeOrConstParam { id: self.id.into() }
4463    }
4464
4465    pub fn name(self, db: &dyn HirDatabase) -> Name {
4466        self.merge().name(db)
4467    }
4468
4469    pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef {
4470        self.id.parent().into()
4471    }
4472
4473    pub fn module(self, db: &dyn HirDatabase) -> Module {
4474        self.id.parent().module(db).into()
4475    }
4476
4477    /// Is this type parameter implicitly introduced (eg. `Self` in a trait or an `impl Trait`
4478    /// argument)?
4479    pub fn is_implicit(self, db: &dyn HirDatabase) -> bool {
4480        let params = GenericParams::of(db, self.id.parent());
4481        let data = &params[self.id.local_id()];
4482        match data.type_param().unwrap().provenance {
4483            TypeParamProvenance::TypeParamList => false,
4484            TypeParamProvenance::TraitSelf | TypeParamProvenance::ArgumentImplTrait => true,
4485        }
4486    }
4487
4488    pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
4489        let interner = DbInterner::new_no_crate(db);
4490        let index = hir_ty::type_or_const_param_idx(db, self.id.into());
4491        let ty = Ty::new_param(interner, self.id, index);
4492        Type::new(self.id.parent(), ty)
4493    }
4494
4495    /// FIXME: this only lists trait bounds from the item defining the type
4496    /// parameter, not additional bounds that might be added e.g. by a method if
4497    /// the parameter comes from an impl!
4498    pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> {
4499        let self_ty = self.ty(db).ty.instantiate_identity().skip_norm_wip();
4500        GenericPredicates::query_explicit(db, self.id.parent())
4501            .iter_identity()
4502            .filter_map(|pred| match &pred.kind().skip_binder() {
4503                ClauseKind::Trait(trait_ref) if trait_ref.self_ty() == self_ty => {
4504                    Some(Trait::from(trait_ref.def_id().0))
4505                }
4506                _ => None,
4507            })
4508            .collect()
4509    }
4510
4511    pub fn default(self, db: &dyn HirDatabase) -> Option<Type<'_>> {
4512        let ty = generic_arg_from_param(db, self.id.into())?;
4513        match ty.kind() {
4514            rustc_type_ir::GenericArgKind::Type(it) if !it.is_ty_error() => {
4515                Some(Type::new(self.id.parent(), it))
4516            }
4517            _ => None,
4518        }
4519    }
4520
4521    pub fn is_unstable(self, db: &dyn HirDatabase) -> bool {
4522        self.attrs(db).is_unstable()
4523    }
4524}
4525
4526#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4527pub struct LifetimeParam {
4528    pub(crate) id: LifetimeParamId,
4529}
4530
4531impl LifetimeParam {
4532    pub fn name(self, db: &dyn HirDatabase) -> Name {
4533        let params = GenericParams::of(db, self.id.parent);
4534        params[self.id.local_id].name.clone()
4535    }
4536
4537    pub fn module(self, db: &dyn HirDatabase) -> Module {
4538        self.id.parent.module(db).into()
4539    }
4540
4541    pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef {
4542        self.id.parent.into()
4543    }
4544}
4545
4546#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4547pub struct ConstParam {
4548    pub(crate) id: ConstParamId,
4549}
4550
4551impl ConstParam {
4552    pub fn merge(self) -> TypeOrConstParam {
4553        TypeOrConstParam { id: self.id.into() }
4554    }
4555
4556    pub fn name(self, db: &dyn HirDatabase) -> Name {
4557        let params = GenericParams::of(db, self.id.parent());
4558        match params[self.id.local_id()].name() {
4559            Some(it) => it.clone(),
4560            None => {
4561                never!();
4562                Name::missing()
4563            }
4564        }
4565    }
4566
4567    pub fn module(self, db: &dyn HirDatabase) -> Module {
4568        self.id.parent().module(db).into()
4569    }
4570
4571    pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef {
4572        self.id.parent().into()
4573    }
4574
4575    pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
4576        Type::new(self.id.parent(), db.const_param_ty(self.id))
4577    }
4578
4579    pub fn default(self, db: &dyn HirDatabase, display_target: DisplayTarget) -> Option<String> {
4580        let arg = generic_arg_from_param(db, self.id.into())?;
4581        Some(arg.display(db, display_target).to_string())
4582    }
4583
4584    pub fn default_source_code(
4585        self,
4586        db: &dyn HirDatabase,
4587        target_module: Module,
4588    ) -> Option<ast::ConstArg> {
4589        let arg = generic_arg_from_param(db, self.id.into())?;
4590        known_const_to_ast(arg.konst()?, db, target_module.id)
4591    }
4592}
4593
4594fn generic_arg_from_param(db: &dyn HirDatabase, id: TypeOrConstParamId) -> Option<GenericArg<'_>> {
4595    let local_idx = hir_ty::type_or_const_param_idx(db, id);
4596    let defaults = db.generic_defaults(id.parent);
4597    let ty = defaults.get(local_idx as usize)?;
4598    // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s.
4599    Some(ty.instantiate_identity().skip_norm_wip())
4600}
4601
4602#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4603pub struct TypeOrConstParam {
4604    pub(crate) id: TypeOrConstParamId,
4605}
4606
4607impl TypeOrConstParam {
4608    pub fn name(self, db: &dyn HirDatabase) -> Name {
4609        let params = GenericParams::of(db, self.id.parent);
4610        match params[self.id.local_id].name() {
4611            Some(n) => n.clone(),
4612            _ => Name::missing(),
4613        }
4614    }
4615
4616    pub fn module(self, db: &dyn HirDatabase) -> Module {
4617        self.id.parent.module(db).into()
4618    }
4619
4620    pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef {
4621        self.id.parent.into()
4622    }
4623
4624    pub fn split(self, db: &dyn HirDatabase) -> Either<ConstParam, TypeParam> {
4625        let params = GenericParams::of(db, self.id.parent);
4626        match &params[self.id.local_id] {
4627            TypeOrConstParamData::TypeParamData(_) => {
4628                Either::Right(TypeParam { id: TypeParamId::from_unchecked(self.id) })
4629            }
4630            TypeOrConstParamData::ConstParamData(_) => {
4631                Either::Left(ConstParam { id: ConstParamId::from_unchecked(self.id) })
4632            }
4633        }
4634    }
4635
4636    pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
4637        match self.split(db) {
4638            Either::Left(it) => it.ty(db),
4639            Either::Right(it) => it.ty(db),
4640        }
4641    }
4642
4643    pub fn as_type_param(self, db: &dyn HirDatabase) -> Option<TypeParam> {
4644        let params = GenericParams::of(db, self.id.parent);
4645        match &params[self.id.local_id] {
4646            TypeOrConstParamData::TypeParamData(_) => {
4647                Some(TypeParam { id: TypeParamId::from_unchecked(self.id) })
4648            }
4649            TypeOrConstParamData::ConstParamData(_) => None,
4650        }
4651    }
4652
4653    pub fn as_const_param(self, db: &dyn HirDatabase) -> Option<ConstParam> {
4654        let params = GenericParams::of(db, self.id.parent);
4655        match &params[self.id.local_id] {
4656            TypeOrConstParamData::TypeParamData(_) => None,
4657            TypeOrConstParamData::ConstParamData(_) => {
4658                Some(ConstParam { id: ConstParamId::from_unchecked(self.id) })
4659            }
4660        }
4661    }
4662}
4663
4664#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4665pub struct Impl {
4666    pub(crate) id: AnyImplId,
4667}
4668
4669impl Impl {
4670    pub fn all_in_crate(db: &dyn HirDatabase, krate: Crate) -> Vec<Impl> {
4671        let mut result = Vec::new();
4672        extend_with_def_map(db, crate_def_map(db, krate.id), &mut result);
4673        return result;
4674
4675        fn extend_with_def_map(db: &dyn HirDatabase, def_map: &DefMap, result: &mut Vec<Impl>) {
4676            for (_, module) in def_map.modules() {
4677                result.extend(module.scope.impls().map(Impl::from));
4678                result.extend(module.scope.builtin_derive_impls().map(Impl::from));
4679
4680                for unnamed_const in module.scope.unnamed_consts() {
4681                    for (_, block_def_map) in Body::of(db, unnamed_const.into()).blocks(db) {
4682                        extend_with_def_map(db, block_def_map, result);
4683                    }
4684                }
4685            }
4686        }
4687    }
4688
4689    pub fn all_in_module(db: &dyn HirDatabase, module: Module) -> Vec<Impl> {
4690        module.impl_defs(db)
4691    }
4692
4693    /// **Note:** This is an **approximation** that strives to give the *human-perceived notion* of an "impl for type",
4694    /// **not** answer the technical question "what are all impls applying to this type". In particular, it excludes
4695    /// blanket impls, and only does a shallow type constructor check. In fact, this should've probably been on `Adt`
4696    /// etc., and not on `Type`. If you would want to create a precise list of all impls applying to a type,
4697    /// you would need to include blanket impls, and try to prove to predicates for each candidate.
4698    pub fn all_for_type<'db>(db: &'db dyn HirDatabase, ty: Type<'db>) -> Vec<Impl> {
4699        let mut result = Vec::new();
4700        let interner = DbInterner::new_no_crate(db);
4701        let Some(simplified_ty) = fast_reject::simplify_type(
4702            interner,
4703            ty.ty.skip_binder(),
4704            fast_reject::TreatParams::AsRigid,
4705        ) else {
4706            return Vec::new();
4707        };
4708        let mut extend_with_impls = |impls: Either<&[ImplId], &[BuiltinDeriveImplId]>| match impls {
4709            Either::Left(impls) => result.extend(impls.iter().copied().map(Impl::from)),
4710            Either::Right(impls) => result.extend(impls.iter().copied().map(Impl::from)),
4711        };
4712        method_resolution::with_incoherent_inherent_impls(
4713            db,
4714            ty.krate(db),
4715            &simplified_ty,
4716            |impls| extend_with_impls(Either::Left(impls)),
4717        );
4718        if let Some(module) = method_resolution::simplified_type_module(db, &simplified_ty) {
4719            InherentImpls::for_each_crate_and_block(
4720                db,
4721                module.krate(db),
4722                module.block(db),
4723                &mut |impls| extend_with_impls(Either::Left(impls.for_self_ty(&simplified_ty))),
4724            );
4725            std::iter::successors(module.block(db), |block| block.module(db).block(db))
4726                .filter_map(|block| TraitImpls::for_block(db, block))
4727                .for_each(|impls| impls.for_self_ty(&simplified_ty, &mut extend_with_impls));
4728            for &krate in &*all_crates(db) {
4729                TraitImpls::for_crate(db, krate)
4730                    .for_self_ty(&simplified_ty, &mut extend_with_impls);
4731            }
4732        } else {
4733            for &krate in &*all_crates(db) {
4734                TraitImpls::for_crate(db, krate)
4735                    .for_self_ty(&simplified_ty, &mut extend_with_impls);
4736            }
4737        }
4738        result
4739    }
4740
4741    pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> {
4742        let module = trait_.module(db).id;
4743        let mut all = Vec::new();
4744        let mut handle_impls = |impls: &TraitImpls<'_>| {
4745            impls.for_trait(trait_.id, |impls| match impls {
4746                Either::Left(impls) => all.extend(impls.iter().copied().map(Impl::from)),
4747                Either::Right(impls) => all.extend(impls.iter().copied().map(Impl::from)),
4748            });
4749        };
4750        for krate in module.krate(db).transitive_rev_deps(db) {
4751            handle_impls(TraitImpls::for_crate(db, krate));
4752        }
4753        if let Some(block) = module.block(db)
4754            && let Some(impls) = TraitImpls::for_block(db, block)
4755        {
4756            handle_impls(impls);
4757        }
4758        all
4759    }
4760
4761    pub fn trait_(self, db: &dyn HirDatabase) -> Option<Trait> {
4762        match self.id {
4763            AnyImplId::ImplId(id) => {
4764                let trait_ref = db.impl_trait(id)?;
4765                let id = trait_ref.skip_binder().def_id;
4766                Some(Trait { id: id.0 })
4767            }
4768            AnyImplId::BuiltinDeriveImplId(id) => {
4769                let loc = id.loc(db);
4770                let lang_items = hir_def::lang_item::lang_items(db, loc.adt.module(db).krate(db));
4771                loc.trait_.get_id(lang_items).map(Trait::from)
4772            }
4773        }
4774    }
4775
4776    pub fn trait_ref(self, db: &dyn HirDatabase) -> Option<TraitRef<'_>> {
4777        match self.id {
4778            AnyImplId::ImplId(id) => {
4779                let trait_ref = db.impl_trait(id)?.instantiate_identity().skip_norm_wip();
4780                Some(TraitRef::new(id.into(), trait_ref))
4781            }
4782            AnyImplId::BuiltinDeriveImplId(id) => {
4783                let loc = id.loc(db);
4784                let krate = loc.module(db).krate(db);
4785                let interner = DbInterner::new_with(db, krate);
4786                let trait_ref = hir_ty::builtin_derive::impl_trait(interner, id)
4787                    .instantiate_identity()
4788                    .skip_norm_wip();
4789                Some(TraitRef { owner: TypeOwnerId::BuiltinDeriveImplId(id), trait_ref })
4790            }
4791        }
4792    }
4793
4794    pub fn self_ty(self, db: &dyn HirDatabase) -> Type<'_> {
4795        match self.id {
4796            AnyImplId::ImplId(id) => {
4797                let ty = db.impl_self_ty(id).instantiate_identity().skip_norm_wip();
4798                Type::new(id.into(), ty)
4799            }
4800            AnyImplId::BuiltinDeriveImplId(id) => {
4801                let loc = id.loc(db);
4802                let krate = loc.module(db).krate(db);
4803                let interner = DbInterner::new_with(db, krate);
4804                let ty =
4805                    hir_ty::builtin_derive::impl_trait(interner, id).map_bound(|it| it.self_ty());
4806                Type { owner: TypeOwnerId::BuiltinDeriveImplId(id), ty }
4807            }
4808        }
4809    }
4810
4811    pub fn items(self, db: &dyn HirDatabase) -> Vec<AssocItem> {
4812        match self.id {
4813            AnyImplId::ImplId(id) => {
4814                id.impl_items(db).items.iter().map(|&(_, it)| it.into()).collect()
4815            }
4816            AnyImplId::BuiltinDeriveImplId(impl_) => impl_
4817                .loc(db)
4818                .trait_
4819                .all_methods()
4820                .iter()
4821                .map(|&method| {
4822                    AssocItem::Function(Function {
4823                        id: AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ },
4824                    })
4825                })
4826                .collect(),
4827        }
4828    }
4829
4830    pub fn is_negative(self, db: &dyn HirDatabase) -> bool {
4831        match self.id {
4832            AnyImplId::ImplId(id) => ImplSignature::of(db, id).flags.contains(ImplFlags::NEGATIVE),
4833            AnyImplId::BuiltinDeriveImplId(_) => false,
4834        }
4835    }
4836
4837    pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool {
4838        match self.id {
4839            AnyImplId::ImplId(id) => ImplSignature::of(db, id).flags.contains(ImplFlags::UNSAFE),
4840            AnyImplId::BuiltinDeriveImplId(_) => false,
4841        }
4842    }
4843
4844    pub fn module(self, db: &dyn HirDatabase) -> Module {
4845        match self.id {
4846            AnyImplId::ImplId(id) => id.module(db).into(),
4847            AnyImplId::BuiltinDeriveImplId(id) => id.module(db).into(),
4848        }
4849    }
4850
4851    pub fn check_orphan_rules(self, db: &dyn HirDatabase) -> bool {
4852        match self.id {
4853            AnyImplId::ImplId(id) => check_orphan_rules(db, id),
4854            AnyImplId::BuiltinDeriveImplId(_) => true,
4855        }
4856    }
4857
4858    fn all_macro_calls(&self, db: &dyn HirDatabase) -> Box<[(AstId<ast::Item>, MacroCallId)]> {
4859        match self.id {
4860            AnyImplId::ImplId(id) => id.impl_items(db).macro_calls.to_vec().into_boxed_slice(),
4861            AnyImplId::BuiltinDeriveImplId(_) => Box::default(),
4862        }
4863    }
4864}
4865
4866#[derive(Clone, PartialEq, Eq, Debug, Hash)]
4867pub struct TraitRef<'db> {
4868    owner: TypeOwnerId<'db>,
4869    trait_ref: hir_ty::next_solver::TraitRef<'db>,
4870}
4871
4872impl<'db> TraitRef<'db> {
4873    fn new(owner: GenericDefId, trait_ref: hir_ty::next_solver::TraitRef<'db>) -> Self {
4874        Self { owner: TypeOwnerId::GenericDefId(owner), trait_ref }
4875    }
4876
4877    pub fn trait_(&self) -> Trait {
4878        Trait { id: self.trait_ref.def_id.0 }
4879    }
4880
4881    pub fn self_ty(&self) -> Type<'_> {
4882        let ty = self.trait_ref.self_ty();
4883        Type { owner: self.owner, ty: EarlyBinder::bind(ty) }
4884    }
4885
4886    /// Returns `idx`-th argument of this trait reference if it is a type argument. Note that the
4887    /// first argument is the `Self` type.
4888    pub fn get_type_argument(&self, idx: usize) -> Option<Type<'db>> {
4889        self.trait_ref
4890            .args
4891            .as_slice()
4892            .get(idx)
4893            .and_then(|arg| arg.ty())
4894            .map(|ty| Type { owner: self.owner, ty: EarlyBinder::bind(ty) })
4895    }
4896}
4897
4898#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4899enum AnyClosureId<'db> {
4900    ClosureId(InternedClosureId<'db>),
4901    CoroutineClosureId(InternedCoroutineClosureId<'db>),
4902}
4903
4904#[derive(Clone, Debug, PartialEq, Eq, Hash)]
4905pub struct Closure<'db> {
4906    owner: TypeOwnerId<'db>,
4907    id: AnyClosureId<'db>,
4908    subst: GenericArgs<'db>,
4909}
4910
4911impl<'db> Closure<'db> {
4912    fn as_ty(&self, db: &'db dyn HirDatabase) -> Ty<'db> {
4913        let interner = DbInterner::new_no_crate(db);
4914        match self.id {
4915            AnyClosureId::ClosureId(id) => Ty::new_closure(interner, id.into(), self.subst),
4916            AnyClosureId::CoroutineClosureId(id) => {
4917                Ty::new_coroutine_closure(interner, id.into(), self.subst)
4918            }
4919        }
4920    }
4921
4922    pub fn display_with_id(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String {
4923        self.as_ty(db)
4924            .display(db, display_target)
4925            .with_closure_style(ClosureStyle::ClosureWithId)
4926            .to_string()
4927    }
4928
4929    pub fn display_with_impl(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String {
4930        self.as_ty(db)
4931            .display(db, display_target)
4932            .with_closure_style(ClosureStyle::ImplFn)
4933            .to_string()
4934    }
4935
4936    pub fn captured_items(&self, db: &'db dyn HirDatabase) -> Vec<ClosureCapture<'db>> {
4937        let closure = match self.id {
4938            AnyClosureId::ClosureId(it) => it.loc(db),
4939            AnyClosureId::CoroutineClosureId(it) => it.loc(db),
4940        };
4941        captured_items(db, closure)
4942    }
4943
4944    pub fn fn_trait(&self, _db: &dyn HirDatabase) -> FnTrait {
4945        match self.id {
4946            AnyClosureId::ClosureId(_) => match self.subst.as_closure().kind() {
4947                rustc_type_ir::ClosureKind::Fn => FnTrait::Fn,
4948                rustc_type_ir::ClosureKind::FnMut => FnTrait::FnMut,
4949                rustc_type_ir::ClosureKind::FnOnce => FnTrait::FnOnce,
4950            },
4951            AnyClosureId::CoroutineClosureId(_) => match self.subst.as_coroutine_closure().kind() {
4952                rustc_type_ir::ClosureKind::Fn => FnTrait::AsyncFn,
4953                rustc_type_ir::ClosureKind::FnMut => FnTrait::AsyncFnMut,
4954                rustc_type_ir::ClosureKind::FnOnce => FnTrait::AsyncFnOnce,
4955            },
4956        }
4957    }
4958}
4959
4960/// A coroutine expression, including async, generator, and async-generator coroutines.
4961#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4962pub struct Coroutine<'db> {
4963    id: InternedCoroutineId<'db>,
4964}
4965
4966impl<'db> Coroutine<'db> {
4967    /// Returns the values captured by this coroutine.
4968    pub fn captured_items(&self, db: &'db dyn HirDatabase) -> Vec<ClosureCapture<'db>> {
4969        captured_items(db, self.id.loc(db))
4970    }
4971}
4972
4973fn captured_items<'db>(
4974    db: &'db dyn HirDatabase,
4975    closure: InternedClosure<'db>,
4976) -> Vec<ClosureCapture<'db>> {
4977    let InternedClosure { owner: infer_owner, expr: closure, .. } = closure;
4978    let infer = InferenceResult::of(db, infer_owner);
4979    let owner = infer_owner.expression_store_owner(db);
4980    infer.closures_data[&closure]
4981        .min_captures
4982        .values()
4983        .flatten()
4984        .map(|capture| ClosureCapture { owner, infer_owner, closure, capture })
4985        .collect()
4986}
4987
4988#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4989pub enum FnTrait {
4990    FnOnce,
4991    FnMut,
4992    Fn,
4993
4994    AsyncFnOnce,
4995    AsyncFnMut,
4996    AsyncFn,
4997}
4998
4999impl From<traits::FnTrait> for FnTrait {
5000    fn from(value: traits::FnTrait) -> Self {
5001        match value {
5002            traits::FnTrait::FnOnce => FnTrait::FnOnce,
5003            traits::FnTrait::FnMut => FnTrait::FnMut,
5004            traits::FnTrait::Fn => FnTrait::Fn,
5005            traits::FnTrait::AsyncFnOnce => FnTrait::AsyncFnOnce,
5006            traits::FnTrait::AsyncFnMut => FnTrait::AsyncFnMut,
5007            traits::FnTrait::AsyncFn => FnTrait::AsyncFn,
5008        }
5009    }
5010}
5011
5012impl fmt::Display for FnTrait {
5013    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5014        match self {
5015            FnTrait::FnOnce => write!(f, "FnOnce"),
5016            FnTrait::FnMut => write!(f, "FnMut"),
5017            FnTrait::Fn => write!(f, "Fn"),
5018            FnTrait::AsyncFnOnce => write!(f, "AsyncFnOnce"),
5019            FnTrait::AsyncFnMut => write!(f, "AsyncFnMut"),
5020            FnTrait::AsyncFn => write!(f, "AsyncFn"),
5021        }
5022    }
5023}
5024
5025impl FnTrait {
5026    pub const fn function_name(&self) -> &'static str {
5027        match self {
5028            FnTrait::FnOnce => "call_once",
5029            FnTrait::FnMut => "call_mut",
5030            FnTrait::Fn => "call",
5031            FnTrait::AsyncFnOnce => "async_call_once",
5032            FnTrait::AsyncFnMut => "async_call_mut",
5033            FnTrait::AsyncFn => "async_call",
5034        }
5035    }
5036
5037    pub fn lang_item(self) -> LangItem {
5038        match self {
5039            FnTrait::FnOnce => LangItem::FnOnce,
5040            FnTrait::FnMut => LangItem::FnMut,
5041            FnTrait::Fn => LangItem::Fn,
5042            FnTrait::AsyncFnOnce => LangItem::AsyncFnOnce,
5043            FnTrait::AsyncFnMut => LangItem::AsyncFnMut,
5044            FnTrait::AsyncFn => LangItem::AsyncFn,
5045        }
5046    }
5047
5048    pub fn get_id(self, db: &dyn HirDatabase, krate: Crate) -> Option<Trait> {
5049        Trait::lang(db, krate, self.lang_item())
5050    }
5051}
5052
5053#[derive(Clone, Debug, PartialEq, Eq)]
5054pub struct ClosureCapture<'db> {
5055    owner: ExpressionStoreOwnerId,
5056    infer_owner: InferBodyId<'db>,
5057    closure: ExprId,
5058    capture: &'db hir_ty::closure_analysis::CapturedPlace,
5059}
5060
5061impl<'db> ClosureCapture<'db> {
5062    pub fn local(&self) -> Local<'db> {
5063        Local {
5064            parent: self.owner,
5065            parent_infer: self.infer_owner,
5066            binding_id: self.capture.captured_local(),
5067        }
5068    }
5069
5070    /// Returns whether this place has any field (aka. non-deref) projections.
5071    pub fn has_field_projections(&self) -> bool {
5072        self.capture
5073            .place
5074            .projections
5075            .iter()
5076            .any(|proj| matches!(proj.kind, hir_ty::closure_analysis::ProjectionKind::Field { .. }))
5077    }
5078
5079    pub fn usages(&self) -> CaptureUsages<'db> {
5080        CaptureUsages { parent: self.owner, sources: &self.capture.info.sources }
5081    }
5082
5083    pub fn kind(&self) -> CaptureKind {
5084        match self.capture.info.capture_kind {
5085            hir_ty::closure_analysis::UpvarCapture::ByValue => CaptureKind::Move,
5086            hir_ty::closure_analysis::UpvarCapture::ByUse => CaptureKind::SharedRef, // Good enough?
5087            hir_ty::closure_analysis::UpvarCapture::ByRef(
5088                hir_ty::closure_analysis::BorrowKind::Immutable,
5089            ) => CaptureKind::SharedRef,
5090            hir_ty::closure_analysis::UpvarCapture::ByRef(
5091                hir_ty::closure_analysis::BorrowKind::UniqueImmutable,
5092            ) => CaptureKind::UniqueSharedRef,
5093            hir_ty::closure_analysis::UpvarCapture::ByRef(
5094                hir_ty::closure_analysis::BorrowKind::Mutable,
5095            ) => CaptureKind::MutableRef,
5096        }
5097    }
5098
5099    /// Converts the place to a name that can be inserted into source code.
5100    pub fn place_to_name(&self, db: &dyn HirDatabase, edition: Edition) -> String {
5101        let mut result = self.local().name(db).display(db, edition).to_string();
5102        for (i, proj) in self.capture.place.projections.iter().enumerate() {
5103            match proj.kind {
5104                hir_ty::closure_analysis::ProjectionKind::Deref => {}
5105                hir_ty::closure_analysis::ProjectionKind::Field { field_idx, variant_idx } => {
5106                    let ty = self.capture.place.ty_before_projection(i);
5107                    match ty.kind() {
5108                        TyKind::Tuple(_) => format_to!(result, "_{field_idx}"),
5109                        TyKind::Adt(adt_def, _) => {
5110                            let variant = match adt_def.def_id() {
5111                                AdtId::StructId(id) => VariantId::from(id),
5112                                AdtId::UnionId(id) => id.into(),
5113                                AdtId::EnumId(id) => {
5114                                    id.enum_variants(db).variants[variant_idx as usize].0.into()
5115                                }
5116                            };
5117                            let field = &variant.fields(db).fields()
5118                                [LocalFieldId::from_raw(la_arena::RawIdx::from_u32(field_idx))];
5119                            format_to!(result, "_{}", field.name.display(db, edition));
5120                        }
5121                        _ => never!("mismatching projection type"),
5122                    }
5123                }
5124                _ => never!("unexpected projection kind"),
5125            }
5126        }
5127        result
5128    }
5129
5130    pub fn display_place_source_code(&self, db: &dyn HirDatabase, edition: Edition) -> String {
5131        let mut result = self.local().name(db).display(db, edition).to_string();
5132        // We only need the derefs that have no field access after them, autoderef will do the rest.
5133        let mut last_derefs = 0;
5134        for (i, proj) in self.capture.place.projections.iter().enumerate() {
5135            match proj.kind {
5136                hir_ty::closure_analysis::ProjectionKind::Deref => last_derefs += 1,
5137                hir_ty::closure_analysis::ProjectionKind::Field { field_idx, variant_idx } => {
5138                    last_derefs = 0;
5139
5140                    let ty = self.capture.place.ty_before_projection(i);
5141                    match ty.kind() {
5142                        TyKind::Tuple(_) => format_to!(result, ".{field_idx}"),
5143                        TyKind::Adt(adt_def, _) => {
5144                            let variant = match adt_def.def_id() {
5145                                AdtId::StructId(id) => VariantId::from(id),
5146                                AdtId::UnionId(id) => id.into(),
5147                                AdtId::EnumId(id) => {
5148                                    // Can't really do that for an enum, unfortunately, so try to do something alike.
5149                                    id.enum_variants(db).variants[variant_idx as usize].0.into()
5150                                }
5151                            };
5152                            let field = &variant.fields(db).fields()
5153                                [LocalFieldId::from_raw(la_arena::RawIdx::from_u32(field_idx))];
5154                            format_to!(result, ".{}", field.name.display(db, edition));
5155                        }
5156                        _ => never!("mismatching projection type"),
5157                    }
5158                }
5159                _ => never!("unexpected projection kind"),
5160            }
5161        }
5162        result.insert_str(0, &"*".repeat(last_derefs));
5163        result
5164    }
5165
5166    pub fn ty(&self, db: &'db dyn HirDatabase) -> Type<'db> {
5167        Type::new_body(db, self.owner, self.capture.place.ty())
5168    }
5169
5170    /// The type that is stored in the closure, which is different from [`Self::ty()`], representing
5171    /// the place's type, when the capture is by ref.
5172    pub fn captured_ty(&self, db: &'db dyn HirDatabase) -> Type<'db> {
5173        Type::new_body(db, self.owner, self.capture.captured_ty(db))
5174    }
5175}
5176
5177#[derive(Clone, Copy, PartialEq, Eq)]
5178pub enum CaptureKind {
5179    SharedRef,
5180    UniqueSharedRef,
5181    MutableRef,
5182    Move,
5183}
5184
5185#[derive(Debug, Clone)]
5186pub struct CaptureUsages<'db> {
5187    parent: ExpressionStoreOwnerId,
5188    sources: &'db [hir_ty::closure_analysis::CaptureSourceStack],
5189}
5190
5191impl CaptureUsages<'_> {
5192    fn is_ref(store: &ExpressionStore, id: ExprOrPatId) -> bool {
5193        match id {
5194            ExprOrPatId::ExprId(expr) => matches!(store[expr], Expr::Ref { .. }),
5195            // FIXME: Figure out if this is correct wrt. match ergonomics.
5196            ExprOrPatId::PatId(pat) => match store[pat] {
5197                Pat::Bind { id: binding, .. } => matches!(
5198                    store[binding].mode,
5199                    BindingAnnotation::Ref | BindingAnnotation::RefMut
5200                ),
5201                _ => false,
5202            },
5203        }
5204    }
5205
5206    pub fn sources(&self, db: &dyn HirDatabase) -> Vec<CaptureUsageSource> {
5207        let (store, source_map) = ExpressionStore::with_source_map(db, self.parent);
5208        let mut result = Vec::with_capacity(self.sources.len());
5209        for source in self.sources {
5210            let source = source.final_source();
5211            let is_ref = Self::is_ref(store, source.unpack());
5212            match source.unpack() {
5213                ExprOrPatId::ExprId(expr) => {
5214                    if let Ok(expr) = source_map.expr_syntax(expr) {
5215                        result.push(CaptureUsageSource { is_ref, source: expr })
5216                    }
5217                }
5218                ExprOrPatId::PatId(pat) => {
5219                    if let Ok(pat) = source_map.pat_syntax(pat) {
5220                        result.push(CaptureUsageSource { is_ref, source: pat });
5221                    }
5222                }
5223            }
5224        }
5225        result
5226    }
5227}
5228
5229#[derive(Debug)]
5230pub struct CaptureUsageSource {
5231    is_ref: bool,
5232    source: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
5233}
5234
5235impl CaptureUsageSource {
5236    pub fn source(&self) -> AstPtr<Either<ast::Expr, ast::Pat>> {
5237        self.source.value
5238    }
5239
5240    pub fn file_id(&self) -> HirFileId {
5241        self.source.file_id
5242    }
5243
5244    pub fn is_ref(&self) -> bool {
5245        self.is_ref
5246    }
5247}
5248
5249#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
5250enum TypeOwnerId<'db> {
5251    GenericDefId(GenericDefId),
5252    BuiltinDeriveImplId(BuiltinDeriveImplId),
5253    AnonConstId(AnonConstId<'db>),
5254    // FIXME: What do when we unify two different crates? Currently we just randomly keep one.
5255    NoParams(base_db::Crate),
5256}
5257
5258impl_from!(
5259    impl<'db>
5260    GenericDefId,
5261    BuiltinDeriveImplId,
5262    AnonConstId<'db>
5263    for TypeOwnerId<'db>
5264);
5265
5266impl TypeOwnerId<'_> {
5267    fn unify(self, other: Self) -> Option<Self> {
5268        match (self, other) {
5269            (TypeOwnerId::NoParams(_), owner) => Some(owner),
5270            (owner, TypeOwnerId::NoParams(_)) => Some(owner),
5271            (_, _) => {
5272                if self == other {
5273                    Some(self)
5274                } else {
5275                    None
5276                }
5277            }
5278        }
5279    }
5280
5281    #[track_caller]
5282    fn must_unify(self, other: Self) -> Self {
5283        self.unify(other).expect("failed to unify type owners")
5284    }
5285
5286    fn can_rebase_into(
5287        self,
5288        db: &dyn HirDatabase,
5289        rebase_into: Self,
5290        self_ty: EarlyBinder<'_, Ty<'_>>,
5291    ) -> bool {
5292        if self == rebase_into || !self_ty.skip_binder().has_param() {
5293            return true;
5294        }
5295        let self_def = match self {
5296            TypeOwnerId::GenericDefId(def) => def,
5297            TypeOwnerId::BuiltinDeriveImplId(_) | TypeOwnerId::AnonConstId(_) => return false,
5298            TypeOwnerId::NoParams(_) => return true,
5299        };
5300        let self_def = match self_def {
5301            GenericDefId::ImplId(def) => ItemContainerId::ImplId(def),
5302            GenericDefId::TraitId(def) => ItemContainerId::TraitId(def),
5303            GenericDefId::AdtId(_)
5304            | GenericDefId::ConstId(_)
5305            | GenericDefId::FunctionId(_)
5306            | GenericDefId::StaticId(_)
5307            | GenericDefId::TypeAliasId(_) => return false,
5308        };
5309        let rebase_into_def = match rebase_into {
5310            TypeOwnerId::GenericDefId(def) => def,
5311            TypeOwnerId::BuiltinDeriveImplId(_)
5312            | TypeOwnerId::AnonConstId(_)
5313            | TypeOwnerId::NoParams(_) => return false,
5314        };
5315        let rebase_into_parent = match rebase_into_def {
5316            GenericDefId::ConstId(def) => def.loc(db).container,
5317            GenericDefId::FunctionId(def) => def.loc(db).container,
5318            GenericDefId::TypeAliasId(def) => def.loc(db).container,
5319            GenericDefId::AdtId(_)
5320            | GenericDefId::ImplId(_)
5321            | GenericDefId::StaticId(_)
5322            | GenericDefId::TraitId(_) => return false,
5323        };
5324        self_def == rebase_into_parent
5325    }
5326}
5327
5328/// Note: A [`Type`] remembers its origin. Trying to do anything (except comparing)
5329/// with types of different origins will cause errors or panics. Instead, use the `instantiate` methods.
5330#[derive(Clone, Debug)]
5331pub struct Type<'db> {
5332    owner: TypeOwnerId<'db>,
5333    ty: EarlyBinder<'db, Ty<'db>>,
5334}
5335
5336impl<'db> std::hash::Hash for Type<'db> {
5337    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
5338        // Do not hash the owner as different owners can compare the same.
5339        // self.owner.hash(state);
5340        self.ty.hash(state);
5341    }
5342}
5343
5344impl<'db> PartialEq for Type<'db> {
5345    fn eq(&self, other: &Self) -> bool {
5346        if self.ty != other.ty {
5347            return false;
5348        }
5349        hir_ty::with_attached_db(|db| {
5350            self.owner.can_rebase_into(db, other.owner, self.ty)
5351                || other.owner.can_rebase_into(db, self.owner, other.ty)
5352        })
5353    }
5354}
5355
5356impl<'db> Eq for Type<'db> {}
5357
5358impl<'db> Type<'db> {
5359    fn new(owner: GenericDefId, ty: Ty<'db>) -> Self {
5360        Type { owner: TypeOwnerId::GenericDefId(owner), ty: EarlyBinder::bind(ty) }
5361    }
5362
5363    fn new_body(db: &dyn HirDatabase, owner: ExpressionStoreOwnerId, ty: Ty<'db>) -> Self {
5364        Self::new(owner.generic_def(db), ty)
5365    }
5366
5367    fn no_params(krate: base_db::Crate, ty: Ty<'db>) -> Self {
5368        Type { owner: TypeOwnerId::NoParams(krate), ty: EarlyBinder::bind(ty) }
5369    }
5370
5371    fn builtin_type_crate(db: &'db dyn HirDatabase) -> base_db::Crate {
5372        // It doesn't really matter.
5373        all_crates(db)[0]
5374    }
5375
5376    fn from_def(db: &'db dyn HirDatabase, def: impl Into<TyDefId>) -> Self {
5377        let def = def.into();
5378        let ty = db.ty(def);
5379        let owner = match def {
5380            TyDefId::AdtId(it) => TypeOwnerId::GenericDefId(GenericDefId::AdtId(it)),
5381            TyDefId::TypeAliasId(it) => TypeOwnerId::GenericDefId(GenericDefId::TypeAliasId(it)),
5382            TyDefId::BuiltinType(_) => TypeOwnerId::NoParams(Self::builtin_type_crate(db)),
5383        };
5384        Type { owner, ty }
5385    }
5386
5387    fn from_value_def(db: &'db dyn HirDatabase, def: impl Into<ValueTyDefId>) -> Self {
5388        let def = def.into();
5389        let Some(ty) = db.value_ty(def) else {
5390            return Type::unknown();
5391        };
5392        let def = match def {
5393            ValueTyDefId::ConstId(it) => GenericDefId::ConstId(it),
5394            ValueTyDefId::FunctionId(it) => GenericDefId::FunctionId(it),
5395            ValueTyDefId::StructId(it) => GenericDefId::AdtId(AdtId::StructId(it)),
5396            ValueTyDefId::UnionId(it) => GenericDefId::AdtId(AdtId::UnionId(it)),
5397            ValueTyDefId::EnumVariantId(it) => {
5398                GenericDefId::AdtId(AdtId::EnumId(it.lookup(db).parent))
5399            }
5400            ValueTyDefId::StaticId(it) => {
5401                return Type::no_params(hir_def::HasModule::krate(&it, db), ty.skip_binder());
5402            }
5403        };
5404        Type::new(def, ty.instantiate_identity().skip_norm_wip())
5405    }
5406
5407    /// Replace any generic parameters with error types.
5408    pub fn instantiate_with_errors(&self) -> Self {
5409        let interner = DbInterner::conjure();
5410        let krate = self.krate(interner.db());
5411        let args = match self.owner {
5412            TypeOwnerId::GenericDefId(def) => GenericArgs::error_for_item(interner, def.into()),
5413            TypeOwnerId::BuiltinDeriveImplId(def) => {
5414                GenericArgs::error_for_item(interner, def.into())
5415            }
5416            TypeOwnerId::AnonConstId(def) => GenericArgs::error_for_item(interner, def.into()),
5417            TypeOwnerId::NoParams(_) => GenericArgs::empty(interner),
5418        };
5419        Type::no_params(krate, self.ty.instantiate(interner, args).skip_norm_wip())
5420    }
5421
5422    // FIXME: Find some way with const params, maybe even lifetimes?
5423    pub fn instantiate(&self, args: impl IntoIterator<Item: Borrow<Type<'db>>>) -> Type<'db> {
5424        let interner = DbInterner::conjure();
5425        let (args, owner) = match self.owner {
5426            TypeOwnerId::GenericDefId(def) => generic_args_from_tys(interner, def.into(), args),
5427            TypeOwnerId::BuiltinDeriveImplId(def) => {
5428                generic_args_from_tys(interner, def.into(), args)
5429            }
5430            TypeOwnerId::AnonConstId(def) => generic_args_from_tys(interner, def.into(), args),
5431            TypeOwnerId::NoParams(krate) => {
5432                (GenericArgs::empty(interner), TypeOwnerId::NoParams(krate))
5433            }
5434        };
5435        Type { owner, ty: EarlyBinder::bind(self.ty.instantiate(interner, args).skip_norm_wip()) }
5436    }
5437
5438    /// Instantiates multiple types with infer vars, keeping the same infer vars for the same owners.
5439    fn instantiate_many_with_infer(
5440        tys: impl IntoIterator<Item: Borrow<Type<'db>>>,
5441        infcx: &InferCtxt<'db>,
5442    ) -> impl Iterator<Item = Ty<'db>> {
5443        let mut var_for_param = FxHashMap::default();
5444        tys.into_iter().map(move |ty| {
5445            let ty = ty.borrow();
5446            let owner = match ty.owner {
5447                TypeOwnerId::GenericDefId(def) => def.into(),
5448                TypeOwnerId::BuiltinDeriveImplId(def) => def.into(),
5449                TypeOwnerId::AnonConstId(def) => def.into(),
5450                TypeOwnerId::NoParams(_) => return ty.ty.skip_binder(),
5451            };
5452            let args = GenericArgs::for_item(infcx.interner, owner, |_, param, _, _| {
5453                *var_for_param
5454                    .entry(param)
5455                    .or_insert_with(|| infcx.var_for_def(param, hir_ty::Span::Dummy))
5456            });
5457
5458            ty.ty.instantiate(infcx.interner, args).skip_norm_wip()
5459        })
5460    }
5461
5462    /// Tries to put this type as-is in the context of `rebase_into`. This will return `Some(_)` if:
5463    ///
5464    ///  - The type does not reference generic parameters, or
5465    ///  - `rebase_into` is in the context of a child of our context (for example, a function in an impl).
5466    pub fn try_rebase_into(
5467        &self,
5468        db: &'db dyn HirDatabase,
5469        rebase_into: &Type<'db>,
5470    ) -> Option<Self> {
5471        if self.owner.can_rebase_into(db, rebase_into.owner, self.ty) {
5472            Some(Type { owner: rebase_into.owner, ty: self.ty })
5473        } else {
5474            None
5475        }
5476    }
5477
5478    /// If `self` can be rebased into `rebase_into`, returns that. Otherwise, instantiates `self` with errors
5479    /// and returns that.
5480    pub fn rebase_into_or_error(
5481        &self,
5482        db: &'db dyn HirDatabase,
5483        rebase_into: &Type<'db>,
5484    ) -> Type<'db> {
5485        self.try_rebase_into(db, rebase_into).unwrap_or_else(|| self.instantiate_with_errors())
5486    }
5487
5488    pub fn try_rebase_into_owner(
5489        &self,
5490        db: &'db dyn HirDatabase,
5491        new_owner: GenericDef,
5492    ) -> Option<Self> {
5493        let new_owner = new_owner.id()?.into();
5494        if self.owner.can_rebase_into(db, new_owner, self.ty) {
5495            Some(Type { owner: new_owner, ty: self.ty })
5496        } else {
5497            None
5498        }
5499    }
5500
5501    pub fn rebase_into_owner_or_error(
5502        &self,
5503        db: &'db dyn HirDatabase,
5504        new_owner: GenericDef,
5505    ) -> Self {
5506        self.try_rebase_into_owner(db, new_owner).unwrap_or_else(|| self.instantiate_with_errors())
5507    }
5508
5509    pub fn unknown() -> Self {
5510        let interner = DbInterner::conjure();
5511        Type::no_params(
5512            Self::builtin_type_crate(interner.db()),
5513            Ty::new_error(interner, ErrorGuaranteed),
5514        )
5515    }
5516
5517    pub fn new_slice(db: &'db dyn HirDatabase, ty: Self) -> Self {
5518        let interner = DbInterner::new_no_crate(db);
5519        Type { owner: ty.owner, ty: ty.ty.map_bound(|ty| Ty::new_slice(interner, ty)) }
5520    }
5521
5522    pub fn new_tuple(
5523        db: &'db dyn HirDatabase,
5524        tys: impl IntoIterator<Item: Borrow<Type<'db>>>,
5525    ) -> Self {
5526        let interner = DbInterner::new_no_crate(db);
5527        let mut owner = None::<TypeOwnerId<'db>>;
5528        let ty = EarlyBinder::bind(Ty::new_tup_from_iter(
5529            interner,
5530            tys.into_iter().map(|ty| {
5531                let ty = ty.borrow();
5532
5533                match &mut owner {
5534                    Some(owner) => *owner = owner.must_unify(ty.owner),
5535                    None => owner = Some(ty.owner),
5536                }
5537
5538                ty.ty.skip_binder()
5539            }),
5540        ));
5541        let owner =
5542            owner.unwrap_or_else(|| TypeOwnerId::NoParams(Self::builtin_type_crate(interner.db())));
5543        Type { owner, ty }
5544    }
5545
5546    pub fn new_unit() -> Self {
5547        let interner = DbInterner::conjure();
5548        Type::no_params(Self::builtin_type_crate(interner.db()), Ty::new_unit(interner))
5549    }
5550
5551    pub fn is_unit(&self) -> bool {
5552        self.ty.skip_binder().is_unit()
5553    }
5554
5555    pub fn is_bool(&self) -> bool {
5556        matches!(self.ty.skip_binder().kind(), TyKind::Bool)
5557    }
5558
5559    pub fn is_str(&self) -> bool {
5560        matches!(self.ty.skip_binder().kind(), TyKind::Str)
5561    }
5562
5563    pub fn is_never(&self) -> bool {
5564        matches!(self.ty.skip_binder().kind(), TyKind::Never)
5565    }
5566
5567    pub fn is_mutable_reference(&self) -> bool {
5568        matches!(
5569            self.ty.skip_binder().kind(),
5570            TyKind::Ref(.., hir_ty::next_solver::Mutability::Mut)
5571        )
5572    }
5573
5574    pub fn is_reference(&self) -> bool {
5575        matches!(self.ty.skip_binder().kind(), TyKind::Ref(..))
5576    }
5577
5578    pub fn contains_reference(&self, db: &'db dyn HirDatabase) -> bool {
5579        let interner = DbInterner::new_no_crate(db);
5580        return self
5581            .ty
5582            .instantiate_identity()
5583            .skip_norm_wip()
5584            .visit_with(&mut Visitor { interner })
5585            .is_break();
5586
5587        fn is_phantom_data(db: &dyn HirDatabase, adt_id: AdtId) -> bool {
5588            match adt_id {
5589                AdtId::StructId(s) => {
5590                    let flags = StructSignature::of(db, s).flags;
5591                    flags.contains(StructFlags::IS_PHANTOM_DATA)
5592                }
5593                AdtId::UnionId(_) | AdtId::EnumId(_) => false,
5594            }
5595        }
5596
5597        struct Visitor<'db> {
5598            interner: DbInterner<'db>,
5599        }
5600
5601        impl<'db> TypeVisitor<DbInterner<'db>> for Visitor<'db> {
5602            type Result = ControlFlow<()>;
5603
5604            fn visit_ty(&mut self, ty: Ty<'db>) -> Self::Result {
5605                match ty.kind() {
5606                    // Reference itself
5607                    TyKind::Ref(..) => ControlFlow::Break(()),
5608
5609                    // For non-phantom_data adts we check variants/fields as well as generic parameters
5610                    TyKind::Adt(adt_def, args)
5611                        if !is_phantom_data(self.interner.db(), adt_def.def_id()) =>
5612                    {
5613                        let _variant_id_to_fields = |id: VariantId| {
5614                            let variant_data = &id.fields(self.interner.db());
5615                            if variant_data.fields().is_empty() {
5616                                vec![]
5617                            } else {
5618                                let field_types = self.interner.db().field_types(id);
5619                                variant_data
5620                                    .fields()
5621                                    .iter()
5622                                    .map(|(idx, _)| {
5623                                        field_types[idx]
5624                                            .ty()
5625                                            .instantiate(self.interner, args)
5626                                            .skip_norm_wip()
5627                                    })
5628                                    .filter(|it| !it.references_non_lt_error())
5629                                    .collect()
5630                            }
5631                        };
5632                        let variant_id_to_fields = |_: VariantId| vec![];
5633
5634                        let variants: Vec<Vec<Ty<'db>>> = match adt_def.def_id() {
5635                            AdtId::StructId(id) => {
5636                                vec![variant_id_to_fields(id.into())]
5637                            }
5638                            AdtId::EnumId(id) => id
5639                                .enum_variants(self.interner.db())
5640                                .variants
5641                                .values()
5642                                .map(|&(variant_id, _)| variant_id_to_fields(variant_id.into()))
5643                                .collect(),
5644                            AdtId::UnionId(id) => {
5645                                vec![variant_id_to_fields(id.into())]
5646                            }
5647                        };
5648
5649                        variants
5650                            .into_iter()
5651                            .flat_map(|variant| variant.into_iter())
5652                            .try_for_each(|ty| ty.visit_with(self))?;
5653                        args.visit_with(self)
5654                    }
5655                    // And for `PhantomData<T>`, we check `T`.
5656                    _ => ty.super_visit_with(self),
5657                }
5658            }
5659        }
5660    }
5661
5662    pub fn as_reference(&self) -> Option<(Type<'db>, Mutability)> {
5663        let TyKind::Ref(_lt, ty, m) = self.ty.skip_binder().kind() else { return None };
5664        let m = Mutability::from_mutable(matches!(m, hir_ty::next_solver::Mutability::Mut));
5665        Some((self.derived(ty), m))
5666    }
5667
5668    pub fn as_reference_inner(&self) -> Option<Type<'db>> {
5669        self.as_reference().map(|(inner, _)| inner)
5670    }
5671
5672    pub fn add_reference(&self, db: &'db dyn HirDatabase, mutability: Mutability) -> Self {
5673        let interner = DbInterner::new_no_crate(db);
5674        let ty_mutability = match mutability {
5675            Mutability::Shared => hir_ty::next_solver::Mutability::Not,
5676            Mutability::Mut => hir_ty::next_solver::Mutability::Mut,
5677        };
5678        self.derived(Ty::new_ref(
5679            interner,
5680            Region::error(interner),
5681            self.ty.skip_binder(),
5682            ty_mutability,
5683        ))
5684    }
5685
5686    pub fn is_slice(&self) -> bool {
5687        matches!(self.ty.skip_binder().kind(), TyKind::Slice(..))
5688    }
5689
5690    pub fn is_usize(&self) -> bool {
5691        matches!(self.ty.skip_binder().kind(), TyKind::Uint(rustc_type_ir::UintTy::Usize))
5692    }
5693
5694    pub fn is_float(&self) -> bool {
5695        matches!(self.ty.skip_binder().kind(), TyKind::Float(_))
5696    }
5697
5698    pub fn is_char(&self) -> bool {
5699        matches!(self.ty.skip_binder().kind(), TyKind::Char)
5700    }
5701
5702    pub fn is_int_or_uint(&self) -> bool {
5703        matches!(self.ty.skip_binder().kind(), TyKind::Int(_) | TyKind::Uint(_))
5704    }
5705
5706    pub fn is_scalar(&self) -> bool {
5707        matches!(
5708            self.ty.skip_binder().kind(),
5709            TyKind::Bool | TyKind::Char | TyKind::Int(_) | TyKind::Uint(_) | TyKind::Float(_)
5710        )
5711    }
5712
5713    pub fn is_tuple(&self) -> bool {
5714        matches!(self.ty.skip_binder().kind(), TyKind::Tuple(..))
5715    }
5716
5717    pub fn as_slice(&self) -> Option<Type<'db>> {
5718        match self.ty.skip_binder().kind() {
5719            TyKind::Slice(ty) => Some(self.derived(ty)),
5720            _ => None,
5721        }
5722    }
5723
5724    pub fn strip_references(&self) -> Self {
5725        self.derived(self.ty.skip_binder().strip_references())
5726    }
5727
5728    // FIXME: This is the same as `remove_ref()`, remove one of these methods.
5729    pub fn strip_reference(&self) -> Self {
5730        self.derived(self.ty.skip_binder().strip_reference())
5731    }
5732
5733    pub fn is_unknown(&self) -> bool {
5734        self.ty.skip_binder().is_ty_error()
5735    }
5736
5737    fn krate(&self, db: &'db dyn HirDatabase) -> base_db::Crate {
5738        match self.owner {
5739            TypeOwnerId::GenericDefId(def) => hir_def::HasModule::krate(&def, db),
5740            TypeOwnerId::BuiltinDeriveImplId(def) => {
5741                hir_def::HasModule::krate(&def.loc(db).adt, db)
5742            }
5743            TypeOwnerId::AnonConstId(def) => hir_def::HasModule::krate(&def, db),
5744            TypeOwnerId::NoParams(krate) => krate,
5745        }
5746    }
5747
5748    fn param_env(&self, db: &'db dyn HirDatabase) -> ParamEnvAndCrate<'db> {
5749        let interner = DbInterner::new_no_crate(db);
5750        let krate = self.krate(db);
5751        match self.owner {
5752            TypeOwnerId::GenericDefId(def) => {
5753                ParamEnvAndCrate { param_env: db.trait_environment(def), krate }
5754            }
5755            TypeOwnerId::BuiltinDeriveImplId(def) => ParamEnvAndCrate {
5756                param_env: hir_ty::builtin_derive::param_env(interner, def),
5757                krate,
5758            },
5759            TypeOwnerId::AnonConstId(def) => ParamEnvAndCrate {
5760                param_env: db.trait_environment(def.loc(db).owner.generic_def(db)),
5761                krate,
5762            },
5763            TypeOwnerId::NoParams(_) => {
5764                ParamEnvAndCrate { param_env: ParamEnv::empty(interner), krate }
5765            }
5766        }
5767    }
5768
5769    /// Checks that particular type `ty` implements `std::future::IntoFuture` or
5770    /// `std::future::Future` and returns the `Output` associated type.
5771    /// This function is used in `.await` syntax completion.
5772    pub fn into_future_output(&self, db: &'db dyn HirDatabase) -> Option<Type<'db>> {
5773        let env = self.param_env(db);
5774        let lang_items = hir_def::lang_item::lang_items(db, env.krate);
5775        let (trait_, output_assoc_type) = lang_items
5776            .IntoFuture
5777            .zip(lang_items.IntoFutureOutput)
5778            .or(lang_items.Future.zip(lang_items.FutureOutput))?;
5779
5780        if !traits::implements_trait_unique(
5781            self.ty.instantiate_identity().skip_norm_wip(),
5782            db,
5783            env,
5784            trait_,
5785        ) {
5786            return None;
5787        }
5788
5789        self.normalize_trait_assoc_type(db, &[], output_assoc_type.into())
5790    }
5791
5792    /// This does **not** resolve `IntoFuture`, only `Future`.
5793    pub fn future_output(self, db: &'db dyn HirDatabase) -> Option<Type<'db>> {
5794        let krate = self.krate(db);
5795        let lang_items = hir_def::lang_item::lang_items(db, krate);
5796        let future_output = lang_items.FutureOutput?;
5797        self.normalize_trait_assoc_type(db, &[], future_output.into())
5798    }
5799
5800    /// This does **not** resolve `IntoIterator`, only `Iterator`.
5801    pub fn iterator_item(self, db: &'db dyn HirDatabase) -> Option<Type<'db>> {
5802        let krate = self.krate(db);
5803        let lang_items = hir_def::lang_item::lang_items(db, krate);
5804        let iterator_item = lang_items.IteratorItem?;
5805        self.normalize_trait_assoc_type(db, &[], iterator_item.into())
5806    }
5807
5808    pub fn impls_iterator(self, db: &'db dyn HirDatabase) -> bool {
5809        let env = self.param_env(db);
5810        let lang_items = hir_def::lang_item::lang_items(db, env.krate);
5811        let Some(iterator_trait) = lang_items.Iterator else {
5812            return false;
5813        };
5814        traits::implements_trait_unique(
5815            self.ty.instantiate_identity().skip_norm_wip(),
5816            db,
5817            env,
5818            iterator_trait,
5819        )
5820    }
5821
5822    /// Resolves the projection `<Self as IntoIterator>::IntoIter` and returns the resulting type
5823    pub fn into_iterator_iter(self, db: &'db dyn HirDatabase) -> Option<Type<'db>> {
5824        let env = self.param_env(db);
5825        let lang_items = hir_def::lang_item::lang_items(db, env.krate);
5826        let trait_ = lang_items.IntoIterator?;
5827
5828        if !traits::implements_trait_unique(
5829            self.ty.instantiate_identity().skip_norm_wip(),
5830            db,
5831            env,
5832            trait_,
5833        ) {
5834            return None;
5835        }
5836
5837        let into_iter_assoc_type = lang_items.IntoIterIntoIterType?;
5838        self.normalize_trait_assoc_type(db, &[], into_iter_assoc_type.into())
5839    }
5840
5841    /// Checks that particular type `ty` implements `std::ops::FnOnce`.
5842    ///
5843    /// This function can be used to check if a particular type is callable, since FnOnce is a
5844    /// supertrait of Fn and FnMut, so all callable types implements at least FnOnce.
5845    pub fn impls_fnonce(&self, db: &'db dyn HirDatabase) -> bool {
5846        let env = self.param_env(db);
5847        let lang_items = hir_def::lang_item::lang_items(db, env.krate);
5848        let fnonce_trait = match lang_items.FnOnce {
5849            Some(it) => it,
5850            None => return false,
5851        };
5852
5853        traits::implements_trait_unique(
5854            self.ty.instantiate_identity().skip_norm_wip(),
5855            db,
5856            env,
5857            fnonce_trait,
5858        )
5859    }
5860
5861    // FIXME: Find better API that also handles const generics
5862    pub fn impls_trait(&self, db: &'db dyn HirDatabase, trait_: Trait, args: &[Type<'db>]) -> bool {
5863        let env = self.param_env(db);
5864        let interner = DbInterner::new_no_crate(db);
5865        let (args, _owner) =
5866            generic_args_from_tys(interner, trait_.id.into(), iter::once(self).chain(args));
5867        traits::implements_trait_unique_with_args(db, env, trait_.id, args)
5868    }
5869
5870    /// Unlike [`Type::impls_trait()`], which checks whether the type always implements the trait,
5871    /// this check whether there are any generic args substitution for `args`` that will cause the
5872    /// trait to be implemented.
5873    ///
5874    /// For example, suppose we're there's `struct Foo<T>` and we're checking `Foo<T>: Trait`.
5875    /// `impls_trait()` will return true only if there is `impl<T> Trait for Foo<T>`, while this
5876    /// method will also return true if there is only `impl Trait for Foo<i32>`.
5877    ///
5878    /// Note that you can of course instantiate `Foo<T>` with `<i32>` and then the checks will
5879    /// be the same, but this check for *any* substitution.
5880    ///
5881    /// Unlike almost anything that takes more than one type, you *can* pass types from different origins
5882    /// to this function.
5883    pub fn has_any_impl(
5884        &self,
5885        db: &'db dyn HirDatabase,
5886        trait_: Trait,
5887        args: &[Type<'db>],
5888    ) -> bool {
5889        let interner = DbInterner::new_no_crate(db);
5890        let env = ParamEnvAndCrate { param_env: ParamEnv::empty(interner), krate: self.krate(db) };
5891        traits::implements_trait_unique_with_infcx(db, env, trait_.id, &mut |infcx| {
5892            let mut args = Self::instantiate_many_with_infer(iter::once(self).chain(args), infcx);
5893            GenericArgs::for_item(infcx.interner, trait_.id.into(), |_, param, _, _| {
5894                if let GenericParamId::TypeParamId(_) = param
5895                    && let Some(arg) = args.next()
5896                {
5897                    arg.into()
5898                } else {
5899                    infcx.var_for_def(param, hir_ty::Span::Dummy)
5900                }
5901            })
5902        })
5903    }
5904
5905    pub fn normalize_trait_assoc_type(
5906        &self,
5907        db: &'db dyn HirDatabase,
5908        args: &[Type<'db>],
5909        alias: TypeAlias,
5910    ) -> Option<Type<'db>> {
5911        let env = self.param_env(db);
5912        let interner = DbInterner::new_with(db, env.krate);
5913        let (args, owner) =
5914            generic_args_from_tys(interner, alias.id.into(), iter::once(self).chain(args));
5915        // FIXME: We don't handle GATs yet.
5916        let projection = Ty::new_alias(
5917            interner,
5918            AliasTy::new_from_args(
5919                interner,
5920                AliasTyKind::Projection { def_id: alias.id.into() },
5921                args,
5922            ),
5923        );
5924
5925        let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
5926        let ty = structurally_normalize_ty(&infcx, projection, env.param_env);
5927        if ty.is_ty_error() { None } else { Some(Type { owner, ty: EarlyBinder::bind(ty) }) }
5928    }
5929
5930    pub fn is_copy(&self, db: &'db dyn HirDatabase) -> bool {
5931        let env = self.param_env(db);
5932        let lang_items = hir_def::lang_item::lang_items(db, env.krate);
5933        let Some(copy_trait) = lang_items.Copy else {
5934            return false;
5935        };
5936        self.impls_trait(db, copy_trait.into(), &[])
5937    }
5938
5939    pub fn as_callable(&self, db: &'db dyn HirDatabase) -> Option<Callable<'db>> {
5940        let interner = DbInterner::new_no_crate(db);
5941        let callee = match self.ty.skip_binder().kind() {
5942            TyKind::Closure(id, subst) => Callee::Closure(id.0, subst),
5943            TyKind::CoroutineClosure(id, subst) => Callee::CoroutineClosure(id.0, subst),
5944            TyKind::FnPtr(..) => Callee::FnPtr,
5945            TyKind::FnDef(id, _) => Callee::Def(id.0),
5946            // This will happen when it implements fn or fn mut, since we add an autoborrow adjustment
5947            TyKind::Ref(_, inner_ty, _) => return self.derived(inner_ty).as_callable(db),
5948            _ => {
5949                let env = self.param_env(db);
5950                let (fn_trait, sig) =
5951                    hir_ty::callable_sig_from_fn_trait(self.ty.skip_binder(), env, db)?;
5952                return Some(Callable {
5953                    ty: self.clone(),
5954                    sig,
5955                    callee: Callee::FnImpl(fn_trait),
5956                    is_bound_method: false,
5957                });
5958            }
5959        };
5960
5961        let sig = self.ty.skip_binder().callable_sig(interner)?;
5962        Some(Callable { ty: self.clone(), sig, callee, is_bound_method: false })
5963    }
5964
5965    pub fn is_closure(&self) -> bool {
5966        matches!(self.ty.skip_binder().kind(), TyKind::Closure { .. })
5967    }
5968
5969    pub fn as_closure(&self) -> Option<Closure<'db>> {
5970        match self.ty.skip_binder().kind() {
5971            TyKind::Closure(id, subst) => {
5972                Some(Closure { id: AnyClosureId::ClosureId(id.0), subst, owner: self.owner })
5973            }
5974            TyKind::CoroutineClosure(id, subst) => Some(Closure {
5975                id: AnyClosureId::CoroutineClosureId(id.0),
5976                subst,
5977                owner: self.owner,
5978            }),
5979            _ => None,
5980        }
5981    }
5982
5983    /// Returns this type as a coroutine.
5984    pub fn as_coroutine(&self) -> Option<Coroutine<'db>> {
5985        match self.ty.skip_binder().kind() {
5986            TyKind::Coroutine(id, _) => Some(Coroutine { id: id.0 }),
5987            _ => None,
5988        }
5989    }
5990
5991    pub fn is_fn(&self) -> bool {
5992        matches!(self.ty.skip_binder().kind(), TyKind::FnDef(..) | TyKind::FnPtr { .. })
5993    }
5994
5995    pub fn is_array(&self) -> bool {
5996        matches!(self.ty.skip_binder().kind(), TyKind::Array(..))
5997    }
5998
5999    pub fn is_packed(&self, _db: &'db dyn HirDatabase) -> bool {
6000        match self.ty.skip_binder().kind() {
6001            TyKind::Adt(adt_def, ..) => adt_def.is_packed(),
6002            _ => false,
6003        }
6004    }
6005
6006    pub fn is_raw_ptr(&self) -> bool {
6007        matches!(self.ty.skip_binder().kind(), TyKind::RawPtr(..))
6008    }
6009
6010    pub fn is_mutable_raw_ptr(&self) -> bool {
6011        // Used outside of rust-analyzer (e.g. by `ra_ap_hir` consumers).
6012        matches!(
6013            self.ty.skip_binder().kind(),
6014            TyKind::RawPtr(.., hir_ty::next_solver::Mutability::Mut)
6015        )
6016    }
6017
6018    pub fn as_raw_ptr(&self) -> Option<(Type<'db>, Mutability)> {
6019        // Used outside of rust-analyzer (e.g. by `ra_ap_hir` consumers).
6020        let TyKind::RawPtr(ty, m) = self.ty.skip_binder().kind() else { return None };
6021        let m = Mutability::from_mutable(matches!(m, hir_ty::next_solver::Mutability::Mut));
6022        Some((self.derived(ty), m))
6023    }
6024
6025    pub fn remove_raw_ptr(&self) -> Option<Type<'db>> {
6026        if let TyKind::RawPtr(ty, _) = self.ty.skip_binder().kind() {
6027            Some(self.derived(ty))
6028        } else {
6029            None
6030        }
6031    }
6032
6033    pub fn contains_unknown(&self) -> bool {
6034        self.ty.skip_binder().references_non_lt_error()
6035    }
6036
6037    pub fn fields(&self, db: &'db dyn HirDatabase) -> Vec<(Field, Self)> {
6038        let interner = DbInterner::new_no_crate(db);
6039        let (variant_id, substs) = match self.ty.skip_binder().kind() {
6040            TyKind::Adt(adt_def, substs) => {
6041                let id = match adt_def.def_id() {
6042                    AdtId::StructId(id) => id.into(),
6043                    AdtId::UnionId(id) => id.into(),
6044                    AdtId::EnumId(_) => return Vec::new(),
6045                };
6046                (id, substs)
6047            }
6048            _ => return Vec::new(),
6049        };
6050
6051        db.field_types(variant_id)
6052            .iter()
6053            .map(|(local_id, field)| {
6054                let def = Field { parent: variant_id.into(), id: local_id };
6055                let ty = field.ty().instantiate(interner, substs).skip_norm_wip();
6056                (def, self.derived(ty))
6057            })
6058            .collect()
6059    }
6060
6061    pub fn tuple_fields(&self, _db: &'db dyn HirDatabase) -> Vec<Self> {
6062        if let TyKind::Tuple(substs) = self.ty.skip_binder().kind() {
6063            substs.iter().map(|ty| self.derived(ty)).collect()
6064        } else {
6065            Vec::new()
6066        }
6067    }
6068
6069    pub fn as_array(&self, db: &'db dyn HirDatabase) -> Option<(Self, usize)> {
6070        if let TyKind::Array(ty, len) = self.ty.skip_binder().kind() {
6071            try_const_usize(db, len).map(|it| (self.derived(ty), it as usize))
6072        } else {
6073            None
6074        }
6075    }
6076
6077    // FIXME: We should probably remove this.
6078    pub fn fingerprint_for_trait_impl(
6079        &self,
6080        db: &'db dyn HirDatabase,
6081    ) -> Option<SimplifiedType<'db>> {
6082        fast_reject::simplify_type(
6083            DbInterner::new_no_crate(db),
6084            self.ty.skip_binder(),
6085            fast_reject::TreatParams::AsRigid,
6086        )
6087    }
6088
6089    /// Returns types that this type dereferences to (including this type itself). The returned
6090    /// iterator won't yield the same type more than once even if the deref chain contains a cycle.
6091    pub fn autoderef(
6092        &self,
6093        db: &'db dyn HirDatabase,
6094    ) -> impl Iterator<Item = Type<'db>> + use<'_, 'db> {
6095        self.autoderef_(db).map(move |ty| self.derived(ty))
6096    }
6097
6098    fn autoderef_(&self, db: &'db dyn HirDatabase) -> impl Iterator<Item = Ty<'db>> {
6099        let interner = DbInterner::new_no_crate(db);
6100        let env = self.param_env(db);
6101        // There should be no inference vars in types passed here
6102        let canonical = hir_ty::replace_errors_with_variables(interner, &self.ty.skip_binder());
6103        autoderef(db, env, canonical)
6104    }
6105
6106    // This would be nicer if it just returned an iterator, but that runs into
6107    // lifetime problems, because we need to borrow temp `CrateImplDefs`.
6108    pub fn iterate_assoc_items<T>(
6109        &self,
6110        db: &'db dyn HirDatabase,
6111        mut callback: impl FnMut(AssocItem) -> Option<T>,
6112    ) -> Option<T> {
6113        let mut slot = None;
6114        self.iterate_assoc_items_dyn(db, &mut |assoc_item_id| {
6115            slot = callback(assoc_item_id.into());
6116            slot.is_some()
6117        });
6118        slot
6119    }
6120
6121    fn iterate_assoc_items_dyn(
6122        &self,
6123        db: &'db dyn HirDatabase,
6124        callback: &mut dyn FnMut(AssocItemId) -> bool,
6125    ) {
6126        let mut handle_impls = |impls: &[ImplId]| {
6127            for &impl_def in impls {
6128                for &(_, item) in impl_def.impl_items(db).items.iter() {
6129                    if callback(item) {
6130                        return;
6131                    }
6132                }
6133            }
6134        };
6135        let krate = self.krate(db);
6136
6137        let interner = DbInterner::new_no_crate(db);
6138        let Some(simplified_type) = fast_reject::simplify_type(
6139            interner,
6140            self.ty.skip_binder(),
6141            fast_reject::TreatParams::AsRigid,
6142        ) else {
6143            return;
6144        };
6145
6146        method_resolution::with_incoherent_inherent_impls(
6147            db,
6148            krate,
6149            &simplified_type,
6150            &mut handle_impls,
6151        );
6152
6153        if let Some(module) = method_resolution::simplified_type_module(db, &simplified_type) {
6154            InherentImpls::for_each_crate_and_block(
6155                db,
6156                module.krate(db),
6157                module.block(db),
6158                &mut |impls| {
6159                    handle_impls(impls.for_self_ty(&simplified_type));
6160                },
6161            );
6162        }
6163    }
6164
6165    /// Iterates its type arguments
6166    ///
6167    /// It iterates the actual type arguments when concrete types are used
6168    /// and otherwise the generic names.
6169    /// It does not include `const` arguments.
6170    ///
6171    /// For code, such as:
6172    /// ```text
6173    /// struct Foo<T, U>
6174    ///
6175    /// impl<U> Foo<String, U>
6176    /// ```
6177    ///
6178    /// It iterates:
6179    /// ```text
6180    /// - "String"
6181    /// - "U"
6182    /// ```
6183    pub fn type_arguments(&self) -> impl Iterator<Item = Type<'db>> + '_ {
6184        match self.ty.skip_binder().strip_references().kind() {
6185            TyKind::Adt(_, substs) => Either::Left(substs.types().map(move |ty| self.derived(ty))),
6186            TyKind::Tuple(substs) => {
6187                Either::Right(Either::Left(substs.iter().map(move |ty| self.derived(ty))))
6188            }
6189            _ => Either::Right(Either::Right(iter::empty())),
6190        }
6191    }
6192
6193    /// Iterates its type and const arguments
6194    ///
6195    /// It iterates the actual type and const arguments when concrete types
6196    /// are used and otherwise the generic names.
6197    ///
6198    /// For code, such as:
6199    /// ```text
6200    /// struct Foo<T, const U: usize, const X: usize>
6201    ///
6202    /// impl<U> Foo<String, U, 12>
6203    /// ```
6204    ///
6205    /// It iterates:
6206    /// ```text
6207    /// - "String"
6208    /// - "U"
6209    /// - "12"
6210    /// ```
6211    pub fn type_and_const_arguments<'a>(
6212        &'a self,
6213        db: &'a dyn HirDatabase,
6214        display_target: DisplayTarget,
6215    ) -> impl Iterator<Item = SmolStr> + 'a {
6216        self.ty
6217            .skip_binder()
6218            .strip_references()
6219            .as_adt()
6220            .into_iter()
6221            .flat_map(|(_, substs)| substs.iter())
6222            .filter_map(move |arg| match arg.kind() {
6223                rustc_type_ir::GenericArgKind::Type(ty) => {
6224                    Some(format_smolstr!("{}", ty.display(db, display_target)))
6225                }
6226                rustc_type_ir::GenericArgKind::Const(const_) => {
6227                    Some(format_smolstr!("{}", const_.display(db, display_target)))
6228                }
6229                rustc_type_ir::GenericArgKind::Lifetime(_) => None,
6230            })
6231    }
6232
6233    /// Combines lifetime indicators, type and constant parameters into a single `Iterator`
6234    pub fn generic_parameters<'a>(
6235        &'a self,
6236        db: &'a dyn HirDatabase,
6237        display_target: DisplayTarget,
6238    ) -> impl Iterator<Item = SmolStr> + 'a {
6239        // iterate the lifetime
6240        self.as_adt()
6241            .and_then(|a| {
6242                // Lifetimes do not need edition-specific handling as they cannot be escaped.
6243                a.lifetime(db).map(|lt| lt.name.display_no_db(Edition::Edition2015).to_smolstr())
6244            })
6245            .into_iter()
6246            // add the type and const parameters
6247            .chain(self.type_and_const_arguments(db, display_target))
6248    }
6249
6250    pub fn iterate_method_candidates_with_traits<T>(
6251        &self,
6252        db: &'db dyn HirDatabase,
6253        scope: &SemanticsScope<'_>,
6254        traits_in_scope: &FxHashSet<TraitId>,
6255        name: Option<&Name>,
6256        mut callback: impl FnMut(Function) -> Option<T>,
6257    ) -> Option<T> {
6258        let _p = tracing::info_span!("iterate_method_candidates_with_traits").entered();
6259        let mut slot = None;
6260        self.iterate_method_candidates_split_inherent(db, scope, traits_in_scope, name, |f| {
6261            match callback(f) {
6262                it @ Some(_) => {
6263                    slot = it;
6264                    ControlFlow::Break(())
6265                }
6266                None => ControlFlow::Continue(()),
6267            }
6268        });
6269        slot
6270    }
6271
6272    pub fn iterate_method_candidates<T>(
6273        &self,
6274        db: &'db dyn HirDatabase,
6275        scope: &SemanticsScope<'_>,
6276        name: Option<&Name>,
6277        callback: impl FnMut(Function) -> Option<T>,
6278    ) -> Option<T> {
6279        self.iterate_method_candidates_with_traits(
6280            db,
6281            scope,
6282            &scope.visible_traits().0,
6283            name,
6284            callback,
6285        )
6286    }
6287
6288    fn with_method_resolution<R>(
6289        &self,
6290        db: &'db dyn HirDatabase,
6291        resolver: &Resolver<'db>,
6292        traits_in_scope: &FxHashSet<TraitId>,
6293        f: impl FnOnce(&MethodResolutionContext<'_, 'db>) -> R,
6294    ) -> R {
6295        let module = resolver.module();
6296        let interner = DbInterner::new_with(db, module.krate(db));
6297        // Most IDE operations want to operate in PostAnalysis mode, revealing opaques. This makes
6298        // for a nicer IDE experience. However, method resolution is always done on real code (either
6299        // existing code or code to be inserted), and there using PostAnalysis is dangerous - we may
6300        // suggest invalid methods. So we're using the TypingMode of the body we're in.
6301        let typing_mode = if let Some(store_owner) = resolver.expression_store_owner() {
6302            TypingMode::analysis_in_body(interner, store_owner.into())
6303        } else {
6304            TypingMode::non_body_analysis()
6305        };
6306        let infcx = interner.infer_ctxt().build(typing_mode);
6307        let features = resolver.top_level_def_map().features();
6308        let environment = self.param_env(db);
6309        let ctx = MethodResolutionContext {
6310            infcx: &infcx,
6311            resolver,
6312            param_env: environment.param_env,
6313            traits_in_scope,
6314            edition: resolver.krate().data(db).edition,
6315            features,
6316            call_span: hir_ty::Span::Dummy,
6317            receiver_span: hir_ty::Span::Dummy,
6318        };
6319        f(&ctx)
6320    }
6321
6322    /// Allows you to treat inherent and non-inherent methods differently.
6323    ///
6324    /// Note that inherent methods may actually be trait methods! For example, in `dyn Trait`, the trait's methods
6325    /// are considered inherent methods.
6326    pub fn iterate_method_candidates_split_inherent(
6327        &self,
6328        db: &'db dyn HirDatabase,
6329        scope: &SemanticsScope<'_>,
6330        traits_in_scope: &FxHashSet<TraitId>,
6331        name: Option<&Name>,
6332        mut callback: impl MethodCandidateCallback,
6333    ) {
6334        let _p = tracing::info_span!(
6335            "iterate_method_candidates_split_inherent",
6336            traits_in_scope = traits_in_scope.len(),
6337            ?name,
6338        )
6339        .entered();
6340
6341        self.with_method_resolution(db, scope.resolver(), traits_in_scope, |ctx| {
6342            // There should be no inference vars in types passed here
6343            let canonical =
6344                hir_ty::replace_errors_with_variables(ctx.infcx.interner, &self.ty.skip_binder());
6345            let (self_ty, _) = ctx.infcx.instantiate_canonical(hir_ty::Span::Dummy, &canonical);
6346
6347            match name {
6348                Some(name) => {
6349                    match ctx.probe_for_name(
6350                        method_resolution::Mode::MethodCall,
6351                        name.clone(),
6352                        self_ty,
6353                    ) {
6354                        Ok(candidate)
6355                        | Err(method_resolution::MethodError::PrivateMatch(candidate)) => {
6356                            let method_resolution::CandidateId::FunctionId(id) = candidate.item
6357                            else {
6358                                unreachable!("`Mode::MethodCall` can only return functions");
6359                            };
6360                            let id = Function { id: AnyFunctionId::FunctionId(id) };
6361                            match candidate.kind {
6362                                method_resolution::PickKind::InherentImplPick(_)
6363                                | method_resolution::PickKind::ObjectPick(..)
6364                                | method_resolution::PickKind::WhereClausePick(..) => {
6365                                    // Candidates from where clauses and trait objects are considered inherent.
6366                                    _ = callback.on_inherent_method(id);
6367                                }
6368                                method_resolution::PickKind::TraitPick(..) => {
6369                                    _ = callback.on_trait_method(id);
6370                                }
6371                            }
6372                        }
6373                        Err(_) => {}
6374                    };
6375                }
6376                None => {
6377                    _ = ctx.probe_all(method_resolution::Mode::MethodCall, self_ty).try_for_each(
6378                        |candidate| {
6379                            let method_resolution::CandidateId::FunctionId(id) =
6380                                candidate.candidate.item
6381                            else {
6382                                unreachable!("`Mode::MethodCall` can only return functions");
6383                            };
6384                            let id = Function { id: AnyFunctionId::FunctionId(id) };
6385                            match candidate.candidate.kind {
6386                                method_resolution::CandidateKind::InherentImplCandidate {
6387                                    ..
6388                                }
6389                                | method_resolution::CandidateKind::ObjectCandidate(..)
6390                                | method_resolution::CandidateKind::WhereClauseCandidate(..) => {
6391                                    // Candidates from where clauses and trait objects are considered inherent.
6392                                    callback.on_inherent_method(id)
6393                                }
6394                                method_resolution::CandidateKind::TraitCandidate(..) => {
6395                                    callback.on_trait_method(id)
6396                                }
6397                            }
6398                        },
6399                    );
6400                }
6401            }
6402        })
6403    }
6404
6405    #[tracing::instrument(skip_all, fields(name = ?name))]
6406    pub fn iterate_path_candidates<T>(
6407        &self,
6408        db: &'db dyn HirDatabase,
6409        scope: &SemanticsScope<'_>,
6410        traits_in_scope: &FxHashSet<TraitId>,
6411        name: Option<&Name>,
6412        mut callback: impl FnMut(AssocItem) -> Option<T>,
6413    ) -> Option<T> {
6414        let _p = tracing::info_span!("iterate_path_candidates").entered();
6415        let mut slot = None;
6416
6417        self.iterate_path_candidates_split_inherent(db, scope, traits_in_scope, name, |item| {
6418            match callback(item) {
6419                it @ Some(_) => {
6420                    slot = it;
6421                    ControlFlow::Break(())
6422                }
6423                None => ControlFlow::Continue(()),
6424            }
6425        });
6426        slot
6427    }
6428
6429    /// Iterates over inherent methods.
6430    ///
6431    /// In some circumstances, inherent methods methods may actually be trait methods!
6432    /// For example, when `dyn Trait` is a receiver, _trait_'s methods would be considered
6433    /// to be inherent methods.
6434    #[tracing::instrument(skip_all, fields(name = ?name))]
6435    pub fn iterate_path_candidates_split_inherent(
6436        &self,
6437        db: &'db dyn HirDatabase,
6438        scope: &SemanticsScope<'_>,
6439        traits_in_scope: &FxHashSet<TraitId>,
6440        name: Option<&Name>,
6441        mut callback: impl PathCandidateCallback,
6442    ) {
6443        let _p = tracing::info_span!(
6444            "iterate_path_candidates_split_inherent",
6445            traits_in_scope = traits_in_scope.len(),
6446            ?name,
6447        )
6448        .entered();
6449
6450        self.with_method_resolution(db, scope.resolver(), traits_in_scope, |ctx| {
6451            // There should be no inference vars in types passed here
6452            let canonical =
6453                hir_ty::replace_errors_with_variables(ctx.infcx.interner, &self.ty.skip_binder());
6454            let (self_ty, _) = ctx.infcx.instantiate_canonical(hir_ty::Span::Dummy, &canonical);
6455
6456            match name {
6457                Some(name) => {
6458                    match ctx.probe_for_name(method_resolution::Mode::Path, name.clone(), self_ty) {
6459                        Ok(candidate)
6460                        | Err(method_resolution::MethodError::PrivateMatch(candidate)) => {
6461                            let id = candidate.item.into();
6462                            match candidate.kind {
6463                                method_resolution::PickKind::InherentImplPick(_)
6464                                | method_resolution::PickKind::ObjectPick(..)
6465                                | method_resolution::PickKind::WhereClausePick(..) => {
6466                                    // Candidates from where clauses and trait objects are considered inherent.
6467                                    _ = callback.on_inherent_item(id);
6468                                }
6469                                method_resolution::PickKind::TraitPick(..) => {
6470                                    _ = callback.on_trait_item(id);
6471                                }
6472                            }
6473                        }
6474                        Err(_) => {}
6475                    };
6476                }
6477                None => {
6478                    _ = ctx.probe_all(method_resolution::Mode::Path, self_ty).try_for_each(
6479                        |candidate| {
6480                            let id = candidate.candidate.item.into();
6481                            match candidate.candidate.kind {
6482                                method_resolution::CandidateKind::InherentImplCandidate {
6483                                    ..
6484                                }
6485                                | method_resolution::CandidateKind::ObjectCandidate(..)
6486                                | method_resolution::CandidateKind::WhereClauseCandidate(..) => {
6487                                    // Candidates from where clauses and trait objects are considered inherent.
6488                                    callback.on_inherent_item(id)
6489                                }
6490                                method_resolution::CandidateKind::TraitCandidate(..) => {
6491                                    callback.on_trait_item(id)
6492                                }
6493                            }
6494                        },
6495                    );
6496                }
6497            }
6498        })
6499    }
6500
6501    pub fn as_adt(&self) -> Option<Adt> {
6502        let (adt, _subst) = self.ty.skip_binder().as_adt()?;
6503        Some(adt.into())
6504    }
6505
6506    /// Holes in the args can come from lifetime/const params.
6507    pub fn as_adt_with_args(&self) -> Option<(Adt, Vec<Option<Type<'db>>>)> {
6508        let (adt, args) = self.ty.skip_binder().as_adt()?;
6509        let args = args.iter().map(|arg| Some(self.derived(arg.ty()?))).collect();
6510        Some((adt.into(), args))
6511    }
6512
6513    pub fn as_builtin(&self) -> Option<BuiltinType> {
6514        self.ty.skip_binder().as_builtin().map(|inner| BuiltinType { inner })
6515    }
6516
6517    pub fn as_dyn_trait(&self) -> Option<Trait> {
6518        self.ty.skip_binder().dyn_trait().map(Into::into)
6519    }
6520
6521    /// If a type can be represented as `dyn Trait`, returns all traits accessible via this type,
6522    /// or an empty iterator otherwise.
6523    pub fn applicable_inherent_traits(
6524        &self,
6525        db: &'db dyn HirDatabase,
6526    ) -> impl Iterator<Item = Trait> {
6527        let _p = tracing::info_span!("applicable_inherent_traits").entered();
6528        self.autoderef_(db)
6529            .filter_map(|ty| ty.dyn_trait())
6530            .flat_map(move |dyn_trait_id| hir_ty::all_super_traits(db, dyn_trait_id))
6531            .copied()
6532            .map(Trait::from)
6533    }
6534
6535    pub fn env_traits(&self, db: &'db dyn HirDatabase) -> impl Iterator<Item = Trait> {
6536        let _p = tracing::info_span!("env_traits").entered();
6537        let env = self.param_env(db);
6538        self.autoderef_(db)
6539            .filter(|ty| matches!(ty.kind(), TyKind::Param(_)))
6540            .flat_map(move |ty| {
6541                env.param_env
6542                    .clauses()
6543                    .iter()
6544                    .filter_map(move |pred| match pred.kind().skip_binder() {
6545                        ClauseKind::Trait(tr) if tr.self_ty() == ty => Some(tr.def_id().0),
6546                        _ => None,
6547                    })
6548                    .flat_map(|t| hir_ty::all_super_traits(db, t))
6549                    .copied()
6550            })
6551            .map(Trait::from)
6552    }
6553
6554    pub fn as_impl_traits(&self, db: &'db dyn HirDatabase) -> Option<impl Iterator<Item = Trait>> {
6555        self.ty.skip_binder().impl_trait_bounds(db).map(|it| {
6556            it.into_iter().filter_map(|pred| match pred.kind().skip_binder() {
6557                ClauseKind::Trait(trait_ref) => Some(Trait::from(trait_ref.def_id().0)),
6558                _ => None,
6559            })
6560        })
6561    }
6562
6563    pub fn as_associated_type_parent_trait(&self, db: &'db dyn HirDatabase) -> Option<Trait> {
6564        let TyKind::Alias(AliasTy { kind: AliasTyKind::Projection { def_id }, .. }) =
6565            self.ty.skip_binder().kind()
6566        else {
6567            return None;
6568        };
6569        match def_id.0.loc(db).container {
6570            ItemContainerId::TraitId(id) => Some(Trait { id }),
6571            _ => None,
6572        }
6573    }
6574
6575    fn derived(&self, ty: Ty<'db>) -> Self {
6576        Type { owner: self.owner, ty: EarlyBinder::bind(ty) }
6577    }
6578
6579    /// Visits every type, including generic arguments, in this type. `callback` is called with type
6580    /// itself first, and then with its generic arguments.
6581    pub fn walk(&self, db: &'db dyn HirDatabase, callback: impl FnMut(Type<'db>)) {
6582        struct Visitor<'db, F> {
6583            db: &'db dyn HirDatabase,
6584            owner: TypeOwnerId<'db>,
6585            callback: F,
6586            visited: FxHashSet<Ty<'db>>,
6587        }
6588        impl<'db, F> TypeVisitor<DbInterner<'db>> for Visitor<'db, F>
6589        where
6590            F: FnMut(Type<'db>),
6591        {
6592            type Result = ();
6593
6594            fn visit_ty(&mut self, ty: Ty<'db>) -> Self::Result {
6595                if !self.visited.insert(ty) {
6596                    return;
6597                }
6598
6599                (self.callback)(Type { owner: self.owner, ty: EarlyBinder::bind(ty) });
6600
6601                if let Some(bounds) = ty.impl_trait_bounds(self.db) {
6602                    bounds.visit_with(self);
6603                }
6604
6605                ty.super_visit_with(self);
6606            }
6607        }
6608
6609        let mut visitor =
6610            Visitor { db, owner: self.owner, callback, visited: FxHashSet::default() };
6611        self.ty.skip_binder().visit_with(&mut visitor);
6612    }
6613    /// Check if type unifies with another type.
6614    ///
6615    /// Note that we consider placeholder types to unify with everything.
6616    /// For example `Option<T>` and `Option<U>` unify although there is unresolved goal `T = U`.
6617    pub fn could_unify_with(&self, db: &'db dyn HirDatabase, other: &Type<'db>) -> bool {
6618        self.owner.must_unify(other.owner);
6619        let env = self.param_env(db);
6620        let interner = DbInterner::new_no_crate(db);
6621        let tys = hir_ty::replace_errors_with_variables(
6622            interner,
6623            &(self.ty.skip_binder(), other.ty.skip_binder()),
6624        );
6625        hir_ty::could_unify(db, env, &tys)
6626    }
6627
6628    /// Check if type unifies with another type eagerly making sure there are no unresolved goals.
6629    ///
6630    /// This means that placeholder types are not considered to unify if there are any bounds set on
6631    /// them. For example `Option<T>` and `Option<U>` do not unify as we cannot show that `T = U`
6632    pub fn could_unify_with_deeply(&self, db: &'db dyn HirDatabase, other: &Type<'db>) -> bool {
6633        self.owner.must_unify(other.owner);
6634        let env = self.param_env(db);
6635        let interner = DbInterner::new_no_crate(db);
6636        let tys = hir_ty::replace_errors_with_variables(
6637            interner,
6638            &(self.ty.skip_binder(), other.ty.skip_binder()),
6639        );
6640        hir_ty::could_unify_deeply(db, env, &tys)
6641    }
6642
6643    pub fn could_coerce_to(&self, db: &'db dyn HirDatabase, to: &Type<'db>) -> bool {
6644        self.owner.must_unify(to.owner);
6645        let env = self.param_env(db);
6646        let interner = DbInterner::new_no_crate(db);
6647        let tys = hir_ty::replace_errors_with_variables(
6648            interner,
6649            &(self.ty.skip_binder(), to.ty.skip_binder()),
6650        );
6651        hir_ty::could_coerce(db, env, &tys)
6652    }
6653
6654    pub fn as_type_param(&self, _db: &'db dyn HirDatabase) -> Option<TypeParam> {
6655        match self.ty.skip_binder().kind() {
6656            TyKind::Param(param) => Some(TypeParam { id: param.id }),
6657            _ => None,
6658        }
6659    }
6660
6661    /// Returns unique `GenericParam`s contained in this type.
6662    pub fn generic_params(&self, db: &'db dyn HirDatabase) -> FxHashSet<GenericParam> {
6663        hir_ty::collect_params(&self.ty.skip_binder())
6664            .into_iter()
6665            .map(|id| TypeOrConstParam { id }.split(db).either_into())
6666            .collect()
6667    }
6668
6669    pub fn layout(&self, db: &'db dyn HirDatabase) -> Result<Layout<'db>, LayoutError> {
6670        let env = self.param_env(db);
6671        db.layout_of_ty(self.ty.skip_binder().store(), env.store())
6672            .map(|layout| Layout(layout, db.target_data_layout(env.krate).unwrap()))
6673    }
6674
6675    pub fn drop_glue(&self, db: &'db dyn HirDatabase) -> DropGlue {
6676        let env = self.param_env(db);
6677        let interner = DbInterner::new_with(db, env.krate);
6678        let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
6679        hir_ty::drop::has_drop_glue(&infcx, self.ty.skip_binder(), env.param_env)
6680    }
6681}
6682
6683#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
6684pub struct InlineAsmOperand {
6685    owner: ExpressionStoreOwnerId,
6686    expr: ExprId,
6687    index: usize,
6688}
6689
6690impl InlineAsmOperand {
6691    pub fn parent(self, _db: &dyn HirDatabase) -> ExpressionStoreOwner {
6692        self.owner.into()
6693    }
6694
6695    pub fn name(&self, db: &dyn HirDatabase) -> Option<Name> {
6696        let body = ExpressionStore::of(db, self.owner);
6697        match &body[self.expr] {
6698            hir_def::hir::Expr::InlineAsm(e) => e.operands.get(self.index)?.0.clone(),
6699            _ => None,
6700        }
6701    }
6702}
6703
6704// FIXME: Document this
6705#[derive(Debug)]
6706pub struct Callable<'db> {
6707    ty: Type<'db>,
6708    sig: PolyFnSig<'db>,
6709    callee: Callee<'db>,
6710    /// Whether this is a method that was called with method call syntax.
6711    is_bound_method: bool,
6712}
6713
6714#[derive(Clone, PartialEq, Eq, Hash, Debug)]
6715enum Callee<'db> {
6716    Def(CallableDefId),
6717    Closure(InternedClosureId<'db>, GenericArgs<'db>),
6718    CoroutineClosure(InternedCoroutineClosureId<'db>, GenericArgs<'db>),
6719    FnPtr,
6720    FnImpl(traits::FnTrait),
6721    BuiltinDeriveImplMethod { method: BuiltinDeriveImplMethod, impl_: BuiltinDeriveImplId },
6722}
6723
6724pub enum CallableKind<'db> {
6725    Function(Function),
6726    TupleStruct(Struct),
6727    TupleEnumVariant(EnumVariant),
6728    Closure(Closure<'db>),
6729    FnPtr,
6730    FnImpl(FnTrait),
6731}
6732
6733impl<'db> Callable<'db> {
6734    fn erased_sig(&self) -> FnSig<'db> {
6735        DbInterner::conjure().instantiate_bound_regions_with_erased(self.sig)
6736    }
6737
6738    pub fn kind(&self) -> CallableKind<'db> {
6739        match self.callee {
6740            Callee::Def(CallableDefId::FunctionId(it)) => CallableKind::Function(it.into()),
6741            Callee::BuiltinDeriveImplMethod { method, impl_ } => CallableKind::Function(Function {
6742                id: AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ },
6743            }),
6744            Callee::Def(CallableDefId::StructId(it)) => CallableKind::TupleStruct(it.into()),
6745            Callee::Def(CallableDefId::EnumVariantId(it)) => {
6746                CallableKind::TupleEnumVariant(it.into())
6747            }
6748            Callee::Closure(id, subst) => CallableKind::Closure(Closure {
6749                id: AnyClosureId::ClosureId(id),
6750                subst,
6751                owner: self.ty.owner,
6752            }),
6753            Callee::CoroutineClosure(id, subst) => CallableKind::Closure(Closure {
6754                id: AnyClosureId::CoroutineClosureId(id),
6755                subst,
6756                owner: self.ty.owner,
6757            }),
6758            Callee::FnPtr => CallableKind::FnPtr,
6759            Callee::FnImpl(fn_) => CallableKind::FnImpl(fn_.into()),
6760        }
6761    }
6762
6763    fn as_function(&self) -> Option<Function> {
6764        match self.callee {
6765            Callee::Def(CallableDefId::FunctionId(it)) => Some(it.into()),
6766            Callee::BuiltinDeriveImplMethod { method, impl_ } => {
6767                Some(Function { id: AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ } })
6768            }
6769            _ => None,
6770        }
6771    }
6772
6773    pub fn receiver_param(&self, db: &'db dyn HirDatabase) -> Option<(SelfParam, Type<'db>)> {
6774        if !self.is_bound_method {
6775            return None;
6776        }
6777        let func = self.as_function()?;
6778        Some((func.self_param(db)?, self.ty.derived(self.erased_sig().inputs()[0])))
6779    }
6780    pub fn n_params(&self) -> usize {
6781        self.sig.skip_binder().inputs_and_output.inputs().len()
6782            - if self.is_bound_method { 1 } else { 0 }
6783    }
6784    pub fn params(&self) -> Vec<Param<'db>> {
6785        self.erased_sig()
6786            .inputs()
6787            .iter()
6788            .enumerate()
6789            .skip(if self.is_bound_method { 1 } else { 0 })
6790            .map(|(idx, ty)| (idx, self.ty.derived(*ty)))
6791            .map(|(idx, ty)| Param { func: self.callee.clone(), idx, ty })
6792            .collect()
6793    }
6794    pub fn return_type(&self) -> Type<'db> {
6795        self.ty.derived(self.erased_sig().output())
6796    }
6797    pub fn sig(&self) -> impl Eq {
6798        &self.sig
6799    }
6800
6801    pub fn ty(&self) -> &Type<'db> {
6802        &self.ty
6803    }
6804}
6805
6806#[derive(Clone, Debug, Eq, PartialEq)]
6807pub struct Layout<'db>(Arc<TyLayout>, &'db TargetDataLayout);
6808
6809impl<'db> Layout<'db> {
6810    pub fn size(&self) -> u64 {
6811        self.0.size.bytes()
6812    }
6813
6814    pub fn align(&self) -> u64 {
6815        self.0.align.bytes()
6816    }
6817
6818    pub fn niches(&self) -> Option<u128> {
6819        Some(self.0.largest_niche?.available(self.1))
6820    }
6821
6822    pub fn field_offset(&self, field: Field) -> Option<u64> {
6823        match self.0.fields {
6824            layout::FieldsShape::Primitive => None,
6825            layout::FieldsShape::Union(_) => Some(0),
6826            layout::FieldsShape::Array { stride, count } => {
6827                let i = u64::try_from(field.index()).ok()?;
6828                (i < count).then_some((stride * i).bytes())
6829            }
6830            layout::FieldsShape::Arbitrary { ref offsets, .. } => {
6831                Some(offsets.get(RustcFieldIdx(field.id))?.bytes())
6832            }
6833        }
6834    }
6835
6836    pub fn tuple_field_offset(&self, field: usize) -> Option<u64> {
6837        match self.0.fields {
6838            layout::FieldsShape::Primitive => None,
6839            layout::FieldsShape::Union(_) => Some(0),
6840            layout::FieldsShape::Array { stride, count } => {
6841                let i = u64::try_from(field).ok()?;
6842                (i < count).then_some((stride * i).bytes())
6843            }
6844            layout::FieldsShape::Arbitrary { ref offsets, .. } => {
6845                Some(offsets.get(RustcFieldIdx::new(field))?.bytes())
6846            }
6847        }
6848    }
6849
6850    pub fn tail_padding(&self, field_size: &mut impl FnMut(usize) -> Option<u64>) -> Option<u64> {
6851        match self.0.fields {
6852            layout::FieldsShape::Primitive => None,
6853            layout::FieldsShape::Union(_) => None,
6854            layout::FieldsShape::Array { stride, count } => count.checked_sub(1).and_then(|tail| {
6855                let tail_field_size = field_size(tail as usize)?;
6856                let offset = stride.bytes() * tail;
6857                self.0.size.bytes().checked_sub(offset)?.checked_sub(tail_field_size)
6858            }),
6859            layout::FieldsShape::Arbitrary { ref offsets, ref in_memory_order } => {
6860                let tail = in_memory_order[in_memory_order.len().checked_sub(1)? as u32];
6861                let tail_field_size = field_size(tail.0.into_raw().into_u32() as usize)?;
6862                let offset = offsets.get(tail)?.bytes();
6863                self.0.size.bytes().checked_sub(offset)?.checked_sub(tail_field_size)
6864            }
6865        }
6866    }
6867
6868    pub fn largest_padding(
6869        &self,
6870        field_size: &mut impl FnMut(usize) -> Option<u64>,
6871    ) -> Option<u64> {
6872        match self.0.fields {
6873            layout::FieldsShape::Primitive => None,
6874            layout::FieldsShape::Union(_) => None,
6875            layout::FieldsShape::Array { stride: _, count: 0 } => None,
6876            layout::FieldsShape::Array { stride, .. } => {
6877                let size = field_size(0)?;
6878                stride.bytes().checked_sub(size)
6879            }
6880            layout::FieldsShape::Arbitrary { ref offsets, ref in_memory_order } => {
6881                let mut reverse_index = vec![None; in_memory_order.len()];
6882                for (mem, src) in in_memory_order.iter().enumerate() {
6883                    reverse_index[mem] =
6884                        Some((src.0.into_raw().into_u32() as usize, offsets[*src].bytes()));
6885                }
6886                if reverse_index.iter().any(|it| it.is_none()) {
6887                    stdx::never!();
6888                    return None;
6889                }
6890                reverse_index
6891                    .into_iter()
6892                    .flatten()
6893                    .chain(iter::once((0, self.0.size.bytes())))
6894                    .array_windows()
6895                    .filter_map(|[(i, start), (_, end)]| {
6896                        let size = field_size(i)?;
6897                        end.checked_sub(start)?.checked_sub(size)
6898                    })
6899                    .max()
6900            }
6901        }
6902    }
6903
6904    pub fn enum_tag_size(&self) -> Option<usize> {
6905        let tag_size =
6906            if let layout::Variants::Multiple { tag, tag_encoding, .. } = &self.0.variants {
6907                match tag_encoding {
6908                    TagEncoding::Direct => tag.size(self.1).bytes_usize(),
6909                    TagEncoding::Niche { .. } => 0,
6910                }
6911            } else {
6912                return None;
6913            };
6914        Some(tag_size)
6915    }
6916}
6917
6918#[derive(Copy, Clone, Debug, Eq, PartialEq)]
6919pub enum BindingMode {
6920    Move,
6921    Ref(Mutability),
6922}
6923
6924/// For IDE only
6925#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
6926pub enum ScopeDef<'db> {
6927    ModuleDef(ModuleDef),
6928    GenericParam(GenericParam),
6929    ImplSelfType(Impl),
6930    AdtSelfType(Adt),
6931    Local(Local<'db>),
6932    Label(Label),
6933    Unknown,
6934}
6935
6936impl ScopeDef<'_> {
6937    pub fn all_items(def: PerNs) -> ArrayVec<Self, 3> {
6938        let mut items = ArrayVec::new();
6939
6940        match (def.take_types(), def.take_values()) {
6941            (Some(m1), None) => items.push(ScopeDef::ModuleDef(m1.into())),
6942            (None, Some(m2)) => items.push(ScopeDef::ModuleDef(m2.into())),
6943            (Some(m1), Some(m2)) => {
6944                // Some items, like unit structs and enum variants, are
6945                // returned as both a type and a value. Here we want
6946                // to de-duplicate them.
6947                if m1 != m2 {
6948                    items.push(ScopeDef::ModuleDef(m1.into()));
6949                    items.push(ScopeDef::ModuleDef(m2.into()));
6950                } else {
6951                    items.push(ScopeDef::ModuleDef(m1.into()));
6952                }
6953            }
6954            (None, None) => {}
6955        };
6956
6957        if let Some(macro_def_id) = def.take_macros() {
6958            items.push(ScopeDef::ModuleDef(ModuleDef::Macro(macro_def_id.into())));
6959        }
6960
6961        if items.is_empty() {
6962            items.push(ScopeDef::Unknown);
6963        }
6964
6965        items
6966    }
6967
6968    pub fn attrs(&self, db: &dyn HirDatabase) -> Option<AttrsWithOwner> {
6969        match self {
6970            ScopeDef::ModuleDef(it) => it.attrs(db),
6971            ScopeDef::GenericParam(it) => Some(it.attrs(db)),
6972            ScopeDef::ImplSelfType(_)
6973            | ScopeDef::AdtSelfType(_)
6974            | ScopeDef::Local(_)
6975            | ScopeDef::Label(_)
6976            | ScopeDef::Unknown => None,
6977        }
6978    }
6979
6980    pub fn krate(&self, db: &dyn HirDatabase) -> Option<Crate> {
6981        match self {
6982            ScopeDef::ModuleDef(it) => it.module(db).map(|m| m.krate(db)),
6983            ScopeDef::GenericParam(it) => Some(it.module(db).krate(db)),
6984            ScopeDef::ImplSelfType(_) => None,
6985            ScopeDef::AdtSelfType(it) => Some(it.module(db).krate(db)),
6986            ScopeDef::Local(it) => Some(it.module(db).krate(db)),
6987            ScopeDef::Label(it) => Some(it.module(db).krate(db)),
6988            ScopeDef::Unknown => None,
6989        }
6990    }
6991}
6992
6993impl_from!(
6994    impl<'db>
6995    ItemInNs { Types => ModuleDef, Values => ModuleDef, Macros => ModuleDef }
6996    for ScopeDef<'db>
6997);
6998
6999#[derive(Clone, Debug, PartialEq, Eq)]
7000pub struct Adjustment<'db> {
7001    pub source: Type<'db>,
7002    pub target: Type<'db>,
7003    pub kind: Adjust,
7004}
7005
7006#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
7007pub enum Adjust {
7008    /// Go from ! to any type.
7009    NeverToAny,
7010    /// Dereference once, producing a place.
7011    Deref(Option<OverloadedDeref>),
7012    /// Take the address and produce either a `&` or `*` pointer.
7013    Borrow(AutoBorrow),
7014    Pointer(PointerCast),
7015}
7016
7017#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
7018pub enum AutoBorrow {
7019    /// Converts from T to &T.
7020    Ref(Mutability),
7021    /// Converts from T to *T.
7022    RawPtr(Mutability),
7023}
7024
7025#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
7026pub struct OverloadedDeref(pub Mutability);
7027
7028pub trait HasVisibility {
7029    fn visibility(&self, db: &dyn HirDatabase) -> Visibility;
7030    fn is_visible_from(&self, db: &dyn HirDatabase, module: Module) -> bool {
7031        let vis = self.visibility(db);
7032        vis.is_visible_from(db, module.id)
7033    }
7034}
7035
7036#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7037pub enum PredicatePolarity {
7038    /// `T: Trait`
7039    Positive,
7040    /// `T: !Trait`
7041    Negative,
7042}
7043
7044#[derive(Debug, Clone, PartialEq, Eq)]
7045pub struct TraitPredicate<'db> {
7046    inner: hir_ty::next_solver::TraitPredicate<'db>,
7047    owner: TypeOwnerId<'db>,
7048}
7049
7050impl<'db> TraitPredicate<'db> {
7051    pub fn polarity(&self) -> PredicatePolarity {
7052        match self.inner.polarity {
7053            rustc_type_ir::PredicatePolarity::Positive => PredicatePolarity::Positive,
7054            rustc_type_ir::PredicatePolarity::Negative => PredicatePolarity::Negative,
7055        }
7056    }
7057
7058    pub fn trait_ref(&self) -> TraitRef<'db> {
7059        TraitRef { owner: self.owner, trait_ref: self.inner.trait_ref }
7060    }
7061}
7062
7063/// Trait for obtaining the defining crate of an item.
7064pub trait HasCrate {
7065    fn krate(&self, db: &dyn HirDatabase) -> Crate;
7066}
7067
7068impl<T: hir_def::HasModule> HasCrate for T {
7069    fn krate(&self, db: &dyn HirDatabase) -> Crate {
7070        self.module(db).krate(db).into()
7071    }
7072}
7073
7074impl HasCrate for AssocItem {
7075    fn krate(&self, db: &dyn HirDatabase) -> Crate {
7076        self.module(db).krate(db)
7077    }
7078}
7079
7080impl HasCrate for Struct {
7081    fn krate(&self, db: &dyn HirDatabase) -> Crate {
7082        self.module(db).krate(db)
7083    }
7084}
7085
7086impl HasCrate for Union {
7087    fn krate(&self, db: &dyn HirDatabase) -> Crate {
7088        self.module(db).krate(db)
7089    }
7090}
7091
7092impl HasCrate for Enum {
7093    fn krate(&self, db: &dyn HirDatabase) -> Crate {
7094        self.module(db).krate(db)
7095    }
7096}
7097
7098impl HasCrate for Field {
7099    fn krate(&self, db: &dyn HirDatabase) -> Crate {
7100        self.parent_def(db).module(db).krate(db)
7101    }
7102}
7103
7104impl HasCrate for EnumVariant {
7105    fn krate(&self, db: &dyn HirDatabase) -> Crate {
7106        self.module(db).krate(db)
7107    }
7108}
7109
7110impl HasCrate for Function {
7111    fn krate(&self, db: &dyn HirDatabase) -> Crate {
7112        self.module(db).krate(db)
7113    }
7114}
7115
7116impl HasCrate for Const {
7117    fn krate(&self, db: &dyn HirDatabase) -> Crate {
7118        self.module(db).krate(db)
7119    }
7120}
7121
7122impl HasCrate for TypeAlias {
7123    fn krate(&self, db: &dyn HirDatabase) -> Crate {
7124        self.module(db).krate(db)
7125    }
7126}
7127
7128impl HasCrate for Type<'_> {
7129    fn krate(&self, db: &dyn HirDatabase) -> Crate {
7130        self.krate(db).into()
7131    }
7132}
7133
7134impl HasCrate for Macro {
7135    fn krate(&self, db: &dyn HirDatabase) -> Crate {
7136        self.module(db).krate(db)
7137    }
7138}
7139
7140impl HasCrate for Trait {
7141    fn krate(&self, db: &dyn HirDatabase) -> Crate {
7142        self.module(db).krate(db)
7143    }
7144}
7145
7146impl HasCrate for Static {
7147    fn krate(&self, db: &dyn HirDatabase) -> Crate {
7148        self.module(db).krate(db)
7149    }
7150}
7151
7152impl HasCrate for Adt {
7153    fn krate(&self, db: &dyn HirDatabase) -> Crate {
7154        self.module(db).krate(db)
7155    }
7156}
7157
7158impl HasCrate for Impl {
7159    fn krate(&self, db: &dyn HirDatabase) -> Crate {
7160        self.module(db).krate(db)
7161    }
7162}
7163
7164impl HasCrate for Module {
7165    fn krate(&self, db: &dyn HirDatabase) -> Crate {
7166        Module::krate(*self, db)
7167    }
7168}
7169
7170impl<'db> HasCrate for AnonConst<'db> {
7171    fn krate(&self, db: &dyn HirDatabase) -> Crate {
7172        hir_def::HasModule::krate(&self.id.loc(db).owner, db).into()
7173    }
7174}
7175
7176pub trait HasContainer {
7177    fn container(&self, db: &dyn HirDatabase) -> ItemContainer;
7178}
7179
7180impl HasContainer for ExternCrateDecl {
7181    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
7182        container_id_to_hir(self.id.lookup(db).container.into())
7183    }
7184}
7185
7186impl HasContainer for Module {
7187    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
7188        // FIXME: handle block expressions as modules (their parent is in a different DefMap)
7189        let def_map = self.id.def_map(db);
7190        match def_map[self.id].parent {
7191            Some(parent_id) => ItemContainer::Module(Module { id: parent_id }),
7192            None => ItemContainer::Crate(def_map.krate().into()),
7193        }
7194    }
7195}
7196
7197impl HasContainer for Function {
7198    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
7199        match self.id {
7200            AnyFunctionId::FunctionId(id) => container_id_to_hir(id.lookup(db).container),
7201            AnyFunctionId::BuiltinDeriveImplMethod { impl_, .. } => {
7202                ItemContainer::Impl(Impl { id: AnyImplId::BuiltinDeriveImplId(impl_) })
7203            }
7204        }
7205    }
7206}
7207
7208impl HasContainer for Struct {
7209    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
7210        ItemContainer::Module(Module { id: self.id.lookup(db).container })
7211    }
7212}
7213
7214impl HasContainer for Union {
7215    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
7216        ItemContainer::Module(Module { id: self.id.lookup(db).container })
7217    }
7218}
7219
7220impl HasContainer for Enum {
7221    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
7222        ItemContainer::Module(Module { id: self.id.lookup(db).container })
7223    }
7224}
7225
7226impl HasContainer for TypeAlias {
7227    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
7228        container_id_to_hir(self.id.lookup(db).container)
7229    }
7230}
7231
7232impl HasContainer for Const {
7233    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
7234        container_id_to_hir(self.id.lookup(db).container)
7235    }
7236}
7237
7238impl HasContainer for Static {
7239    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
7240        container_id_to_hir(self.id.lookup(db).container)
7241    }
7242}
7243
7244impl HasContainer for Trait {
7245    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
7246        ItemContainer::Module(Module { id: self.id.lookup(db).container })
7247    }
7248}
7249
7250impl HasContainer for ExternBlock {
7251    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
7252        ItemContainer::Module(Module { id: self.id.lookup(db).container })
7253    }
7254}
7255
7256pub trait HasName {
7257    fn name(&self, db: &dyn HirDatabase) -> Option<Name>;
7258}
7259
7260macro_rules! impl_has_name {
7261    ( $( $ty:ident ),* $(,)? ) => {
7262        $(
7263            impl HasName for $ty {
7264                fn name(&self, db: &dyn HirDatabase) -> Option<Name> {
7265                    (*self).name(db).into()
7266                }
7267            }
7268        )*
7269    };
7270}
7271
7272impl_has_name!(
7273    ModuleDef,
7274    Module,
7275    Field,
7276    Struct,
7277    Union,
7278    Enum,
7279    EnumVariant,
7280    Adt,
7281    Variant,
7282    DefWithBody,
7283    Function,
7284    ExternCrateDecl,
7285    Const,
7286    Static,
7287    Trait,
7288    TypeAlias,
7289    Macro,
7290    ExternAssocItem,
7291    AssocItem,
7292    DeriveHelper,
7293    ToolModule,
7294    Label,
7295    GenericParam,
7296    TypeParam,
7297    LifetimeParam,
7298    ConstParam,
7299    TypeOrConstParam,
7300    InlineAsmOperand,
7301);
7302
7303macro_rules! impl_has_name_no_db {
7304    ( $( $ty:ident ),* $(,)? ) => {
7305        $(
7306            impl HasName for $ty {
7307                fn name(&self, _db: &dyn HirDatabase) -> Option<Name> {
7308                    (*self).name().into()
7309                }
7310            }
7311        )*
7312    };
7313}
7314
7315impl_has_name_no_db!(StaticLifetime, BuiltinType, BuiltinAttr);
7316
7317impl HasName for Local<'_> {
7318    fn name(&self, db: &dyn HirDatabase) -> Option<Name> {
7319        (*self).name(db).into()
7320    }
7321}
7322
7323impl HasName for TupleField<'_> {
7324    fn name(&self, _db: &dyn HirDatabase) -> Option<Name> {
7325        (*self).name().into()
7326    }
7327}
7328
7329impl HasName for Param<'_> {
7330    fn name(&self, db: &dyn HirDatabase) -> Option<Name> {
7331        self.name(db)
7332    }
7333}
7334
7335fn container_id_to_hir(c: ItemContainerId) -> ItemContainer {
7336    match c {
7337        ItemContainerId::ExternBlockId(id) => ItemContainer::ExternBlock(ExternBlock { id }),
7338        ItemContainerId::ModuleId(id) => ItemContainer::Module(Module { id }),
7339        ItemContainerId::ImplId(id) => ItemContainer::Impl(id.into()),
7340        ItemContainerId::TraitId(id) => ItemContainer::Trait(Trait { id }),
7341    }
7342}
7343
7344#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7345pub enum ItemContainer {
7346    Trait(Trait),
7347    Impl(Impl),
7348    Module(Module),
7349    ExternBlock(ExternBlock),
7350    Crate(Crate),
7351}
7352
7353/// Subset of `ide_db::Definition` that doc links can resolve to.
7354pub enum DocLinkDef {
7355    ModuleDef(ModuleDef),
7356    Field(Field),
7357    SelfType(Trait),
7358}
7359
7360fn push_ty_diagnostics<'db>(
7361    db: &'db dyn HirDatabase,
7362    acc: &mut Vec<AnyDiagnostic<'db>>,
7363    diagnostics: &[TyLoweringDiagnostic],
7364    source_map: &ExpressionStoreSourceMap,
7365) {
7366    acc.extend(
7367        diagnostics
7368            .iter()
7369            .filter_map(|diagnostic| AnyDiagnostic::ty_diagnostic(diagnostic, source_map, db)),
7370    );
7371}
7372
7373pub trait MethodCandidateCallback {
7374    fn on_inherent_method(&mut self, f: Function) -> ControlFlow<()>;
7375
7376    fn on_trait_method(&mut self, f: Function) -> ControlFlow<()>;
7377}
7378
7379impl<F> MethodCandidateCallback for F
7380where
7381    F: FnMut(Function) -> ControlFlow<()>,
7382{
7383    fn on_inherent_method(&mut self, f: Function) -> ControlFlow<()> {
7384        self(f)
7385    }
7386
7387    fn on_trait_method(&mut self, f: Function) -> ControlFlow<()> {
7388        self(f)
7389    }
7390}
7391
7392pub trait PathCandidateCallback {
7393    fn on_inherent_item(&mut self, item: AssocItem) -> ControlFlow<()>;
7394
7395    fn on_trait_item(&mut self, item: AssocItem) -> ControlFlow<()>;
7396}
7397
7398impl<F> PathCandidateCallback for F
7399where
7400    F: FnMut(AssocItem) -> ControlFlow<()>,
7401{
7402    fn on_inherent_item(&mut self, item: AssocItem) -> ControlFlow<()> {
7403        self(item)
7404    }
7405
7406    fn on_trait_item(&mut self, item: AssocItem) -> ControlFlow<()> {
7407        self(item)
7408    }
7409}
7410
7411pub fn resolve_absolute_path<'a, I: Iterator<Item = Symbol> + Clone + 'a>(
7412    db: &'a dyn HirDatabase,
7413    mut segments: I,
7414) -> impl Iterator<Item = ItemInNs> + use<'a, I> {
7415    segments
7416        .next()
7417        .into_iter()
7418        .flat_map(move |crate_name| {
7419            all_crates(db)
7420                .iter()
7421                .filter(|&krate| {
7422                    krate
7423                        .extra_data(db)
7424                        .display_name
7425                        .as_ref()
7426                        .is_some_and(|name| *name.crate_name().symbol() == crate_name)
7427                })
7428                .filter_map(|&krate| {
7429                    let segments = segments.clone();
7430                    let mut def_map = crate_def_map(db, krate);
7431                    let mut module = &def_map[def_map.root_module_id()];
7432                    let mut segments = segments.with_position().peekable();
7433                    while let Some((_, segment)) =
7434                        segments.next_if(|&(position, _)| !position.is_last)
7435                    {
7436                        let res = module
7437                            .scope
7438                            .get(&Name::new_symbol_root(segment))
7439                            .take_types()
7440                            .and_then(|res| match res {
7441                                ModuleDefId::ModuleId(it) => Some(it),
7442                                _ => None,
7443                            })?;
7444                        def_map = res.def_map(db);
7445                        module = &def_map[res];
7446                    }
7447                    let (_, item_name) = segments.next()?;
7448                    let res = module.scope.get(&Name::new_symbol_root(item_name));
7449                    Some(res.iter_items().map(|(item, _)| item.into()))
7450                })
7451                .collect::<Vec<_>>()
7452        })
7453        .flatten()
7454}
7455
7456fn as_name_opt(name: Option<impl AsName>) -> Name {
7457    name.map_or_else(Name::missing, |name| name.as_name())
7458}
7459
7460#[track_caller]
7461fn generic_args_from_tys<'db>(
7462    interner: DbInterner<'db>,
7463    def_id: SolverDefId<'db>,
7464    args: impl IntoIterator<Item: Borrow<Type<'db>>>,
7465) -> (GenericArgs<'db>, TypeOwnerId<'db>) {
7466    let mut owner = None::<TypeOwnerId<'db>>;
7467    let mut args = args.into_iter();
7468    let args = GenericArgs::for_item(interner, def_id, |_, id, _, _| {
7469        if matches!(id, GenericParamId::TypeParamId(_))
7470            && let Some(arg) = args.next()
7471        {
7472            let arg = arg.borrow();
7473
7474            match &mut owner {
7475                Some(owner) => *owner = owner.must_unify(arg.owner),
7476                None => owner = Some(arg.owner),
7477            }
7478
7479            arg.ty.skip_binder().into()
7480        } else {
7481            next_solver::GenericArg::error_from_id(interner, id)
7482        }
7483    });
7484    let owner =
7485        owner.unwrap_or_else(|| TypeOwnerId::NoParams(Type::builtin_type_crate(interner.db())));
7486    (args, owner)
7487}
7488
7489fn has_non_default_type_params(db: &dyn HirDatabase, generic_def: GenericDefId) -> bool {
7490    let params = GenericParams::of(db, generic_def);
7491    let defaults = db.generic_defaults(generic_def);
7492    params
7493        .iter_type_or_consts()
7494        .filter(|(_, param)| matches!(param, TypeOrConstParamData::TypeParamData(_)))
7495        .map(|(local_id, _)| TypeOrConstParamId { parent: generic_def, local_id })
7496        .any(|param| {
7497            let param = hir_ty::type_or_const_param_idx(db, param);
7498            defaults.get(param as usize).is_none()
7499        })
7500}
7501
7502fn param_env_from_has_crate<'db>(
7503    db: &'db dyn HirDatabase,
7504    id: impl hir_def::HasModule + Into<GenericDefId> + Copy,
7505) -> ParamEnvAndCrate<'db> {
7506    ParamEnvAndCrate { param_env: db.trait_environment(id.into()), krate: id.krate(db) }
7507}
7508
7509// FIXME: We probably don't want to expose this.
7510pub trait MacroCallIdExt {
7511    fn loc(self, db: &dyn HirDatabase) -> &hir_expand::MacroCallLoc;
7512}
7513impl MacroCallIdExt for span::MacroCallId {
7514    #[inline]
7515    fn loc(self, db: &dyn HirDatabase) -> &hir_expand::MacroCallLoc {
7516        hir_expand::MacroCallId::from(self).loc(db)
7517    }
7518}
7519
7520// Like https://github.com/rust-lang/rust/blob/7c3c88f42ad444f4688b865591d84660be4ece2f/compiler/rustc_middle/src/ty/util.rs#L254-L310
7521pub fn struct_tail_raw<'db>(
7522    db: &'db dyn HirDatabase,
7523    interner: DbInterner<'db>,
7524    mut ty: Ty<'db>,
7525    mut normalize: impl FnMut(Ty<'db>) -> Ty<'db>,
7526) -> Ty<'db> {
7527    let recursion_limit = 16;
7528    for iteration in 0.. {
7529        if iteration >= recursion_limit {
7530            return Ty::new_error(interner, ErrorGuaranteed);
7531        }
7532        match ty.kind() {
7533            TyKind::Adt(def, args) => {
7534                let AdtId::StructId(def_id) = def.def_id() else { break };
7535                let last_field = db.field_types(def_id.into()).iter().next_back();
7536                match last_field {
7537                    Some((_, field)) => {
7538                        ty = normalize(field.ty().instantiate(interner, args).skip_norm_wip())
7539                    }
7540                    None => break,
7541                }
7542            }
7543            TyKind::Tuple(tys) if let Some((&last_ty, _)) = tys.split_last() => {
7544                ty = last_ty;
7545            }
7546            TyKind::Tuple(_) => break,
7547            TyKind::Pat(inner, _) => {
7548                ty = inner;
7549            }
7550            _ => {
7551                break;
7552            }
7553        }
7554    }
7555    ty
7556}