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