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