Skip to main content

hir/
lib.rs

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