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