Skip to main content

hir/
lib.rs

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