Skip to main content

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