Skip to main content

hir/
lib.rs

1//! HIR (previously known as descriptors) provides a high-level object-oriented
2//! access to Rust code.
3//!
4//! The principal difference between HIR and syntax trees is that HIR is bound
5//! to a particular crate instance. That is, it has cfg flags and features
6//! applied. So, the relation between syntax and HIR is many-to-one.
7//!
8//! HIR is the public API of the all of the compiler logic above syntax trees.
9//! It is written in "OO" style. Each type is self contained (as in, it knows its
10//! parents and full context). It should be "clean code".
11//!
12//! `hir_*` crates are the implementation of the compiler logic.
13//! They are written in "ECS" style, with relatively little abstractions.
14//! Many types are not self-contained, and explicitly use local indexes, arenas, etc.
15//!
16//! `hir` is what insulates the "we don't know how to actually write an incremental compiler"
17//! from the ide with completions, hovers, etc. It is a (soft, internal) boundary:
18//! <https://www.tedinski.com/2018/02/06/system-boundaries.html>.
19
20#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
21#![recursion_limit = "512"]
22
23extern crate ra_ap_rustc_type_ir as rustc_type_ir;
24
25mod attrs;
26mod from_id;
27mod has_source;
28mod semantics;
29mod source_analyzer;
30
31pub mod db;
32pub mod diagnostics;
33pub mod symbols;
34pub mod term_search;
35
36mod display;
37
38#[doc(hidden)]
39pub use hir_def::ModuleId;
40
41use std::{
42    borrow::Borrow,
43    fmt, iter,
44    ops::{ControlFlow, Not},
45};
46
47use arrayvec::ArrayVec;
48use base_db::{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    fn types_impl(
3142        &self,
3143        db: &'db dyn HirDatabase,
3144    ) -> impl Iterator<Item = (Ty<'db>, Option<Name>)> {
3145        let container = match self.def {
3146            GenericDefId::ConstId(id) => Some(id.lookup(db).container),
3147            GenericDefId::FunctionId(id) => Some(id.lookup(db).container),
3148            GenericDefId::TypeAliasId(id) => Some(id.lookup(db).container),
3149            _ => None,
3150        };
3151        let container_type_params = container
3152            .and_then(|container| match container {
3153                ItemContainerId::ImplId(container) => Some(container.into()),
3154                ItemContainerId::TraitId(container) => Some(container.into()),
3155                _ => None,
3156            })
3157            .map(|container| {
3158                GenericParams::of(db, container)
3159                    .iter_type_or_consts()
3160                    .filter_map(|param| match param.1 {
3161                        TypeOrConstParamData::TypeParamData(param) => Some(param.name.clone()),
3162                        TypeOrConstParamData::ConstParamData(_) => None,
3163                    })
3164                    .collect::<Vec<_>>()
3165            });
3166        let generics = GenericParams::of(db, self.def);
3167        let type_params = generics.iter_type_or_consts().filter_map(|param| match param.1 {
3168            TypeOrConstParamData::TypeParamData(param) => Some(param.name.clone()),
3169            TypeOrConstParamData::ConstParamData(_) => None,
3170        });
3171        self.subst.types().zip(container_type_params.into_iter().flatten().chain(type_params))
3172    }
3173
3174    /// Returns type arguments with type parameter names.
3175    pub fn types(&self, db: &'db dyn HirDatabase) -> Vec<(Symbol, Type<'db>)> {
3176        self.types_impl(db)
3177            .filter_map(|(ty, name)| {
3178                Some((
3179                    name?.symbol().clone(),
3180                    Type { ty: EarlyBinder::bind(ty), owner: self.owner },
3181                ))
3182            })
3183            .collect()
3184    }
3185
3186    /// Returns all type arguments, including unnamed ones such as implicit `impl Trait` parameters.
3187    ///
3188    /// Unlike [`Self::types`], this does not filter out arguments that have no
3189    /// corresponding type parameter name.
3190    // Note: this method is not used by rust-analyzer itself as of writing, but is
3191    // used by external tools, so please do not remove it even if it appears unused.
3192    pub fn all_types(&self, db: &'db dyn HirDatabase) -> Vec<Type<'db>> {
3193        self.types_impl(db)
3194            .map(|(ty, _)| Type { ty: EarlyBinder::bind(ty), owner: self.owner })
3195            .collect()
3196    }
3197}
3198
3199/// A single local definition.
3200#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3201pub struct Local<'db> {
3202    pub(crate) parent: ExpressionStoreOwnerId,
3203    pub(crate) parent_infer: InferBodyId<'db>,
3204    pub(crate) binding_id: BindingId,
3205}
3206
3207pub struct LocalSource<'db> {
3208    pub local: Local<'db>,
3209    pub source: InFile<Either<ast::IdentPat, ast::SelfParam>>,
3210}
3211
3212impl<'db> LocalSource<'db> {
3213    pub fn as_ident_pat(&self) -> Option<&ast::IdentPat> {
3214        match &self.source.value {
3215            Either::Left(it) => Some(it),
3216            Either::Right(_) => None,
3217        }
3218    }
3219
3220    pub fn into_ident_pat(self) -> Option<ast::IdentPat> {
3221        match self.source.value {
3222            Either::Left(it) => Some(it),
3223            Either::Right(_) => None,
3224        }
3225    }
3226
3227    pub fn original_file(&self, db: &dyn HirDatabase) -> EditionedFileId {
3228        self.source.file_id.original_file(db)
3229    }
3230
3231    pub fn file(&self) -> HirFileId {
3232        self.source.file_id
3233    }
3234
3235    pub fn name(&self) -> Option<InFile<ast::Name>> {
3236        self.source.as_ref().map(|it| it.name()).transpose()
3237    }
3238
3239    pub fn syntax(&self) -> &SyntaxNode {
3240        self.source.value.syntax()
3241    }
3242
3243    pub fn syntax_ptr(self) -> InFile<SyntaxNodePtr> {
3244        self.source.map(|it| SyntaxNodePtr::new(it.syntax()))
3245    }
3246}
3247
3248impl<'db> Local<'db> {
3249    pub fn is_param(self, db: &dyn HirDatabase) -> bool {
3250        // FIXME: This parses!
3251        let src = self.primary_source(db);
3252        match src.source.value {
3253            Either::Left(pat) => pat
3254                .syntax()
3255                .ancestors()
3256                .map(|it| it.kind())
3257                .take_while(|&kind| ast::Pat::can_cast(kind) || ast::Param::can_cast(kind))
3258                .any(ast::Param::can_cast),
3259            Either::Right(_) => true,
3260        }
3261    }
3262
3263    pub fn as_self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> {
3264        match self.parent {
3265            ExpressionStoreOwnerId::Body(DefWithBodyId::FunctionId(func)) if self.is_self(db) => {
3266                Some(SelfParam { func: func.into() })
3267            }
3268            _ => None,
3269        }
3270    }
3271
3272    pub fn name(self, db: &dyn HirDatabase) -> Name {
3273        ExpressionStore::of(db, self.parent)[self.binding_id].name.clone()
3274    }
3275
3276    pub fn is_self(self, db: &dyn HirDatabase) -> bool {
3277        self.name(db) == sym::self_
3278    }
3279
3280    pub fn is_mut(self, db: &dyn HirDatabase) -> bool {
3281        ExpressionStore::of(db, self.parent)[self.binding_id].mode == BindingAnnotation::Mutable
3282    }
3283
3284    pub fn is_ref(self, db: &dyn HirDatabase) -> bool {
3285        matches!(
3286            ExpressionStore::of(db, self.parent)[self.binding_id].mode,
3287            BindingAnnotation::Ref | BindingAnnotation::RefMut
3288        )
3289    }
3290
3291    pub fn parent(self, _db: &dyn HirDatabase) -> ExpressionStoreOwner {
3292        self.parent.into()
3293    }
3294
3295    pub fn module(self, db: &dyn HirDatabase) -> Module {
3296        self.parent(db).module(db)
3297    }
3298
3299    pub fn as_id(self) -> u32 {
3300        self.binding_id.into_raw().into_u32()
3301    }
3302
3303    pub fn ty(self, db: &'db dyn HirDatabase) -> Type<'db> {
3304        let def = self.parent;
3305        let infer = InferenceResult::of(db, self.parent_infer);
3306        let ty = infer.binding_ty(self.binding_id);
3307        Type::new_body(db, def, ty)
3308    }
3309
3310    /// All definitions for this local. Example: `let (a$0, _) | (_, a$0) = it;`
3311    pub fn sources(self, db: &dyn HirDatabase) -> Vec<LocalSource<'db>> {
3312        let b;
3313        let (_, source_map) = match self.parent {
3314            ExpressionStoreOwnerId::Signature(generic_def_id) => {
3315                ExpressionStore::with_source_map(db, generic_def_id.into())
3316            }
3317            ExpressionStoreOwnerId::Body(def_with_body_id) => {
3318                b = Body::with_source_map(db, def_with_body_id);
3319                if b.0.is_any_self_param(self.binding_id)
3320                    && let Some(source) = b.1.self_param_syntax()
3321                {
3322                    let root = source.file_syntax(db);
3323                    return vec![LocalSource {
3324                        local: self,
3325                        source: source.map(|ast| Either::Right(ast.to_node(&root))),
3326                    }];
3327                }
3328                (&b.0.store, &b.1.store)
3329            }
3330            ExpressionStoreOwnerId::VariantFields(def) => {
3331                ExpressionStore::with_source_map(db, def.into())
3332            }
3333        };
3334        source_map
3335            .patterns_for_binding(self.binding_id)
3336            .iter()
3337            .map(|&definition| {
3338                let src = source_map.pat_syntax(definition).unwrap(); // Hmm...
3339                let root = src.file_syntax(db);
3340                LocalSource {
3341                    local: self,
3342                    source: src.map(|ast| match ast.to_node(&root) {
3343                        Either::Right(ast::Pat::IdentPat(it)) => Either::Left(it),
3344                        _ => unreachable!("local with non ident-pattern"),
3345                    }),
3346                }
3347            })
3348            .collect()
3349    }
3350
3351    /// The leftmost definition for this local. Example: `let (a$0, _) | (_, a) = it;`
3352    pub fn primary_source(self, db: &dyn HirDatabase) -> LocalSource<'db> {
3353        let b;
3354        let (_, source_map) = match self.parent {
3355            ExpressionStoreOwnerId::Signature(generic_def_id) => {
3356                ExpressionStore::with_source_map(db, generic_def_id.into())
3357            }
3358            ExpressionStoreOwnerId::Body(def_with_body_id) => {
3359                b = Body::with_source_map(db, def_with_body_id);
3360                if b.0.is_any_self_param(self.binding_id)
3361                    && let Some(source) = b.1.self_param_syntax()
3362                {
3363                    let root = source.file_syntax(db);
3364                    return LocalSource {
3365                        local: self,
3366                        source: source.map(|ast| Either::Right(ast.to_node(&root))),
3367                    };
3368                }
3369                (&b.0.store, &b.1.store)
3370            }
3371            ExpressionStoreOwnerId::VariantFields(def) => {
3372                ExpressionStore::with_source_map(db, def.into())
3373            }
3374        };
3375        source_map
3376            .patterns_for_binding(self.binding_id)
3377            .first()
3378            .map(|&definition| {
3379                let src = source_map.pat_syntax(definition).unwrap(); // Hmm...
3380                let root = src.file_syntax(db);
3381                LocalSource {
3382                    local: self,
3383                    source: src.map(|ast| match ast.to_node(&root) {
3384                        Either::Right(ast::Pat::IdentPat(it)) => Either::Left(it),
3385                        _ => unreachable!("local with non ident-pattern"),
3386                    }),
3387                }
3388            })
3389            .unwrap()
3390    }
3391}
3392
3393impl PartialOrd for Local<'_> {
3394    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
3395        Some(self.cmp(other))
3396    }
3397}
3398
3399impl Ord for Local<'_> {
3400    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
3401        self.binding_id.cmp(&other.binding_id)
3402    }
3403}
3404
3405#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3406pub struct DeriveHelper {
3407    pub(crate) derive: MacroId,
3408    pub(crate) idx: u32,
3409}
3410
3411impl DeriveHelper {
3412    pub fn derive(&self) -> Macro {
3413        Macro { id: self.derive }
3414    }
3415
3416    pub fn name(&self, db: &dyn HirDatabase) -> Name {
3417        AttrFlags::derive_info(db, self.derive)
3418            .and_then(|it| it.helpers.get(self.idx as usize))
3419            .map(|helper| Name::new_symbol_root(helper.clone()))
3420            .unwrap_or_else(Name::missing)
3421    }
3422}
3423
3424#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3425pub struct BuiltinAttr {
3426    idx: u32,
3427}
3428
3429impl BuiltinAttr {
3430    fn builtin(name: &str) -> Option<Self> {
3431        hir_expand::inert_attr_macro::find_builtin_attr_idx(&Symbol::intern(name))
3432            .map(|idx| BuiltinAttr { idx: idx as u32 })
3433    }
3434
3435    pub fn name(&self) -> Name {
3436        Name::new_symbol_root(Symbol::intern(
3437            hir_expand::inert_attr_macro::INERT_ATTRIBUTES[self.idx as usize].name,
3438        ))
3439    }
3440
3441    pub fn template(&self) -> Option<AttributeTemplate> {
3442        Some(hir_expand::inert_attr_macro::INERT_ATTRIBUTES[self.idx as usize].template)
3443    }
3444}
3445
3446#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3447pub struct ToolModule {
3448    krate: base_db::Crate,
3449    idx: u32,
3450}
3451
3452impl ToolModule {
3453    pub(crate) fn by_name(db: &dyn HirDatabase, krate: Crate, name: &str) -> Option<Self> {
3454        let krate = krate.id;
3455        let idx =
3456            crate_def_map(db, krate).registered_tools().iter().position(|it| it.as_str() == name)?
3457                as u32;
3458        Some(ToolModule { krate, idx })
3459    }
3460
3461    pub fn name(&self, db: &dyn HirDatabase) -> Name {
3462        Name::new_symbol_root(
3463            crate_def_map(db, self.krate).registered_tools()[self.idx as usize].clone(),
3464        )
3465    }
3466
3467    pub fn krate(&self) -> Crate {
3468        Crate { id: self.krate }
3469    }
3470}
3471
3472#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3473pub struct Label {
3474    pub(crate) parent: ExpressionStoreOwnerId,
3475    pub(crate) label_id: LabelId,
3476}
3477
3478impl Label {
3479    pub fn module(self, db: &dyn HirDatabase) -> Module {
3480        self.parent(db).module(db)
3481    }
3482
3483    pub fn parent(self, _db: &dyn HirDatabase) -> ExpressionStoreOwner {
3484        self.parent.into()
3485    }
3486
3487    pub fn name(self, db: &dyn HirDatabase) -> Name {
3488        ExpressionStore::of(db, self.parent)[self.label_id].name.clone()
3489    }
3490}
3491
3492#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3493pub enum GenericParam {
3494    TypeParam(TypeParam),
3495    ConstParam(ConstParam),
3496    LifetimeParam(LifetimeParam),
3497}
3498impl_from!(TypeParam, ConstParam, LifetimeParam for GenericParam);
3499
3500impl GenericParam {
3501    pub fn module(self, db: &dyn HirDatabase) -> Module {
3502        match self {
3503            GenericParam::TypeParam(it) => it.module(db),
3504            GenericParam::ConstParam(it) => it.module(db),
3505            GenericParam::LifetimeParam(it) => it.module(db),
3506        }
3507    }
3508
3509    pub fn name(self, db: &dyn HirDatabase) -> Name {
3510        match self {
3511            GenericParam::TypeParam(it) => it.name(db),
3512            GenericParam::ConstParam(it) => it.name(db),
3513            GenericParam::LifetimeParam(it) => it.name(db),
3514        }
3515    }
3516
3517    pub fn parent(self) -> GenericDef {
3518        match self {
3519            GenericParam::TypeParam(it) => it.id.parent().into(),
3520            GenericParam::ConstParam(it) => it.id.parent().into(),
3521            GenericParam::LifetimeParam(it) => it.id.parent.into(),
3522        }
3523    }
3524
3525    pub fn variance(self, db: &dyn HirDatabase) -> Option<Variance> {
3526        let parent = match self {
3527            GenericParam::TypeParam(it) => it.id.parent(),
3528            // const parameters are always invariant
3529            GenericParam::ConstParam(_) => return None,
3530            GenericParam::LifetimeParam(it) => it.id.parent,
3531        };
3532        let index = match self {
3533            GenericParam::TypeParam(it) => hir_ty::type_or_const_param_idx(db, it.id.into()),
3534            GenericParam::ConstParam(_) => return None,
3535            GenericParam::LifetimeParam(it) => hir_ty::lifetime_param_idx(db, it.id),
3536        };
3537        db.variances_of(parent).get(index as usize).map(Into::into)
3538    }
3539}
3540
3541#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3542pub enum Variance {
3543    Bivariant,
3544    Covariant,
3545    Contravariant,
3546    Invariant,
3547}
3548
3549impl From<rustc_type_ir::Variance> for Variance {
3550    #[inline]
3551    fn from(value: rustc_type_ir::Variance) -> Self {
3552        match value {
3553            rustc_type_ir::Variance::Covariant => Variance::Covariant,
3554            rustc_type_ir::Variance::Invariant => Variance::Invariant,
3555            rustc_type_ir::Variance::Contravariant => Variance::Contravariant,
3556            rustc_type_ir::Variance::Bivariant => Variance::Bivariant,
3557        }
3558    }
3559}
3560
3561impl fmt::Display for Variance {
3562    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3563        let description = match self {
3564            Variance::Bivariant => "bivariant",
3565            Variance::Covariant => "covariant",
3566            Variance::Contravariant => "contravariant",
3567            Variance::Invariant => "invariant",
3568        };
3569        f.pad(description)
3570    }
3571}
3572
3573#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3574pub struct TypeParam {
3575    pub(crate) id: TypeParamId,
3576}
3577
3578impl TypeParam {
3579    pub fn merge(self) -> TypeOrConstParam {
3580        TypeOrConstParam { id: self.id.into() }
3581    }
3582
3583    pub fn name(self, db: &dyn HirDatabase) -> Name {
3584        self.merge().name(db)
3585    }
3586
3587    pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef {
3588        self.id.parent().into()
3589    }
3590
3591    pub fn module(self, db: &dyn HirDatabase) -> Module {
3592        self.id.parent().module(db).into()
3593    }
3594
3595    /// Is this type parameter implicitly introduced (eg. `Self` in a trait or an `impl Trait`
3596    /// argument)?
3597    pub fn is_implicit(self, db: &dyn HirDatabase) -> bool {
3598        let params = GenericParams::of(db, self.id.parent());
3599        let data = &params[self.id.local_id()];
3600        match data.type_param().unwrap().provenance {
3601            TypeParamProvenance::TypeParamList => false,
3602            TypeParamProvenance::TraitSelf | TypeParamProvenance::ArgumentImplTrait => true,
3603        }
3604    }
3605
3606    pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
3607        let interner = DbInterner::new_no_crate(db);
3608        let index = hir_ty::type_or_const_param_idx(db, self.id.into());
3609        let ty = Ty::new_param(interner, self.id, index);
3610        Type::new(self.id.parent(), ty)
3611    }
3612
3613    /// FIXME: this only lists trait bounds from the item defining the type
3614    /// parameter, not additional bounds that might be added e.g. by a method if
3615    /// the parameter comes from an impl!
3616    pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> {
3617        let self_ty = self.ty(db).ty.instantiate_identity().skip_norm_wip();
3618        GenericPredicates::query_explicit(db, self.id.parent())
3619            .iter_identity()
3620            .filter_map(|pred| match &pred.kind().skip_binder() {
3621                ClauseKind::Trait(trait_ref) if trait_ref.self_ty() == self_ty => {
3622                    Some(Trait::from(trait_ref.def_id().0))
3623                }
3624                _ => None,
3625            })
3626            .collect()
3627    }
3628
3629    pub fn default(self, db: &dyn HirDatabase) -> Option<Type<'_>> {
3630        let ty = generic_arg_from_param(db, self.id.into())?;
3631        match ty.kind() {
3632            rustc_type_ir::GenericArgKind::Type(it) if !it.is_ty_error() => {
3633                Some(Type::new(self.id.parent(), it))
3634            }
3635            _ => None,
3636        }
3637    }
3638
3639    pub fn is_unstable(self, db: &dyn HirDatabase) -> bool {
3640        self.attrs(db).is_unstable()
3641    }
3642}
3643
3644#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3645pub struct LifetimeParam {
3646    pub(crate) id: LifetimeParamId,
3647}
3648
3649impl LifetimeParam {
3650    pub fn name(self, db: &dyn HirDatabase) -> Name {
3651        let params = GenericParams::of(db, self.id.parent);
3652        params[self.id.local_id].name.clone()
3653    }
3654
3655    pub fn module(self, db: &dyn HirDatabase) -> Module {
3656        self.id.parent.module(db).into()
3657    }
3658
3659    pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef {
3660        self.id.parent.into()
3661    }
3662}
3663
3664#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3665pub struct ConstParam {
3666    pub(crate) id: ConstParamId,
3667}
3668
3669impl ConstParam {
3670    pub fn merge(self) -> TypeOrConstParam {
3671        TypeOrConstParam { id: self.id.into() }
3672    }
3673
3674    pub fn name(self, db: &dyn HirDatabase) -> Name {
3675        let params = GenericParams::of(db, self.id.parent());
3676        match params[self.id.local_id()].name() {
3677            Some(it) => it.clone(),
3678            None => {
3679                never!();
3680                Name::missing()
3681            }
3682        }
3683    }
3684
3685    pub fn module(self, db: &dyn HirDatabase) -> Module {
3686        self.id.parent().module(db).into()
3687    }
3688
3689    pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef {
3690        self.id.parent().into()
3691    }
3692
3693    pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
3694        Type::new(self.id.parent(), db.const_param_ty(self.id))
3695    }
3696
3697    pub fn default(self, db: &dyn HirDatabase, display_target: DisplayTarget) -> Option<String> {
3698        let arg = generic_arg_from_param(db, self.id.into())?;
3699        Some(arg.display(db, display_target).to_string())
3700    }
3701
3702    pub fn default_source_code(
3703        self,
3704        db: &dyn HirDatabase,
3705        target_module: Module,
3706    ) -> Option<ast::ConstArg> {
3707        let arg = generic_arg_from_param(db, self.id.into())?;
3708        known_const_to_ast(arg.konst()?, db, target_module.id)
3709    }
3710}
3711
3712fn generic_arg_from_param(db: &dyn HirDatabase, id: TypeOrConstParamId) -> Option<GenericArg<'_>> {
3713    let local_idx = hir_ty::type_or_const_param_idx(db, id);
3714    let defaults = db.generic_defaults(id.parent);
3715    let ty = defaults.get(local_idx as usize)?;
3716    // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s.
3717    Some(ty.instantiate_identity().skip_norm_wip())
3718}
3719
3720#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3721pub struct TypeOrConstParam {
3722    pub(crate) id: TypeOrConstParamId,
3723}
3724
3725impl TypeOrConstParam {
3726    pub fn name(self, db: &dyn HirDatabase) -> Name {
3727        let params = GenericParams::of(db, self.id.parent);
3728        match params[self.id.local_id].name() {
3729            Some(n) => n.clone(),
3730            _ => Name::missing(),
3731        }
3732    }
3733
3734    pub fn module(self, db: &dyn HirDatabase) -> Module {
3735        self.id.parent.module(db).into()
3736    }
3737
3738    pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef {
3739        self.id.parent.into()
3740    }
3741
3742    pub fn split(self, db: &dyn HirDatabase) -> Either<ConstParam, TypeParam> {
3743        let params = GenericParams::of(db, self.id.parent);
3744        match &params[self.id.local_id] {
3745            TypeOrConstParamData::TypeParamData(_) => {
3746                Either::Right(TypeParam { id: TypeParamId::from_unchecked(self.id) })
3747            }
3748            TypeOrConstParamData::ConstParamData(_) => {
3749                Either::Left(ConstParam { id: ConstParamId::from_unchecked(self.id) })
3750            }
3751        }
3752    }
3753
3754    pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
3755        match self.split(db) {
3756            Either::Left(it) => it.ty(db),
3757            Either::Right(it) => it.ty(db),
3758        }
3759    }
3760
3761    pub fn as_type_param(self, db: &dyn HirDatabase) -> Option<TypeParam> {
3762        let params = GenericParams::of(db, self.id.parent);
3763        match &params[self.id.local_id] {
3764            TypeOrConstParamData::TypeParamData(_) => {
3765                Some(TypeParam { id: TypeParamId::from_unchecked(self.id) })
3766            }
3767            TypeOrConstParamData::ConstParamData(_) => None,
3768        }
3769    }
3770
3771    pub fn as_const_param(self, db: &dyn HirDatabase) -> Option<ConstParam> {
3772        let params = GenericParams::of(db, self.id.parent);
3773        match &params[self.id.local_id] {
3774            TypeOrConstParamData::TypeParamData(_) => None,
3775            TypeOrConstParamData::ConstParamData(_) => {
3776                Some(ConstParam { id: ConstParamId::from_unchecked(self.id) })
3777            }
3778        }
3779    }
3780}
3781
3782#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3783pub struct Impl {
3784    pub(crate) id: AnyImplId,
3785}
3786
3787impl Impl {
3788    pub fn all_in_crate(db: &dyn HirDatabase, krate: Crate) -> Vec<Impl> {
3789        let mut result = Vec::new();
3790        extend_with_def_map(db, crate_def_map(db, krate.id), &mut result);
3791        return result;
3792
3793        fn extend_with_def_map(db: &dyn HirDatabase, def_map: &DefMap, result: &mut Vec<Impl>) {
3794            for (_, module) in def_map.modules() {
3795                result.extend(module.scope.impls().map(Impl::from));
3796                result.extend(module.scope.builtin_derive_impls().map(Impl::from));
3797
3798                for unnamed_const in module.scope.unnamed_consts() {
3799                    for (_, block_def_map) in Body::of(db, unnamed_const.into()).blocks(db) {
3800                        extend_with_def_map(db, block_def_map, result);
3801                    }
3802                }
3803            }
3804        }
3805    }
3806
3807    pub fn all_in_module(db: &dyn HirDatabase, module: Module) -> Vec<Impl> {
3808        module.impl_defs(db)
3809    }
3810
3811    /// **Note:** This is an **approximation** that strives to give the *human-perceived notion* of an "impl for type",
3812    /// **not** answer the technical question "what are all impls applying to this type". In particular, it excludes
3813    /// blanket impls, and only does a shallow type constructor check. In fact, this should've probably been on `Adt`
3814    /// etc., and not on `Type`. If you would want to create a precise list of all impls applying to a type,
3815    /// you would need to include blanket impls, and try to prove to predicates for each candidate.
3816    pub fn all_for_type<'db>(db: &'db dyn HirDatabase, ty: Type<'db>) -> Vec<Impl> {
3817        let mut result = Vec::new();
3818        let interner = DbInterner::new_no_crate(db);
3819        let Some(simplified_ty) = fast_reject::simplify_type(
3820            interner,
3821            ty.ty.skip_binder(),
3822            fast_reject::TreatParams::AsRigid,
3823        ) else {
3824            return Vec::new();
3825        };
3826        let mut extend_with_impls = |impls: Either<&[ImplId], &[BuiltinDeriveImplId]>| match impls {
3827            Either::Left(impls) => result.extend(impls.iter().copied().map(Impl::from)),
3828            Either::Right(impls) => result.extend(impls.iter().copied().map(Impl::from)),
3829        };
3830        method_resolution::with_incoherent_inherent_impls(
3831            db,
3832            ty.krate(db),
3833            &simplified_ty,
3834            |impls| extend_with_impls(Either::Left(impls)),
3835        );
3836        if let Some(module) = method_resolution::simplified_type_module(db, &simplified_ty) {
3837            InherentImpls::for_each_crate_and_block(
3838                db,
3839                module.krate(db),
3840                module.block(db),
3841                &mut |impls| extend_with_impls(Either::Left(impls.for_self_ty(&simplified_ty))),
3842            );
3843            std::iter::successors(module.block(db), |block| block.module(db).block(db))
3844                .filter_map(|block| TraitImpls::for_block(db, block))
3845                .for_each(|impls| impls.for_self_ty(&simplified_ty, &mut extend_with_impls));
3846            for &krate in &*all_crates(db) {
3847                TraitImpls::for_crate(db, krate)
3848                    .for_self_ty(&simplified_ty, &mut extend_with_impls);
3849            }
3850        } else {
3851            for &krate in &*all_crates(db) {
3852                TraitImpls::for_crate(db, krate)
3853                    .for_self_ty(&simplified_ty, &mut extend_with_impls);
3854            }
3855        }
3856        result
3857    }
3858
3859    pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> {
3860        let module = trait_.module(db).id;
3861        let mut all = Vec::new();
3862        let mut handle_impls = |impls: &TraitImpls<'_>| {
3863            impls.for_trait(trait_.id, |impls| match impls {
3864                Either::Left(impls) => all.extend(impls.iter().copied().map(Impl::from)),
3865                Either::Right(impls) => all.extend(impls.iter().copied().map(Impl::from)),
3866            });
3867        };
3868        for krate in module.krate(db).transitive_rev_deps(db) {
3869            handle_impls(TraitImpls::for_crate(db, krate));
3870        }
3871        if let Some(block) = module.block(db)
3872            && let Some(impls) = TraitImpls::for_block(db, block)
3873        {
3874            handle_impls(impls);
3875        }
3876        all
3877    }
3878
3879    pub fn trait_(self, db: &dyn HirDatabase) -> Option<Trait> {
3880        match self.id {
3881            AnyImplId::ImplId(id) => {
3882                let trait_ref = db.impl_trait(id)?;
3883                let id = trait_ref.skip_binder().def_id;
3884                Some(Trait { id: id.0 })
3885            }
3886            AnyImplId::BuiltinDeriveImplId(id) => {
3887                let loc = id.loc(db);
3888                let lang_items = hir_def::lang_item::lang_items(db, loc.adt.module(db).krate(db));
3889                loc.trait_.get_id(lang_items).map(Trait::from)
3890            }
3891        }
3892    }
3893
3894    pub fn trait_ref(self, db: &dyn HirDatabase) -> Option<TraitRef<'_>> {
3895        match self.id {
3896            AnyImplId::ImplId(id) => {
3897                let trait_ref = db.impl_trait(id)?.instantiate_identity().skip_norm_wip();
3898                Some(TraitRef::new(id.into(), trait_ref))
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 trait_ref = hir_ty::builtin_derive::impl_trait(interner, id)
3905                    .instantiate_identity()
3906                    .skip_norm_wip();
3907                Some(TraitRef { owner: TypeOwnerId::BuiltinDeriveImplId(id), trait_ref })
3908            }
3909        }
3910    }
3911
3912    pub fn self_ty(self, db: &dyn HirDatabase) -> Type<'_> {
3913        match self.id {
3914            AnyImplId::ImplId(id) => {
3915                let ty = db.impl_self_ty(id).instantiate_identity().skip_norm_wip();
3916                Type::new(id.into(), ty)
3917            }
3918            AnyImplId::BuiltinDeriveImplId(id) => {
3919                let loc = id.loc(db);
3920                let krate = loc.module(db).krate(db);
3921                let interner = DbInterner::new_with(db, krate);
3922                let ty =
3923                    hir_ty::builtin_derive::impl_trait(interner, id).map_bound(|it| it.self_ty());
3924                Type { owner: TypeOwnerId::BuiltinDeriveImplId(id), ty }
3925            }
3926        }
3927    }
3928
3929    pub fn items(self, db: &dyn HirDatabase) -> Vec<AssocItem> {
3930        match self.id {
3931            AnyImplId::ImplId(id) => {
3932                id.impl_items(db).items.iter().map(|&(_, it)| it.into()).collect()
3933            }
3934            AnyImplId::BuiltinDeriveImplId(impl_) => impl_
3935                .loc(db)
3936                .trait_
3937                .all_methods()
3938                .iter()
3939                .map(|&method| {
3940                    AssocItem::Function(Function {
3941                        id: AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ },
3942                    })
3943                })
3944                .collect(),
3945        }
3946    }
3947
3948    pub fn is_negative(self, db: &dyn HirDatabase) -> bool {
3949        match self.id {
3950            AnyImplId::ImplId(id) => ImplSignature::of(db, id).flags.contains(ImplFlags::NEGATIVE),
3951            AnyImplId::BuiltinDeriveImplId(_) => false,
3952        }
3953    }
3954
3955    pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool {
3956        match self.id {
3957            AnyImplId::ImplId(id) => ImplSignature::of(db, id).flags.contains(ImplFlags::UNSAFE),
3958            AnyImplId::BuiltinDeriveImplId(_) => false,
3959        }
3960    }
3961
3962    pub fn module(self, db: &dyn HirDatabase) -> Module {
3963        match self.id {
3964            AnyImplId::ImplId(id) => id.module(db).into(),
3965            AnyImplId::BuiltinDeriveImplId(id) => id.module(db).into(),
3966        }
3967    }
3968
3969    pub fn check_orphan_rules(self, db: &dyn HirDatabase) -> bool {
3970        match self.id {
3971            AnyImplId::ImplId(id) => check_orphan_rules(db, id),
3972            AnyImplId::BuiltinDeriveImplId(_) => true,
3973        }
3974    }
3975}
3976
3977#[derive(Clone, PartialEq, Eq, Debug, Hash)]
3978pub struct TraitRef<'db> {
3979    owner: TypeOwnerId,
3980    trait_ref: hir_ty::next_solver::TraitRef<'db>,
3981}
3982
3983impl<'db> TraitRef<'db> {
3984    fn new(owner: GenericDefId, trait_ref: hir_ty::next_solver::TraitRef<'db>) -> Self {
3985        Self { owner: TypeOwnerId::GenericDefId(owner), trait_ref }
3986    }
3987
3988    pub fn trait_(&self) -> Trait {
3989        Trait { id: self.trait_ref.def_id.0 }
3990    }
3991
3992    pub fn self_ty(&self) -> Type<'_> {
3993        let ty = self.trait_ref.self_ty();
3994        Type { owner: self.owner, ty: EarlyBinder::bind(ty) }
3995    }
3996
3997    /// Returns `idx`-th argument of this trait reference if it is a type argument. Note that the
3998    /// first argument is the `Self` type.
3999    pub fn get_type_argument(&self, idx: usize) -> Option<Type<'db>> {
4000        self.trait_ref
4001            .args
4002            .as_slice()
4003            .get(idx)
4004            .and_then(|arg| arg.ty())
4005            .map(|ty| Type { owner: self.owner, ty: EarlyBinder::bind(ty) })
4006    }
4007}
4008
4009#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4010enum AnyClosureId<'db> {
4011    ClosureId(InternedClosureId<'db>),
4012    CoroutineClosureId(InternedCoroutineClosureId<'db>),
4013}
4014
4015#[derive(Clone, Debug, PartialEq, Eq, Hash)]
4016pub struct Closure<'db> {
4017    owner: TypeOwnerId,
4018    id: AnyClosureId<'db>,
4019    subst: GenericArgs<'db>,
4020}
4021
4022impl<'db> Closure<'db> {
4023    fn as_ty(&self, db: &'db dyn HirDatabase) -> Ty<'db> {
4024        let interner = DbInterner::new_no_crate(db);
4025        match self.id {
4026            AnyClosureId::ClosureId(id) => Ty::new_closure(interner, id.into(), self.subst),
4027            AnyClosureId::CoroutineClosureId(id) => {
4028                Ty::new_coroutine_closure(interner, id.into(), self.subst)
4029            }
4030        }
4031    }
4032
4033    pub fn display_with_id(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String {
4034        self.as_ty(db)
4035            .display(db, display_target)
4036            .with_closure_style(ClosureStyle::ClosureWithId)
4037            .to_string()
4038    }
4039
4040    pub fn display_with_impl(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String {
4041        self.as_ty(db)
4042            .display(db, display_target)
4043            .with_closure_style(ClosureStyle::ImplFn)
4044            .to_string()
4045    }
4046
4047    pub fn captured_items(&self, db: &'db dyn HirDatabase) -> Vec<ClosureCapture<'db>> {
4048        let closure = match self.id {
4049            AnyClosureId::ClosureId(it) => it.loc(db),
4050            AnyClosureId::CoroutineClosureId(it) => it.loc(db),
4051        };
4052        captured_items(db, closure)
4053    }
4054
4055    pub fn fn_trait(&self, _db: &dyn HirDatabase) -> FnTrait {
4056        match self.id {
4057            AnyClosureId::ClosureId(_) => match self.subst.as_closure().kind() {
4058                rustc_type_ir::ClosureKind::Fn => FnTrait::Fn,
4059                rustc_type_ir::ClosureKind::FnMut => FnTrait::FnMut,
4060                rustc_type_ir::ClosureKind::FnOnce => FnTrait::FnOnce,
4061            },
4062            AnyClosureId::CoroutineClosureId(_) => match self.subst.as_coroutine_closure().kind() {
4063                rustc_type_ir::ClosureKind::Fn => FnTrait::AsyncFn,
4064                rustc_type_ir::ClosureKind::FnMut => FnTrait::AsyncFnMut,
4065                rustc_type_ir::ClosureKind::FnOnce => FnTrait::AsyncFnOnce,
4066            },
4067        }
4068    }
4069}
4070
4071/// A coroutine expression, including async, generator, and async-generator coroutines.
4072#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4073pub struct Coroutine<'db> {
4074    id: InternedCoroutineId<'db>,
4075}
4076
4077impl<'db> Coroutine<'db> {
4078    /// Returns the values captured by this coroutine.
4079    pub fn captured_items(&self, db: &'db dyn HirDatabase) -> Vec<ClosureCapture<'db>> {
4080        captured_items(db, self.id.loc(db))
4081    }
4082}
4083
4084fn captured_items<'db>(
4085    db: &'db dyn HirDatabase,
4086    closure: InternedClosure<'db>,
4087) -> Vec<ClosureCapture<'db>> {
4088    let InternedClosure { owner: infer_owner, expr: closure, .. } = closure;
4089    let infer = InferenceResult::of(db, infer_owner);
4090    let owner = infer_owner.expression_store_owner(db);
4091    infer.closures_data[&closure]
4092        .min_captures
4093        .values()
4094        .flatten()
4095        .map(|capture| ClosureCapture { owner, infer_owner, closure, capture })
4096        .collect()
4097}
4098
4099#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4100pub enum FnTrait {
4101    FnOnce,
4102    FnMut,
4103    Fn,
4104
4105    AsyncFnOnce,
4106    AsyncFnMut,
4107    AsyncFn,
4108}
4109
4110impl From<traits::FnTrait> for FnTrait {
4111    fn from(value: traits::FnTrait) -> Self {
4112        match value {
4113            traits::FnTrait::FnOnce => FnTrait::FnOnce,
4114            traits::FnTrait::FnMut => FnTrait::FnMut,
4115            traits::FnTrait::Fn => FnTrait::Fn,
4116            traits::FnTrait::AsyncFnOnce => FnTrait::AsyncFnOnce,
4117            traits::FnTrait::AsyncFnMut => FnTrait::AsyncFnMut,
4118            traits::FnTrait::AsyncFn => FnTrait::AsyncFn,
4119        }
4120    }
4121}
4122
4123impl fmt::Display for FnTrait {
4124    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4125        match self {
4126            FnTrait::FnOnce => write!(f, "FnOnce"),
4127            FnTrait::FnMut => write!(f, "FnMut"),
4128            FnTrait::Fn => write!(f, "Fn"),
4129            FnTrait::AsyncFnOnce => write!(f, "AsyncFnOnce"),
4130            FnTrait::AsyncFnMut => write!(f, "AsyncFnMut"),
4131            FnTrait::AsyncFn => write!(f, "AsyncFn"),
4132        }
4133    }
4134}
4135
4136impl FnTrait {
4137    pub const fn function_name(&self) -> &'static str {
4138        match self {
4139            FnTrait::FnOnce => "call_once",
4140            FnTrait::FnMut => "call_mut",
4141            FnTrait::Fn => "call",
4142            FnTrait::AsyncFnOnce => "async_call_once",
4143            FnTrait::AsyncFnMut => "async_call_mut",
4144            FnTrait::AsyncFn => "async_call",
4145        }
4146    }
4147
4148    pub fn lang_item(self) -> LangItem {
4149        match self {
4150            FnTrait::FnOnce => LangItem::FnOnce,
4151            FnTrait::FnMut => LangItem::FnMut,
4152            FnTrait::Fn => LangItem::Fn,
4153            FnTrait::AsyncFnOnce => LangItem::AsyncFnOnce,
4154            FnTrait::AsyncFnMut => LangItem::AsyncFnMut,
4155            FnTrait::AsyncFn => LangItem::AsyncFn,
4156        }
4157    }
4158
4159    pub fn get_id(self, db: &dyn HirDatabase, krate: Crate) -> Option<Trait> {
4160        Trait::lang(db, krate, self.lang_item())
4161    }
4162}
4163
4164#[derive(Clone, Debug, PartialEq, Eq)]
4165pub struct ClosureCapture<'db> {
4166    owner: ExpressionStoreOwnerId,
4167    infer_owner: InferBodyId<'db>,
4168    closure: ExprId,
4169    capture: &'db hir_ty::closure_analysis::CapturedPlace,
4170}
4171
4172impl<'db> ClosureCapture<'db> {
4173    pub fn local(&self) -> Local<'db> {
4174        Local {
4175            parent: self.owner,
4176            parent_infer: self.infer_owner,
4177            binding_id: self.capture.captured_local(),
4178        }
4179    }
4180
4181    /// Returns whether this place has any field (aka. non-deref) projections.
4182    pub fn has_field_projections(&self) -> bool {
4183        self.capture
4184            .place
4185            .projections
4186            .iter()
4187            .any(|proj| matches!(proj.kind, hir_ty::closure_analysis::ProjectionKind::Field { .. }))
4188    }
4189
4190    pub fn usages(&self) -> CaptureUsages<'db> {
4191        CaptureUsages { parent: self.owner, sources: &self.capture.info.sources }
4192    }
4193
4194    pub fn kind(&self) -> CaptureKind {
4195        match self.capture.info.capture_kind {
4196            hir_ty::closure_analysis::UpvarCapture::ByValue => CaptureKind::Move,
4197            hir_ty::closure_analysis::UpvarCapture::ByUse => CaptureKind::SharedRef, // Good enough?
4198            hir_ty::closure_analysis::UpvarCapture::ByRef(
4199                hir_ty::closure_analysis::BorrowKind::Immutable,
4200            ) => CaptureKind::SharedRef,
4201            hir_ty::closure_analysis::UpvarCapture::ByRef(
4202                hir_ty::closure_analysis::BorrowKind::UniqueImmutable,
4203            ) => CaptureKind::UniqueSharedRef,
4204            hir_ty::closure_analysis::UpvarCapture::ByRef(
4205                hir_ty::closure_analysis::BorrowKind::Mutable,
4206            ) => CaptureKind::MutableRef,
4207        }
4208    }
4209
4210    /// Converts the place to a name that can be inserted into source code.
4211    pub fn place_to_name(&self, db: &dyn HirDatabase, edition: Edition) -> String {
4212        let mut result = self.local().name(db).display(db, edition).to_string();
4213        for (i, proj) in self.capture.place.projections.iter().enumerate() {
4214            match proj.kind {
4215                hir_ty::closure_analysis::ProjectionKind::Deref => {}
4216                hir_ty::closure_analysis::ProjectionKind::Field { field_idx, variant_idx } => {
4217                    let ty = self.capture.place.ty_before_projection(i);
4218                    match ty.kind() {
4219                        TyKind::Tuple(_) => format_to!(result, "_{field_idx}"),
4220                        TyKind::Adt(adt_def, _) => {
4221                            let variant = match adt_def.def_id() {
4222                                AdtId::StructId(id) => VariantId::from(id),
4223                                AdtId::UnionId(id) => id.into(),
4224                                AdtId::EnumId(id) => {
4225                                    id.enum_variants(db).variants[variant_idx as usize].0.into()
4226                                }
4227                            };
4228                            let field = &variant.fields(db).fields()
4229                                [LocalFieldId::from_raw(la_arena::RawIdx::from_u32(field_idx))];
4230                            format_to!(result, "_{}", field.name.display(db, edition));
4231                        }
4232                        _ => never!("mismatching projection type"),
4233                    }
4234                }
4235                _ => never!("unexpected projection kind"),
4236            }
4237        }
4238        result
4239    }
4240
4241    pub fn display_place_source_code(&self, db: &dyn HirDatabase, edition: Edition) -> String {
4242        let mut result = self.local().name(db).display(db, edition).to_string();
4243        // We only need the derefs that have no field access after them, autoderef will do the rest.
4244        let mut last_derefs = 0;
4245        for (i, proj) in self.capture.place.projections.iter().enumerate() {
4246            match proj.kind {
4247                hir_ty::closure_analysis::ProjectionKind::Deref => last_derefs += 1,
4248                hir_ty::closure_analysis::ProjectionKind::Field { field_idx, variant_idx } => {
4249                    last_derefs = 0;
4250
4251                    let ty = self.capture.place.ty_before_projection(i);
4252                    match ty.kind() {
4253                        TyKind::Tuple(_) => format_to!(result, ".{field_idx}"),
4254                        TyKind::Adt(adt_def, _) => {
4255                            let variant = match adt_def.def_id() {
4256                                AdtId::StructId(id) => VariantId::from(id),
4257                                AdtId::UnionId(id) => id.into(),
4258                                AdtId::EnumId(id) => {
4259                                    // Can't really do that for an enum, unfortunately, so try to do something alike.
4260                                    id.enum_variants(db).variants[variant_idx as usize].0.into()
4261                                }
4262                            };
4263                            let field = &variant.fields(db).fields()
4264                                [LocalFieldId::from_raw(la_arena::RawIdx::from_u32(field_idx))];
4265                            format_to!(result, ".{}", field.name.display(db, edition));
4266                        }
4267                        _ => never!("mismatching projection type"),
4268                    }
4269                }
4270                _ => never!("unexpected projection kind"),
4271            }
4272        }
4273        result.insert_str(0, &"*".repeat(last_derefs));
4274        result
4275    }
4276
4277    pub fn ty(&self, db: &'db dyn HirDatabase) -> Type<'db> {
4278        Type::new_body(db, self.owner, self.capture.place.ty())
4279    }
4280
4281    /// The type that is stored in the closure, which is different from [`Self::ty()`], representing
4282    /// the place's type, when the capture is by ref.
4283    pub fn captured_ty(&self, db: &'db dyn HirDatabase) -> Type<'db> {
4284        Type::new_body(db, self.owner, self.capture.captured_ty(db))
4285    }
4286}
4287
4288#[derive(Clone, Copy, PartialEq, Eq)]
4289pub enum CaptureKind {
4290    SharedRef,
4291    UniqueSharedRef,
4292    MutableRef,
4293    Move,
4294}
4295
4296#[derive(Debug, Clone)]
4297pub struct CaptureUsages<'db> {
4298    parent: ExpressionStoreOwnerId,
4299    sources: &'db [hir_ty::closure_analysis::CaptureSourceStack],
4300}
4301
4302impl CaptureUsages<'_> {
4303    fn is_ref(store: &ExpressionStore, id: ExprOrPatId) -> bool {
4304        match id {
4305            ExprOrPatId::ExprId(expr) => matches!(store[expr], Expr::Ref { .. }),
4306            // FIXME: Figure out if this is correct wrt. match ergonomics.
4307            ExprOrPatId::PatId(pat) => match store[pat] {
4308                Pat::Bind { id: binding, .. } => matches!(
4309                    store[binding].mode,
4310                    BindingAnnotation::Ref | BindingAnnotation::RefMut
4311                ),
4312                _ => false,
4313            },
4314        }
4315    }
4316
4317    pub fn sources(&self, db: &dyn HirDatabase) -> Vec<CaptureUsageSource> {
4318        let (store, source_map) = ExpressionStore::with_source_map(db, self.parent);
4319        let mut result = Vec::with_capacity(self.sources.len());
4320        for source in self.sources {
4321            let source = source.final_source();
4322            let is_ref = Self::is_ref(store, source.unpack());
4323            match source.unpack() {
4324                ExprOrPatId::ExprId(expr) => {
4325                    if let Ok(expr) = source_map.expr_syntax(expr) {
4326                        result.push(CaptureUsageSource { is_ref, source: expr })
4327                    }
4328                }
4329                ExprOrPatId::PatId(pat) => {
4330                    if let Ok(pat) = source_map.pat_syntax(pat) {
4331                        result.push(CaptureUsageSource { is_ref, source: pat });
4332                    }
4333                }
4334            }
4335        }
4336        result
4337    }
4338}
4339
4340#[derive(Debug)]
4341pub struct CaptureUsageSource {
4342    is_ref: bool,
4343    source: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
4344}
4345
4346impl CaptureUsageSource {
4347    pub fn source(&self) -> AstPtr<Either<ast::Expr, ast::Pat>> {
4348        self.source.value
4349    }
4350
4351    pub fn file_id(&self) -> HirFileId {
4352        self.source.file_id
4353    }
4354
4355    pub fn is_ref(&self) -> bool {
4356        self.is_ref
4357    }
4358}
4359
4360#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
4361enum TypeOwnerId {
4362    GenericDefId(GenericDefId),
4363    BuiltinDeriveImplId(BuiltinDeriveImplId),
4364    // FIXME: What do when we unify two different crates? Currently we just randomly keep one.
4365    NoParams(base_db::Crate),
4366}
4367
4368impl_from!(
4369    GenericDefId,
4370    BuiltinDeriveImplId
4371    for TypeOwnerId
4372);
4373
4374impl TypeOwnerId {
4375    /// We associated anon consts with their parent, because they can never have generics of their own.
4376    /// It can have *less* than the parent, but providing more generic args is not a problem.
4377    fn from_anon_const<'db>(id: AnonConstId<'db>, db: &'db dyn HirDatabase) -> TypeOwnerId {
4378        TypeOwnerId::GenericDefId(id.loc(db).owner.generic_def(db))
4379    }
4380
4381    fn unify(self, other: Self) -> Option<Self> {
4382        match (self, other) {
4383            (TypeOwnerId::NoParams(_), owner) => Some(owner),
4384            (owner, TypeOwnerId::NoParams(_)) => Some(owner),
4385            (_, _) => {
4386                if self == other {
4387                    Some(self)
4388                } else {
4389                    None
4390                }
4391            }
4392        }
4393    }
4394
4395    #[track_caller]
4396    fn must_unify(self, other: Self) -> Self {
4397        self.unify(other).expect("failed to unify type owners")
4398    }
4399
4400    fn can_rebase_into(
4401        self,
4402        db: &dyn HirDatabase,
4403        rebase_into: Self,
4404        self_ty: EarlyBinder<'_, Ty<'_>>,
4405    ) -> bool {
4406        if self == rebase_into || !self_ty.skip_binder().has_param() {
4407            return true;
4408        }
4409        let self_def = match self {
4410            TypeOwnerId::GenericDefId(def) => def,
4411            TypeOwnerId::BuiltinDeriveImplId(_) => return false,
4412            TypeOwnerId::NoParams(_) => return true,
4413        };
4414        let self_def = match self_def {
4415            GenericDefId::ImplId(def) => ItemContainerId::ImplId(def),
4416            GenericDefId::TraitId(def) => ItemContainerId::TraitId(def),
4417            GenericDefId::AdtId(_)
4418            | GenericDefId::ConstId(_)
4419            | GenericDefId::FunctionId(_)
4420            | GenericDefId::StaticId(_)
4421            | GenericDefId::TypeAliasId(_) => return false,
4422        };
4423        let rebase_into_def = match rebase_into {
4424            TypeOwnerId::GenericDefId(def) => def,
4425            TypeOwnerId::BuiltinDeriveImplId(_) | TypeOwnerId::NoParams(_) => return false,
4426        };
4427        let rebase_into_parent = match rebase_into_def {
4428            GenericDefId::ConstId(def) => def.loc(db).container,
4429            GenericDefId::FunctionId(def) => def.loc(db).container,
4430            GenericDefId::TypeAliasId(def) => def.loc(db).container,
4431            GenericDefId::AdtId(_)
4432            | GenericDefId::ImplId(_)
4433            | GenericDefId::StaticId(_)
4434            | GenericDefId::TraitId(_) => return false,
4435        };
4436        self_def == rebase_into_parent
4437    }
4438}
4439
4440/// Note: A [`Type`] remembers its origin. Trying to do anything (except comparing)
4441/// with types of different origins will cause errors or panics. Instead, use the `instantiate` methods.
4442#[derive(Clone, Debug)]
4443pub struct Type<'db> {
4444    owner: TypeOwnerId,
4445    ty: EarlyBinder<'db, Ty<'db>>,
4446}
4447
4448impl<'db> std::hash::Hash for Type<'db> {
4449    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
4450        // Do not hash the owner as different owners can compare the same.
4451        // self.owner.hash(state);
4452        self.ty.hash(state);
4453    }
4454}
4455
4456impl<'db> PartialEq for Type<'db> {
4457    fn eq(&self, other: &Self) -> bool {
4458        if self.ty != other.ty {
4459            return false;
4460        }
4461        hir_ty::with_attached_db(|db| {
4462            self.owner.can_rebase_into(db, other.owner, self.ty)
4463                || other.owner.can_rebase_into(db, self.owner, other.ty)
4464        })
4465    }
4466}
4467
4468impl<'db> Eq for Type<'db> {}
4469
4470impl<'db> Type<'db> {
4471    fn new(owner: GenericDefId, ty: Ty<'db>) -> Self {
4472        Type { owner: TypeOwnerId::GenericDefId(owner), ty: EarlyBinder::bind(ty) }
4473    }
4474
4475    fn new_body(db: &dyn HirDatabase, owner: ExpressionStoreOwnerId, ty: Ty<'db>) -> Self {
4476        Self::new(owner.generic_def(db), ty)
4477    }
4478
4479    fn no_params(krate: base_db::Crate, ty: Ty<'db>) -> Self {
4480        Type { owner: TypeOwnerId::NoParams(krate), ty: EarlyBinder::bind(ty) }
4481    }
4482
4483    fn builtin_type_crate(db: &'db dyn HirDatabase) -> base_db::Crate {
4484        // It doesn't really matter.
4485        all_crates(db)[0]
4486    }
4487
4488    fn from_def(db: &'db dyn HirDatabase, def: impl Into<TyDefId>) -> Self {
4489        let def = def.into();
4490        let ty = db.ty(def);
4491        let owner = match def {
4492            TyDefId::AdtId(it) => TypeOwnerId::GenericDefId(GenericDefId::AdtId(it)),
4493            TyDefId::TypeAliasId(it) => TypeOwnerId::GenericDefId(GenericDefId::TypeAliasId(it)),
4494            TyDefId::BuiltinType(_) => TypeOwnerId::NoParams(Self::builtin_type_crate(db)),
4495        };
4496        Type { owner, ty }
4497    }
4498
4499    fn from_value_def(db: &'db dyn HirDatabase, def: impl Into<ValueTyDefId>) -> Self {
4500        let def = def.into();
4501        let Some(ty) = db.value_ty(def) else {
4502            return Type::unknown();
4503        };
4504        let def = match def {
4505            ValueTyDefId::ConstId(it) => GenericDefId::ConstId(it),
4506            ValueTyDefId::FunctionId(it) => GenericDefId::FunctionId(it),
4507            ValueTyDefId::StructId(it) => GenericDefId::AdtId(AdtId::StructId(it)),
4508            ValueTyDefId::UnionId(it) => GenericDefId::AdtId(AdtId::UnionId(it)),
4509            ValueTyDefId::EnumVariantId(it) => {
4510                GenericDefId::AdtId(AdtId::EnumId(it.lookup(db).parent))
4511            }
4512            ValueTyDefId::StaticId(it) => {
4513                return Type::no_params(hir_def::HasModule::krate(&it, db), ty.skip_binder());
4514            }
4515        };
4516        Type::new(def, ty.instantiate_identity().skip_norm_wip())
4517    }
4518
4519    /// Replace any generic parameters with error types.
4520    pub fn instantiate_with_errors(&self) -> Self {
4521        let interner = DbInterner::conjure();
4522        let krate = self.krate(interner.db());
4523        let args = match self.owner {
4524            TypeOwnerId::GenericDefId(def) => GenericArgs::error_for_item(interner, def.into()),
4525            TypeOwnerId::BuiltinDeriveImplId(def) => {
4526                GenericArgs::error_for_item(interner, def.into())
4527            }
4528            TypeOwnerId::NoParams(_) => GenericArgs::empty(),
4529        };
4530        Type::no_params(krate, self.ty.instantiate(interner, args).skip_norm_wip())
4531    }
4532
4533    // FIXME: Find some way with const params, maybe even lifetimes?
4534    pub fn instantiate(&self, args: impl IntoIterator<Item: Borrow<Type<'db>>>) -> Type<'db> {
4535        let interner = DbInterner::conjure();
4536        let (args, owner) = match self.owner {
4537            TypeOwnerId::GenericDefId(def) => generic_args_from_tys(interner, def.into(), args),
4538            TypeOwnerId::BuiltinDeriveImplId(def) => {
4539                generic_args_from_tys(interner, def.into(), args)
4540            }
4541            TypeOwnerId::NoParams(krate) => (GenericArgs::empty(), TypeOwnerId::NoParams(krate)),
4542        };
4543        Type { owner, ty: EarlyBinder::bind(self.ty.instantiate(interner, args).skip_norm_wip()) }
4544    }
4545
4546    /// Instantiates multiple types with infer vars, keeping the same infer vars for the same owners.
4547    fn instantiate_many_with_infer(
4548        tys: impl IntoIterator<Item: Borrow<Type<'db>>>,
4549        infcx: &InferCtxt<'db>,
4550    ) -> impl Iterator<Item = Ty<'db>> {
4551        let mut var_for_param = FxHashMap::default();
4552        tys.into_iter().map(move |ty| {
4553            let ty = ty.borrow();
4554            let owner = match ty.owner {
4555                TypeOwnerId::GenericDefId(def) => def.into(),
4556                TypeOwnerId::BuiltinDeriveImplId(def) => def.into(),
4557                TypeOwnerId::NoParams(_) => return ty.ty.skip_binder(),
4558            };
4559            let args = GenericArgs::for_item(infcx.interner, owner, |_, param, _, _| {
4560                *var_for_param
4561                    .entry(param)
4562                    .or_insert_with(|| infcx.var_for_def(param, hir_ty::Span::Dummy))
4563            });
4564
4565            ty.ty.instantiate(infcx.interner, args).skip_norm_wip()
4566        })
4567    }
4568
4569    /// Tries to put this type as-is in the context of `rebase_into`. This will return `Some(_)` if:
4570    ///
4571    ///  - The type does not reference generic parameters, or
4572    ///  - `rebase_into` is in the context of a child of our context (for example, a function in an impl).
4573    pub fn try_rebase_into(
4574        &self,
4575        db: &'db dyn HirDatabase,
4576        rebase_into: &Type<'db>,
4577    ) -> Option<Self> {
4578        if self.owner.can_rebase_into(db, rebase_into.owner, self.ty) {
4579            Some(Type { owner: rebase_into.owner, ty: self.ty })
4580        } else {
4581            None
4582        }
4583    }
4584
4585    /// If `self` can be rebased into `rebase_into`, returns that. Otherwise, instantiates `self` with errors
4586    /// and returns that.
4587    pub fn rebase_into_or_error(
4588        &self,
4589        db: &'db dyn HirDatabase,
4590        rebase_into: &Type<'db>,
4591    ) -> Type<'db> {
4592        self.try_rebase_into(db, rebase_into).unwrap_or_else(|| self.instantiate_with_errors())
4593    }
4594
4595    pub fn try_rebase_into_owner(
4596        &self,
4597        db: &'db dyn HirDatabase,
4598        new_owner: GenericDef,
4599    ) -> Option<Self> {
4600        let new_owner = new_owner.id()?.into();
4601        if self.owner.can_rebase_into(db, new_owner, self.ty) {
4602            Some(Type { owner: new_owner, ty: self.ty })
4603        } else {
4604            None
4605        }
4606    }
4607
4608    pub fn rebase_into_owner_or_error(
4609        &self,
4610        db: &'db dyn HirDatabase,
4611        new_owner: GenericDef,
4612    ) -> Self {
4613        self.try_rebase_into_owner(db, new_owner).unwrap_or_else(|| self.instantiate_with_errors())
4614    }
4615
4616    pub fn unknown() -> Self {
4617        let interner = DbInterner::conjure();
4618        Type::no_params(
4619            Self::builtin_type_crate(interner.db()),
4620            Ty::new_error(interner, ErrorGuaranteed),
4621        )
4622    }
4623
4624    pub fn new_slice(db: &'db dyn HirDatabase, ty: Self) -> Self {
4625        let interner = DbInterner::new_no_crate(db);
4626        Type { owner: ty.owner, ty: ty.ty.map_bound(|ty| Ty::new_slice(interner, ty)) }
4627    }
4628
4629    pub fn new_tuple(
4630        db: &'db dyn HirDatabase,
4631        tys: impl IntoIterator<Item: Borrow<Type<'db>>>,
4632    ) -> Self {
4633        let interner = DbInterner::new_no_crate(db);
4634        let mut owner = None::<TypeOwnerId>;
4635        let ty = EarlyBinder::bind(Ty::new_tup_from_iter(
4636            interner,
4637            tys.into_iter().map(|ty| {
4638                let ty = ty.borrow();
4639
4640                match &mut owner {
4641                    Some(owner) => *owner = owner.must_unify(ty.owner),
4642                    None => owner = Some(ty.owner),
4643                }
4644
4645                ty.ty.skip_binder()
4646            }),
4647        ));
4648        let owner =
4649            owner.unwrap_or_else(|| TypeOwnerId::NoParams(Self::builtin_type_crate(interner.db())));
4650        Type { owner, ty }
4651    }
4652
4653    pub fn new_unit() -> Self {
4654        let interner = DbInterner::conjure();
4655        Type::no_params(Self::builtin_type_crate(interner.db()), Ty::new_unit(interner))
4656    }
4657
4658    pub fn is_unit(&self) -> bool {
4659        self.ty.skip_binder().is_unit()
4660    }
4661
4662    pub fn is_bool(&self) -> bool {
4663        matches!(self.ty.skip_binder().kind(), TyKind::Bool)
4664    }
4665
4666    pub fn is_str(&self) -> bool {
4667        matches!(self.ty.skip_binder().kind(), TyKind::Str)
4668    }
4669
4670    pub fn is_never(&self) -> bool {
4671        matches!(self.ty.skip_binder().kind(), TyKind::Never)
4672    }
4673
4674    pub fn is_mutable_reference(&self) -> bool {
4675        matches!(
4676            self.ty.skip_binder().kind(),
4677            TyKind::Ref(.., hir_ty::next_solver::Mutability::Mut)
4678        )
4679    }
4680
4681    pub fn is_reference(&self) -> bool {
4682        matches!(self.ty.skip_binder().kind(), TyKind::Ref(..))
4683    }
4684
4685    pub fn contains_reference(&self, db: &'db dyn HirDatabase) -> bool {
4686        let interner = DbInterner::new_no_crate(db);
4687        return self
4688            .ty
4689            .instantiate_identity()
4690            .skip_norm_wip()
4691            .visit_with(&mut Visitor { interner })
4692            .is_break();
4693
4694        fn is_phantom_data(db: &dyn HirDatabase, adt_id: AdtId) -> bool {
4695            match adt_id {
4696                AdtId::StructId(s) => {
4697                    let flags = StructSignature::of(db, s).flags;
4698                    flags.contains(StructFlags::IS_PHANTOM_DATA)
4699                }
4700                AdtId::UnionId(_) | AdtId::EnumId(_) => false,
4701            }
4702        }
4703
4704        struct Visitor<'db> {
4705            interner: DbInterner<'db>,
4706        }
4707
4708        impl<'db> TypeVisitor<DbInterner<'db>> for Visitor<'db> {
4709            type Result = ControlFlow<()>;
4710
4711            fn visit_ty(&mut self, ty: Ty<'db>) -> Self::Result {
4712                match ty.kind() {
4713                    // Reference itself
4714                    TyKind::Ref(..) => ControlFlow::Break(()),
4715
4716                    // For non-phantom_data adts we check variants/fields as well as generic parameters
4717                    TyKind::Adt(adt_def, args)
4718                        if !is_phantom_data(self.interner.db(), adt_def.def_id()) =>
4719                    {
4720                        let _variant_id_to_fields = |id: VariantId| {
4721                            let variant_data = &id.fields(self.interner.db());
4722                            if variant_data.fields().is_empty() {
4723                                vec![]
4724                            } else {
4725                                let field_types = self.interner.db().field_types(id);
4726                                variant_data
4727                                    .fields()
4728                                    .iter()
4729                                    .map(|(idx, _)| {
4730                                        field_types[idx]
4731                                            .ty()
4732                                            .instantiate(self.interner, args)
4733                                            .skip_norm_wip()
4734                                    })
4735                                    .filter(|it| !it.references_non_lt_error())
4736                                    .collect()
4737                            }
4738                        };
4739                        let variant_id_to_fields = |_: VariantId| vec![];
4740
4741                        let variants: Vec<Vec<Ty<'db>>> = match adt_def.def_id() {
4742                            AdtId::StructId(id) => {
4743                                vec![variant_id_to_fields(id.into())]
4744                            }
4745                            AdtId::EnumId(id) => id
4746                                .enum_variants(self.interner.db())
4747                                .variants
4748                                .values()
4749                                .map(|&(variant_id, _)| variant_id_to_fields(variant_id.into()))
4750                                .collect(),
4751                            AdtId::UnionId(id) => {
4752                                vec![variant_id_to_fields(id.into())]
4753                            }
4754                        };
4755
4756                        variants
4757                            .into_iter()
4758                            .flat_map(|variant| variant.into_iter())
4759                            .try_for_each(|ty| ty.visit_with(self))?;
4760                        args.visit_with(self)
4761                    }
4762                    // And for `PhantomData<T>`, we check `T`.
4763                    _ => ty.super_visit_with(self),
4764                }
4765            }
4766        }
4767    }
4768
4769    pub fn as_reference(&self) -> Option<(Type<'db>, Mutability)> {
4770        let TyKind::Ref(_lt, ty, m) = self.ty.skip_binder().kind() else { return None };
4771        let m = Mutability::from_mutable(matches!(m, hir_ty::next_solver::Mutability::Mut));
4772        Some((self.derived(ty), m))
4773    }
4774
4775    pub fn as_reference_inner(&self) -> Option<Type<'db>> {
4776        self.as_reference().map(|(inner, _)| inner)
4777    }
4778
4779    pub fn add_reference(&self, db: &'db dyn HirDatabase, mutability: Mutability) -> Self {
4780        let interner = DbInterner::new_no_crate(db);
4781        let ty_mutability = match mutability {
4782            Mutability::Shared => hir_ty::next_solver::Mutability::Not,
4783            Mutability::Mut => hir_ty::next_solver::Mutability::Mut,
4784        };
4785        self.derived(Ty::new_ref(
4786            interner,
4787            Region::error(interner),
4788            self.ty.skip_binder(),
4789            ty_mutability,
4790        ))
4791    }
4792
4793    pub fn is_slice(&self) -> bool {
4794        matches!(self.ty.skip_binder().kind(), TyKind::Slice(..))
4795    }
4796
4797    pub fn is_usize(&self) -> bool {
4798        matches!(self.ty.skip_binder().kind(), TyKind::Uint(rustc_type_ir::UintTy::Usize))
4799    }
4800
4801    pub fn is_float(&self) -> bool {
4802        matches!(self.ty.skip_binder().kind(), TyKind::Float(_))
4803    }
4804
4805    pub fn is_char(&self) -> bool {
4806        matches!(self.ty.skip_binder().kind(), TyKind::Char)
4807    }
4808
4809    pub fn is_int_or_uint(&self) -> bool {
4810        matches!(self.ty.skip_binder().kind(), TyKind::Int(_) | TyKind::Uint(_))
4811    }
4812
4813    pub fn is_scalar(&self) -> bool {
4814        matches!(
4815            self.ty.skip_binder().kind(),
4816            TyKind::Bool | TyKind::Char | TyKind::Int(_) | TyKind::Uint(_) | TyKind::Float(_)
4817        )
4818    }
4819
4820    pub fn is_tuple(&self) -> bool {
4821        matches!(self.ty.skip_binder().kind(), TyKind::Tuple(..))
4822    }
4823
4824    pub fn as_slice(&self) -> Option<Type<'db>> {
4825        match self.ty.skip_binder().kind() {
4826            TyKind::Slice(ty) => Some(self.derived(ty)),
4827            _ => None,
4828        }
4829    }
4830
4831    pub fn strip_references(&self) -> Self {
4832        self.derived(self.ty.skip_binder().strip_references())
4833    }
4834
4835    // FIXME: This is the same as `remove_ref()`, remove one of these methods.
4836    pub fn strip_reference(&self) -> Self {
4837        self.derived(self.ty.skip_binder().strip_reference())
4838    }
4839
4840    pub fn is_unknown(&self) -> bool {
4841        self.ty.skip_binder().is_ty_error()
4842    }
4843
4844    fn krate(&self, db: &'db dyn HirDatabase) -> base_db::Crate {
4845        match self.owner {
4846            TypeOwnerId::GenericDefId(def) => hir_def::HasModule::krate(&def, db),
4847            TypeOwnerId::BuiltinDeriveImplId(def) => {
4848                hir_def::HasModule::krate(&def.loc(db).adt, db)
4849            }
4850            TypeOwnerId::NoParams(krate) => krate,
4851        }
4852    }
4853
4854    fn param_env(&self, db: &'db dyn HirDatabase) -> ParamEnvAndCrate<'db> {
4855        let krate = self.krate(db);
4856        match self.owner {
4857            TypeOwnerId::GenericDefId(def) => {
4858                ParamEnvAndCrate { param_env: db.trait_environment(def), krate }
4859            }
4860            TypeOwnerId::BuiltinDeriveImplId(def) => ParamEnvAndCrate {
4861                param_env: hir_ty::builtin_derive::param_env(DbInterner::new_with(db, krate), def),
4862                krate,
4863            },
4864            TypeOwnerId::NoParams(_) => ParamEnvAndCrate { param_env: ParamEnv::empty(), krate },
4865        }
4866    }
4867
4868    /// Checks that particular type `ty` implements `std::future::IntoFuture` or
4869    /// `std::future::Future` and returns the `Output` associated type.
4870    /// This function is used in `.await` syntax completion.
4871    pub fn into_future_output(&self, db: &'db dyn HirDatabase) -> Option<Type<'db>> {
4872        let env = self.param_env(db);
4873        let lang_items = hir_def::lang_item::lang_items(db, env.krate);
4874        let (trait_, output_assoc_type) = lang_items
4875            .IntoFuture
4876            .zip(lang_items.IntoFutureOutput)
4877            .or(lang_items.Future.zip(lang_items.FutureOutput))?;
4878
4879        if !traits::implements_trait_unique(
4880            self.ty.instantiate_identity().skip_norm_wip(),
4881            db,
4882            env,
4883            trait_,
4884        ) {
4885            return None;
4886        }
4887
4888        self.normalize_trait_assoc_type(db, &[], output_assoc_type.into())
4889    }
4890
4891    /// This does **not** resolve `IntoFuture`, only `Future`.
4892    pub fn future_output(self, db: &'db dyn HirDatabase) -> Option<Type<'db>> {
4893        let krate = self.krate(db);
4894        let lang_items = hir_def::lang_item::lang_items(db, krate);
4895        let future_output = lang_items.FutureOutput?;
4896        self.normalize_trait_assoc_type(db, &[], future_output.into())
4897    }
4898
4899    /// This does **not** resolve `IntoIterator`, only `Iterator`.
4900    pub fn iterator_item(self, db: &'db dyn HirDatabase) -> Option<Type<'db>> {
4901        let krate = self.krate(db);
4902        let lang_items = hir_def::lang_item::lang_items(db, krate);
4903        let iterator_item = lang_items.IteratorItem?;
4904        self.normalize_trait_assoc_type(db, &[], iterator_item.into())
4905    }
4906
4907    pub fn impls_iterator(self, db: &'db dyn HirDatabase) -> bool {
4908        let env = self.param_env(db);
4909        let lang_items = hir_def::lang_item::lang_items(db, env.krate);
4910        let Some(iterator_trait) = lang_items.Iterator else {
4911            return false;
4912        };
4913        traits::implements_trait_unique(
4914            self.ty.instantiate_identity().skip_norm_wip(),
4915            db,
4916            env,
4917            iterator_trait,
4918        )
4919    }
4920
4921    /// Resolves the projection `<Self as IntoIterator>::IntoIter` and returns the resulting type
4922    pub fn into_iterator_iter(self, db: &'db dyn HirDatabase) -> Option<Type<'db>> {
4923        let env = self.param_env(db);
4924        let lang_items = hir_def::lang_item::lang_items(db, env.krate);
4925        let trait_ = lang_items.IntoIterator?;
4926
4927        if !traits::implements_trait_unique(
4928            self.ty.instantiate_identity().skip_norm_wip(),
4929            db,
4930            env,
4931            trait_,
4932        ) {
4933            return None;
4934        }
4935
4936        let into_iter_assoc_type = lang_items.IntoIterIntoIterType?;
4937        self.normalize_trait_assoc_type(db, &[], into_iter_assoc_type.into())
4938    }
4939
4940    /// Checks that particular type `ty` implements `std::ops::FnOnce`.
4941    ///
4942    /// This function can be used to check if a particular type is callable, since FnOnce is a
4943    /// supertrait of Fn and FnMut, so all callable types implements at least FnOnce.
4944    pub fn impls_fnonce(&self, db: &'db dyn HirDatabase) -> bool {
4945        let env = self.param_env(db);
4946        let lang_items = hir_def::lang_item::lang_items(db, env.krate);
4947        let fnonce_trait = match lang_items.FnOnce {
4948            Some(it) => it,
4949            None => return false,
4950        };
4951
4952        traits::implements_trait_unique(
4953            self.ty.instantiate_identity().skip_norm_wip(),
4954            db,
4955            env,
4956            fnonce_trait,
4957        )
4958    }
4959
4960    // FIXME: Find better API that also handles const generics
4961    pub fn impls_trait(&self, db: &'db dyn HirDatabase, trait_: Trait, args: &[Type<'db>]) -> bool {
4962        let env = self.param_env(db);
4963        let interner = DbInterner::new_no_crate(db);
4964        let (args, _owner) =
4965            generic_args_from_tys(interner, trait_.id.into(), iter::once(self).chain(args));
4966        traits::implements_trait_unique_with_args(db, env, trait_.id, args)
4967    }
4968
4969    /// Unlike [`Type::impls_trait()`], which checks whether the type always implements the trait,
4970    /// this check whether there are any generic args substitution for `args`` that will cause the
4971    /// trait to be implemented.
4972    ///
4973    /// For example, suppose we're there's `struct Foo<T>` and we're checking `Foo<T>: Trait`.
4974    /// `impls_trait()` will return true only if there is `impl<T> Trait for Foo<T>`, while this
4975    /// method will also return true if there is only `impl Trait for Foo<i32>`.
4976    ///
4977    /// Note that you can of course instantiate `Foo<T>` with `<i32>` and then the checks will
4978    /// be the same, but this check for *any* substitution.
4979    ///
4980    /// Unlike almost anything that takes more than one type, you *can* pass types from different origins
4981    /// to this function.
4982    pub fn has_any_impl(
4983        &self,
4984        db: &'db dyn HirDatabase,
4985        trait_: Trait,
4986        args: &[Type<'db>],
4987    ) -> bool {
4988        let env = ParamEnvAndCrate { param_env: ParamEnv::empty(), krate: self.krate(db) };
4989        traits::implements_trait_unique_with_infcx(db, env, trait_.id, &mut |infcx| {
4990            let mut args = Self::instantiate_many_with_infer(iter::once(self).chain(args), infcx);
4991            GenericArgs::for_item(infcx.interner, trait_.id.into(), |_, param, _, _| {
4992                if let GenericParamId::TypeParamId(_) = param
4993                    && let Some(arg) = args.next()
4994                {
4995                    arg.into()
4996                } else {
4997                    infcx.var_for_def(param, hir_ty::Span::Dummy)
4998                }
4999            })
5000        })
5001    }
5002
5003    pub fn normalize_trait_assoc_type(
5004        &self,
5005        db: &'db dyn HirDatabase,
5006        args: &[Type<'db>],
5007        alias: TypeAlias,
5008    ) -> Option<Type<'db>> {
5009        let env = self.param_env(db);
5010        let interner = DbInterner::new_with(db, env.krate);
5011        let (args, owner) =
5012            generic_args_from_tys(interner, alias.id.into(), iter::once(self).chain(args));
5013        // FIXME: We don't handle GATs yet.
5014        let projection = Ty::new_alias(
5015            interner,
5016            AliasTy::new_from_args(
5017                interner,
5018                AliasTyKind::Projection { def_id: alias.id.into() },
5019                args,
5020            ),
5021        );
5022
5023        let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
5024        let ty = structurally_normalize_ty(&infcx, projection, env.param_env);
5025        if ty.is_ty_error() { None } else { Some(Type { owner, ty: EarlyBinder::bind(ty) }) }
5026    }
5027
5028    pub fn is_copy(&self, db: &'db dyn HirDatabase) -> bool {
5029        let env = self.param_env(db);
5030        let lang_items = hir_def::lang_item::lang_items(db, env.krate);
5031        let Some(copy_trait) = lang_items.Copy else {
5032            return false;
5033        };
5034        self.impls_trait(db, copy_trait.into(), &[])
5035    }
5036
5037    pub fn as_callable(&self, db: &'db dyn HirDatabase) -> Option<Callable<'db>> {
5038        let interner = DbInterner::new_no_crate(db);
5039        let callee = match self.ty.skip_binder().kind() {
5040            TyKind::Closure(id, subst) => Callee::Closure(id.0, subst),
5041            TyKind::CoroutineClosure(id, subst) => Callee::CoroutineClosure(id.0, subst),
5042            TyKind::FnPtr(..) => Callee::FnPtr,
5043            TyKind::FnDef(id, _) => Callee::Def(id.0),
5044            // This will happen when it implements fn or fn mut, since we add an autoborrow adjustment
5045            TyKind::Ref(_, inner_ty, _) => return self.derived(inner_ty).as_callable(db),
5046            _ => {
5047                let env = self.param_env(db);
5048                let (fn_trait, sig) =
5049                    hir_ty::callable_sig_from_fn_trait(self.ty.skip_binder(), env, db)?;
5050                return Some(Callable {
5051                    ty: self.clone(),
5052                    sig,
5053                    callee: Callee::FnImpl(fn_trait),
5054                    is_bound_method: false,
5055                });
5056            }
5057        };
5058
5059        let sig = self.ty.skip_binder().callable_sig(interner)?;
5060        Some(Callable { ty: self.clone(), sig, callee, is_bound_method: false })
5061    }
5062
5063    pub fn is_closure(&self) -> bool {
5064        matches!(self.ty.skip_binder().kind(), TyKind::Closure { .. })
5065    }
5066
5067    pub fn as_closure(&self) -> Option<Closure<'db>> {
5068        match self.ty.skip_binder().kind() {
5069            TyKind::Closure(id, subst) => {
5070                Some(Closure { id: AnyClosureId::ClosureId(id.0), subst, owner: self.owner })
5071            }
5072            TyKind::CoroutineClosure(id, subst) => Some(Closure {
5073                id: AnyClosureId::CoroutineClosureId(id.0),
5074                subst,
5075                owner: self.owner,
5076            }),
5077            _ => None,
5078        }
5079    }
5080
5081    /// Returns this type as a coroutine.
5082    pub fn as_coroutine(&self) -> Option<Coroutine<'db>> {
5083        match self.ty.skip_binder().kind() {
5084            TyKind::Coroutine(id, _) => Some(Coroutine { id: id.0 }),
5085            _ => None,
5086        }
5087    }
5088
5089    pub fn is_fn(&self) -> bool {
5090        matches!(self.ty.skip_binder().kind(), TyKind::FnDef(..) | TyKind::FnPtr { .. })
5091    }
5092
5093    pub fn is_array(&self) -> bool {
5094        matches!(self.ty.skip_binder().kind(), TyKind::Array(..))
5095    }
5096
5097    pub fn is_packed(&self, _db: &'db dyn HirDatabase) -> bool {
5098        match self.ty.skip_binder().kind() {
5099            TyKind::Adt(adt_def, ..) => adt_def.is_packed(),
5100            _ => false,
5101        }
5102    }
5103
5104    pub fn is_raw_ptr(&self) -> bool {
5105        matches!(self.ty.skip_binder().kind(), TyKind::RawPtr(..))
5106    }
5107
5108    pub fn is_mutable_raw_ptr(&self) -> bool {
5109        // Used outside of rust-analyzer (e.g. by `ra_ap_hir` consumers).
5110        matches!(
5111            self.ty.skip_binder().kind(),
5112            TyKind::RawPtr(.., hir_ty::next_solver::Mutability::Mut)
5113        )
5114    }
5115
5116    pub fn as_raw_ptr(&self) -> Option<(Type<'db>, Mutability)> {
5117        // Used outside of rust-analyzer (e.g. by `ra_ap_hir` consumers).
5118        let TyKind::RawPtr(ty, m) = self.ty.skip_binder().kind() else { return None };
5119        let m = Mutability::from_mutable(matches!(m, hir_ty::next_solver::Mutability::Mut));
5120        Some((self.derived(ty), m))
5121    }
5122
5123    pub fn remove_raw_ptr(&self) -> Option<Type<'db>> {
5124        if let TyKind::RawPtr(ty, _) = self.ty.skip_binder().kind() {
5125            Some(self.derived(ty))
5126        } else {
5127            None
5128        }
5129    }
5130
5131    pub fn contains_unknown(&self) -> bool {
5132        self.ty.skip_binder().references_non_lt_error()
5133    }
5134
5135    pub fn fields(&self, db: &'db dyn HirDatabase) -> Vec<(Field, Self)> {
5136        let interner = DbInterner::new_no_crate(db);
5137        let (variant_id, substs) = match self.ty.skip_binder().kind() {
5138            TyKind::Adt(adt_def, substs) => {
5139                let id = match adt_def.def_id() {
5140                    AdtId::StructId(id) => id.into(),
5141                    AdtId::UnionId(id) => id.into(),
5142                    AdtId::EnumId(_) => return Vec::new(),
5143                };
5144                (id, substs)
5145            }
5146            _ => return Vec::new(),
5147        };
5148
5149        db.field_types(variant_id)
5150            .iter()
5151            .map(|(local_id, field)| {
5152                let def = Field { parent: variant_id.into(), id: local_id };
5153                let ty = field.ty().instantiate(interner, substs).skip_norm_wip();
5154                (def, self.derived(ty))
5155            })
5156            .collect()
5157    }
5158
5159    pub fn tuple_fields(&self, _db: &'db dyn HirDatabase) -> Vec<Self> {
5160        if let TyKind::Tuple(substs) = self.ty.skip_binder().kind() {
5161            substs.iter().map(|ty| self.derived(ty)).collect()
5162        } else {
5163            Vec::new()
5164        }
5165    }
5166
5167    pub fn as_array(&self, db: &'db dyn HirDatabase) -> Option<(Self, usize)> {
5168        if let TyKind::Array(ty, len) = self.ty.skip_binder().kind() {
5169            try_const_usize(db, len).map(|it| (self.derived(ty), it as usize))
5170        } else {
5171            None
5172        }
5173    }
5174
5175    // FIXME: We should probably remove this.
5176    pub fn fingerprint_for_trait_impl(
5177        &self,
5178        db: &'db dyn HirDatabase,
5179    ) -> Option<SimplifiedType<'db>> {
5180        fast_reject::simplify_type(
5181            DbInterner::new_no_crate(db),
5182            self.ty.skip_binder(),
5183            fast_reject::TreatParams::AsRigid,
5184        )
5185    }
5186
5187    /// Returns types that this type dereferences to (including this type itself). The returned
5188    /// iterator won't yield the same type more than once even if the deref chain contains a cycle.
5189    pub fn autoderef(
5190        &self,
5191        db: &'db dyn HirDatabase,
5192    ) -> impl Iterator<Item = Type<'db>> + use<'_, 'db> {
5193        self.autoderef_(db).map(move |ty| self.derived(ty))
5194    }
5195
5196    fn autoderef_(&self, db: &'db dyn HirDatabase) -> impl Iterator<Item = Ty<'db>> {
5197        let interner = DbInterner::new_no_crate(db);
5198        let env = self.param_env(db);
5199        // There should be no inference vars in types passed here
5200        let canonical = hir_ty::replace_errors_with_variables(interner, &self.ty.skip_binder());
5201        autoderef(db, env, canonical)
5202    }
5203
5204    // This would be nicer if it just returned an iterator, but that runs into
5205    // lifetime problems, because we need to borrow temp `CrateImplDefs`.
5206    pub fn iterate_assoc_items<T>(
5207        &self,
5208        db: &'db dyn HirDatabase,
5209        mut callback: impl FnMut(AssocItem) -> Option<T>,
5210    ) -> Option<T> {
5211        let mut slot = None;
5212        self.iterate_assoc_items_dyn(db, &mut |assoc_item_id| {
5213            slot = callback(assoc_item_id.into());
5214            slot.is_some()
5215        });
5216        slot
5217    }
5218
5219    fn iterate_assoc_items_dyn(
5220        &self,
5221        db: &'db dyn HirDatabase,
5222        callback: &mut dyn FnMut(AssocItemId) -> bool,
5223    ) {
5224        let mut handle_impls = |impls: &[ImplId]| {
5225            for &impl_def in impls {
5226                for &(_, item) in impl_def.impl_items(db).items.iter() {
5227                    if callback(item) {
5228                        return;
5229                    }
5230                }
5231            }
5232        };
5233        let krate = self.krate(db);
5234
5235        let interner = DbInterner::new_no_crate(db);
5236        let Some(simplified_type) = fast_reject::simplify_type(
5237            interner,
5238            self.ty.skip_binder(),
5239            fast_reject::TreatParams::AsRigid,
5240        ) else {
5241            return;
5242        };
5243
5244        method_resolution::with_incoherent_inherent_impls(
5245            db,
5246            krate,
5247            &simplified_type,
5248            &mut handle_impls,
5249        );
5250
5251        if let Some(module) = method_resolution::simplified_type_module(db, &simplified_type) {
5252            InherentImpls::for_each_crate_and_block(
5253                db,
5254                module.krate(db),
5255                module.block(db),
5256                &mut |impls| {
5257                    handle_impls(impls.for_self_ty(&simplified_type));
5258                },
5259            );
5260        }
5261    }
5262
5263    /// Iterates its type arguments
5264    ///
5265    /// It iterates the actual type arguments when concrete types are used
5266    /// and otherwise the generic names.
5267    /// It does not include `const` arguments.
5268    ///
5269    /// For code, such as:
5270    /// ```text
5271    /// struct Foo<T, U>
5272    ///
5273    /// impl<U> Foo<String, U>
5274    /// ```
5275    ///
5276    /// It iterates:
5277    /// ```text
5278    /// - "String"
5279    /// - "U"
5280    /// ```
5281    pub fn type_arguments(&self) -> impl Iterator<Item = Type<'db>> + '_ {
5282        match self.ty.skip_binder().strip_references().kind() {
5283            TyKind::Adt(_, substs) => Either::Left(substs.types().map(move |ty| self.derived(ty))),
5284            TyKind::Tuple(substs) => {
5285                Either::Right(Either::Left(substs.iter().map(move |ty| self.derived(ty))))
5286            }
5287            _ => Either::Right(Either::Right(iter::empty())),
5288        }
5289    }
5290
5291    /// Iterates its type and const arguments
5292    ///
5293    /// It iterates the actual type and const arguments when concrete types
5294    /// are used and otherwise the generic names.
5295    ///
5296    /// For code, such as:
5297    /// ```text
5298    /// struct Foo<T, const U: usize, const X: usize>
5299    ///
5300    /// impl<U> Foo<String, U, 12>
5301    /// ```
5302    ///
5303    /// It iterates:
5304    /// ```text
5305    /// - "String"
5306    /// - "U"
5307    /// - "12"
5308    /// ```
5309    pub fn type_and_const_arguments<'a>(
5310        &'a self,
5311        db: &'a dyn HirDatabase,
5312        display_target: DisplayTarget,
5313    ) -> impl Iterator<Item = SmolStr> + 'a {
5314        self.ty
5315            .skip_binder()
5316            .strip_references()
5317            .as_adt()
5318            .into_iter()
5319            .flat_map(|(_, substs)| substs.iter())
5320            .filter_map(move |arg| match arg.kind() {
5321                rustc_type_ir::GenericArgKind::Type(ty) => {
5322                    Some(format_smolstr!("{}", ty.display(db, display_target)))
5323                }
5324                rustc_type_ir::GenericArgKind::Const(const_) => {
5325                    Some(format_smolstr!("{}", const_.display(db, display_target)))
5326                }
5327                rustc_type_ir::GenericArgKind::Lifetime(_) => None,
5328            })
5329    }
5330
5331    /// Combines lifetime indicators, type and constant parameters into a single `Iterator`
5332    pub fn generic_parameters<'a>(
5333        &'a self,
5334        db: &'a dyn HirDatabase,
5335        display_target: DisplayTarget,
5336    ) -> impl Iterator<Item = SmolStr> + 'a {
5337        // iterate the lifetime
5338        self.as_adt()
5339            .and_then(|a| {
5340                // Lifetimes do not need edition-specific handling as they cannot be escaped.
5341                a.lifetime(db).map(|lt| lt.name.display_no_db(Edition::Edition2015).to_smolstr())
5342            })
5343            .into_iter()
5344            // add the type and const parameters
5345            .chain(self.type_and_const_arguments(db, display_target))
5346    }
5347
5348    pub fn iterate_method_candidates_with_traits<T>(
5349        &self,
5350        db: &'db dyn HirDatabase,
5351        scope: &SemanticsScope<'_>,
5352        traits_in_scope: &FxHashSet<TraitId>,
5353        name: Option<&Name>,
5354        mut callback: impl FnMut(Function) -> Option<T>,
5355    ) -> Option<T> {
5356        let _p = tracing::info_span!("iterate_method_candidates_with_traits").entered();
5357        let mut slot = None;
5358        self.iterate_method_candidates_split_inherent(db, scope, traits_in_scope, name, |f| {
5359            match callback(f) {
5360                it @ Some(_) => {
5361                    slot = it;
5362                    ControlFlow::Break(())
5363                }
5364                None => ControlFlow::Continue(()),
5365            }
5366        });
5367        slot
5368    }
5369
5370    pub fn iterate_method_candidates<T>(
5371        &self,
5372        db: &'db dyn HirDatabase,
5373        scope: &SemanticsScope<'_>,
5374        name: Option<&Name>,
5375        callback: impl FnMut(Function) -> Option<T>,
5376    ) -> Option<T> {
5377        self.iterate_method_candidates_with_traits(
5378            db,
5379            scope,
5380            &scope.visible_traits().0,
5381            name,
5382            callback,
5383        )
5384    }
5385
5386    fn with_method_resolution<R>(
5387        &self,
5388        db: &'db dyn HirDatabase,
5389        resolver: &Resolver<'db>,
5390        traits_in_scope: &FxHashSet<TraitId>,
5391        f: impl FnOnce(&MethodResolutionContext<'_, 'db>) -> R,
5392    ) -> R {
5393        let module = resolver.module();
5394        let interner = DbInterner::new_with(db, module.krate(db));
5395        // Most IDE operations want to operate in PostAnalysis mode, revealing opaques. This makes
5396        // for a nicer IDE experience. However, method resolution is always done on real code (either
5397        // existing code or code to be inserted), and there using PostAnalysis is dangerous - we may
5398        // suggest invalid methods. So we're using the TypingMode of the body we're in.
5399        let typing_mode = if let Some(store_owner) = resolver.expression_store_owner() {
5400            TypingMode::analysis_in_body(interner, store_owner.into())
5401        } else {
5402            TypingMode::non_body_analysis()
5403        };
5404        let infcx = interner.infer_ctxt().build(typing_mode);
5405        let features = resolver.top_level_def_map().features();
5406        let environment = self.param_env(db);
5407        let ctx = MethodResolutionContext {
5408            infcx: &infcx,
5409            resolver,
5410            param_env: environment.param_env,
5411            traits_in_scope,
5412            edition: resolver.krate().data(db).edition,
5413            features,
5414            call_span: hir_ty::Span::Dummy,
5415            receiver_span: hir_ty::Span::Dummy,
5416        };
5417        f(&ctx)
5418    }
5419
5420    /// Allows you to treat inherent and non-inherent methods differently.
5421    ///
5422    /// Note that inherent methods may actually be trait methods! For example, in `dyn Trait`, the trait's methods
5423    /// are considered inherent methods.
5424    pub fn iterate_method_candidates_split_inherent(
5425        &self,
5426        db: &'db dyn HirDatabase,
5427        scope: &SemanticsScope<'_>,
5428        traits_in_scope: &FxHashSet<TraitId>,
5429        name: Option<&Name>,
5430        mut callback: impl MethodCandidateCallback,
5431    ) {
5432        let _p = tracing::info_span!(
5433            "iterate_method_candidates_split_inherent",
5434            traits_in_scope = traits_in_scope.len(),
5435            ?name,
5436        )
5437        .entered();
5438
5439        self.with_method_resolution(db, scope.resolver(), traits_in_scope, |ctx| {
5440            // There should be no inference vars in types passed here
5441            let canonical =
5442                hir_ty::replace_errors_with_variables(ctx.infcx.interner, &self.ty.skip_binder());
5443            let (self_ty, _) = ctx.infcx.instantiate_canonical(hir_ty::Span::Dummy, &canonical);
5444
5445            match name {
5446                Some(name) => {
5447                    match ctx.probe_for_name(
5448                        method_resolution::Mode::MethodCall,
5449                        name.clone(),
5450                        self_ty,
5451                    ) {
5452                        Ok(candidate)
5453                        | Err(method_resolution::MethodError::PrivateMatch(candidate)) => {
5454                            let method_resolution::CandidateId::FunctionId(id) = candidate.item
5455                            else {
5456                                unreachable!("`Mode::MethodCall` can only return functions");
5457                            };
5458                            let id = Function { id: AnyFunctionId::FunctionId(id) };
5459                            match candidate.kind {
5460                                method_resolution::PickKind::InherentImplPick(_)
5461                                | method_resolution::PickKind::ObjectPick(..)
5462                                | method_resolution::PickKind::WhereClausePick(..) => {
5463                                    // Candidates from where clauses and trait objects are considered inherent.
5464                                    _ = callback.on_inherent_method(id);
5465                                }
5466                                method_resolution::PickKind::TraitPick(..) => {
5467                                    _ = callback.on_trait_method(id);
5468                                }
5469                            }
5470                        }
5471                        Err(_) => {}
5472                    };
5473                }
5474                None => {
5475                    _ = ctx.probe_all(method_resolution::Mode::MethodCall, self_ty).try_for_each(
5476                        |candidate| {
5477                            let method_resolution::CandidateId::FunctionId(id) =
5478                                candidate.candidate.item
5479                            else {
5480                                unreachable!("`Mode::MethodCall` can only return functions");
5481                            };
5482                            let id = Function { id: AnyFunctionId::FunctionId(id) };
5483                            match candidate.candidate.kind {
5484                                method_resolution::CandidateKind::InherentImplCandidate {
5485                                    ..
5486                                }
5487                                | method_resolution::CandidateKind::ObjectCandidate(..)
5488                                | method_resolution::CandidateKind::WhereClauseCandidate(..) => {
5489                                    // Candidates from where clauses and trait objects are considered inherent.
5490                                    callback.on_inherent_method(id)
5491                                }
5492                                method_resolution::CandidateKind::TraitCandidate(..) => {
5493                                    callback.on_trait_method(id)
5494                                }
5495                            }
5496                        },
5497                    );
5498                }
5499            }
5500        })
5501    }
5502
5503    #[tracing::instrument(skip_all, fields(name = ?name))]
5504    pub fn iterate_path_candidates<T>(
5505        &self,
5506        db: &'db dyn HirDatabase,
5507        scope: &SemanticsScope<'_>,
5508        traits_in_scope: &FxHashSet<TraitId>,
5509        name: Option<&Name>,
5510        mut callback: impl FnMut(AssocItem) -> Option<T>,
5511    ) -> Option<T> {
5512        let _p = tracing::info_span!("iterate_path_candidates").entered();
5513        let mut slot = None;
5514
5515        self.iterate_path_candidates_split_inherent(db, scope, traits_in_scope, name, |item| {
5516            match callback(item) {
5517                it @ Some(_) => {
5518                    slot = it;
5519                    ControlFlow::Break(())
5520                }
5521                None => ControlFlow::Continue(()),
5522            }
5523        });
5524        slot
5525    }
5526
5527    /// Iterates over inherent methods.
5528    ///
5529    /// In some circumstances, inherent methods methods may actually be trait methods!
5530    /// For example, when `dyn Trait` is a receiver, _trait_'s methods would be considered
5531    /// to be inherent methods.
5532    #[tracing::instrument(skip_all, fields(name = ?name))]
5533    pub fn iterate_path_candidates_split_inherent(
5534        &self,
5535        db: &'db dyn HirDatabase,
5536        scope: &SemanticsScope<'_>,
5537        traits_in_scope: &FxHashSet<TraitId>,
5538        name: Option<&Name>,
5539        mut callback: impl PathCandidateCallback,
5540    ) {
5541        let _p = tracing::info_span!(
5542            "iterate_path_candidates_split_inherent",
5543            traits_in_scope = traits_in_scope.len(),
5544            ?name,
5545        )
5546        .entered();
5547
5548        self.with_method_resolution(db, scope.resolver(), traits_in_scope, |ctx| {
5549            // There should be no inference vars in types passed here
5550            let canonical =
5551                hir_ty::replace_errors_with_variables(ctx.infcx.interner, &self.ty.skip_binder());
5552            let (self_ty, _) = ctx.infcx.instantiate_canonical(hir_ty::Span::Dummy, &canonical);
5553
5554            match name {
5555                Some(name) => {
5556                    match ctx.probe_for_name(method_resolution::Mode::Path, name.clone(), self_ty) {
5557                        Ok(candidate)
5558                        | Err(method_resolution::MethodError::PrivateMatch(candidate)) => {
5559                            let id = candidate.item.into();
5560                            match candidate.kind {
5561                                method_resolution::PickKind::InherentImplPick(_)
5562                                | method_resolution::PickKind::ObjectPick(..)
5563                                | method_resolution::PickKind::WhereClausePick(..) => {
5564                                    // Candidates from where clauses and trait objects are considered inherent.
5565                                    _ = callback.on_inherent_item(id);
5566                                }
5567                                method_resolution::PickKind::TraitPick(..) => {
5568                                    _ = callback.on_trait_item(id);
5569                                }
5570                            }
5571                        }
5572                        Err(_) => {}
5573                    };
5574                }
5575                None => {
5576                    _ = ctx.probe_all(method_resolution::Mode::Path, self_ty).try_for_each(
5577                        |candidate| {
5578                            let id = candidate.candidate.item.into();
5579                            match candidate.candidate.kind {
5580                                method_resolution::CandidateKind::InherentImplCandidate {
5581                                    ..
5582                                }
5583                                | method_resolution::CandidateKind::ObjectCandidate(..)
5584                                | method_resolution::CandidateKind::WhereClauseCandidate(..) => {
5585                                    // Candidates from where clauses and trait objects are considered inherent.
5586                                    callback.on_inherent_item(id)
5587                                }
5588                                method_resolution::CandidateKind::TraitCandidate(..) => {
5589                                    callback.on_trait_item(id)
5590                                }
5591                            }
5592                        },
5593                    );
5594                }
5595            }
5596        })
5597    }
5598
5599    pub fn as_adt(&self) -> Option<Adt> {
5600        let (adt, _subst) = self.ty.skip_binder().as_adt()?;
5601        Some(adt.into())
5602    }
5603
5604    /// Holes in the args can come from lifetime/const params.
5605    pub fn as_adt_with_args(&self) -> Option<(Adt, Vec<Option<Type<'db>>>)> {
5606        let (adt, args) = self.ty.skip_binder().as_adt()?;
5607        let args = args.iter().map(|arg| Some(self.derived(arg.ty()?))).collect();
5608        Some((adt.into(), args))
5609    }
5610
5611    pub fn as_builtin(&self) -> Option<BuiltinType> {
5612        self.ty.skip_binder().as_builtin().map(|inner| BuiltinType { inner })
5613    }
5614
5615    pub fn as_dyn_trait(&self) -> Option<Trait> {
5616        self.ty.skip_binder().dyn_trait().map(Into::into)
5617    }
5618
5619    /// If a type can be represented as `dyn Trait`, returns all traits accessible via this type,
5620    /// or an empty iterator otherwise.
5621    pub fn applicable_inherent_traits(
5622        &self,
5623        db: &'db dyn HirDatabase,
5624    ) -> impl Iterator<Item = Trait> {
5625        let _p = tracing::info_span!("applicable_inherent_traits").entered();
5626        self.autoderef_(db)
5627            .filter_map(|ty| ty.dyn_trait())
5628            .flat_map(move |dyn_trait_id| hir_ty::all_super_traits(db, dyn_trait_id))
5629            .copied()
5630            .map(Trait::from)
5631    }
5632
5633    pub fn env_traits(&self, db: &'db dyn HirDatabase) -> impl Iterator<Item = Trait> {
5634        let _p = tracing::info_span!("env_traits").entered();
5635        let env = self.param_env(db);
5636        self.autoderef_(db)
5637            .filter(|ty| matches!(ty.kind(), TyKind::Param(_)))
5638            .flat_map(move |ty| {
5639                env.param_env
5640                    .clauses()
5641                    .iter()
5642                    .filter_map(move |pred| match pred.kind().skip_binder() {
5643                        ClauseKind::Trait(tr) if tr.self_ty() == ty => Some(tr.def_id().0),
5644                        _ => None,
5645                    })
5646                    .flat_map(|t| hir_ty::all_super_traits(db, t))
5647                    .copied()
5648            })
5649            .map(Trait::from)
5650    }
5651
5652    pub fn as_impl_traits(&self, db: &'db dyn HirDatabase) -> Option<impl Iterator<Item = Trait>> {
5653        self.ty.skip_binder().impl_trait_bounds(db).map(|it| {
5654            it.into_iter().filter_map(|pred| match pred.kind().skip_binder() {
5655                ClauseKind::Trait(trait_ref) => Some(Trait::from(trait_ref.def_id().0)),
5656                _ => None,
5657            })
5658        })
5659    }
5660
5661    pub fn as_associated_type_parent_trait(&self, db: &'db dyn HirDatabase) -> Option<Trait> {
5662        let TyKind::Alias(AliasTy { kind: AliasTyKind::Projection { def_id }, .. }) =
5663            self.ty.skip_binder().kind()
5664        else {
5665            return None;
5666        };
5667        match def_id.0.loc(db).container {
5668            ItemContainerId::TraitId(id) => Some(Trait { id }),
5669            _ => None,
5670        }
5671    }
5672
5673    fn derived(&self, ty: Ty<'db>) -> Self {
5674        Type { owner: self.owner, ty: EarlyBinder::bind(ty) }
5675    }
5676
5677    /// Visits every type, including generic arguments, in this type. `callback` is called with type
5678    /// itself first, and then with its generic arguments.
5679    pub fn walk(&self, db: &'db dyn HirDatabase, callback: impl FnMut(Type<'db>)) {
5680        struct Visitor<'db, F> {
5681            db: &'db dyn HirDatabase,
5682            owner: TypeOwnerId,
5683            callback: F,
5684            visited: FxHashSet<Ty<'db>>,
5685        }
5686        impl<'db, F> TypeVisitor<DbInterner<'db>> for Visitor<'db, F>
5687        where
5688            F: FnMut(Type<'db>),
5689        {
5690            type Result = ();
5691
5692            fn visit_ty(&mut self, ty: Ty<'db>) -> Self::Result {
5693                if !self.visited.insert(ty) {
5694                    return;
5695                }
5696
5697                (self.callback)(Type { owner: self.owner, ty: EarlyBinder::bind(ty) });
5698
5699                if let Some(bounds) = ty.impl_trait_bounds(self.db) {
5700                    bounds.visit_with(self);
5701                }
5702
5703                ty.super_visit_with(self);
5704            }
5705        }
5706
5707        let mut visitor =
5708            Visitor { db, owner: self.owner, callback, visited: FxHashSet::default() };
5709        self.ty.skip_binder().visit_with(&mut visitor);
5710    }
5711    /// Check if type unifies with another type.
5712    ///
5713    /// Note that we consider placeholder types to unify with everything.
5714    /// For example `Option<T>` and `Option<U>` unify although there is unresolved goal `T = U`.
5715    pub fn could_unify_with(&self, db: &'db dyn HirDatabase, other: &Type<'db>) -> bool {
5716        self.owner.must_unify(other.owner);
5717        let env = self.param_env(db);
5718        let interner = DbInterner::new_no_crate(db);
5719        let tys = hir_ty::replace_errors_with_variables(
5720            interner,
5721            &(self.ty.skip_binder(), other.ty.skip_binder()),
5722        );
5723        hir_ty::could_unify(db, env, &tys)
5724    }
5725
5726    /// Check if type unifies with another type eagerly making sure there are no unresolved goals.
5727    ///
5728    /// This means that placeholder types are not considered to unify if there are any bounds set on
5729    /// them. For example `Option<T>` and `Option<U>` do not unify as we cannot show that `T = U`
5730    pub fn could_unify_with_deeply(&self, db: &'db dyn HirDatabase, other: &Type<'db>) -> bool {
5731        self.owner.must_unify(other.owner);
5732        let env = self.param_env(db);
5733        let interner = DbInterner::new_no_crate(db);
5734        let tys = hir_ty::replace_errors_with_variables(
5735            interner,
5736            &(self.ty.skip_binder(), other.ty.skip_binder()),
5737        );
5738        hir_ty::could_unify_deeply(db, env, &tys)
5739    }
5740
5741    pub fn could_coerce_to(&self, db: &'db dyn HirDatabase, to: &Type<'db>) -> bool {
5742        self.owner.must_unify(to.owner);
5743        let env = self.param_env(db);
5744        let interner = DbInterner::new_no_crate(db);
5745        let tys = hir_ty::replace_errors_with_variables(
5746            interner,
5747            &(self.ty.skip_binder(), to.ty.skip_binder()),
5748        );
5749        hir_ty::could_coerce(db, env, &tys)
5750    }
5751
5752    pub fn as_type_param(&self, _db: &'db dyn HirDatabase) -> Option<TypeParam> {
5753        match self.ty.skip_binder().kind() {
5754            TyKind::Param(param) => Some(TypeParam { id: param.id }),
5755            _ => None,
5756        }
5757    }
5758
5759    /// Returns unique `GenericParam`s contained in this type.
5760    pub fn generic_params(&self, db: &'db dyn HirDatabase) -> FxHashSet<GenericParam> {
5761        hir_ty::collect_params(&self.ty.skip_binder())
5762            .into_iter()
5763            .map(|id| TypeOrConstParam { id }.split(db).either_into())
5764            .collect()
5765    }
5766
5767    pub fn layout(&self, db: &'db dyn HirDatabase) -> Result<Layout<'db>, LayoutError> {
5768        let env = self.param_env(db);
5769        db.layout_of_ty(self.ty.skip_binder().store(), env.store())
5770            .map(|layout| Layout(layout, db.target_data_layout(env.krate).unwrap()))
5771    }
5772
5773    pub fn drop_glue(&self, db: &'db dyn HirDatabase) -> DropGlue {
5774        let env = self.param_env(db);
5775        let interner = DbInterner::new_with(db, env.krate);
5776        let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
5777        hir_ty::drop::has_drop_glue(&infcx, self.ty.skip_binder(), env.param_env)
5778    }
5779}
5780
5781#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
5782pub struct InlineAsmOperand {
5783    owner: ExpressionStoreOwnerId,
5784    expr: ExprId,
5785    index: usize,
5786}
5787
5788impl InlineAsmOperand {
5789    pub fn parent(self, _db: &dyn HirDatabase) -> ExpressionStoreOwner {
5790        self.owner.into()
5791    }
5792
5793    pub fn name(&self, db: &dyn HirDatabase) -> Option<Name> {
5794        let body = ExpressionStore::of(db, self.owner);
5795        match &body[self.expr] {
5796            hir_def::hir::Expr::InlineAsm(e) => e.operands.get(self.index)?.0.clone(),
5797            _ => None,
5798        }
5799    }
5800}
5801
5802// FIXME: Document this
5803#[derive(Debug)]
5804pub struct Callable<'db> {
5805    ty: Type<'db>,
5806    sig: PolyFnSig<'db>,
5807    callee: Callee<'db>,
5808    /// Whether this is a method that was called with method call syntax.
5809    is_bound_method: bool,
5810}
5811
5812#[derive(Clone, PartialEq, Eq, Hash, Debug)]
5813enum Callee<'db> {
5814    Def(CallableDefId),
5815    Closure(InternedClosureId<'db>, GenericArgs<'db>),
5816    CoroutineClosure(InternedCoroutineClosureId<'db>, GenericArgs<'db>),
5817    FnPtr,
5818    FnImpl(traits::FnTrait),
5819    BuiltinDeriveImplMethod { method: BuiltinDeriveImplMethod, impl_: BuiltinDeriveImplId },
5820}
5821
5822pub enum CallableKind<'db> {
5823    Function(Function),
5824    TupleStruct(Struct),
5825    TupleEnumVariant(EnumVariant),
5826    Closure(Closure<'db>),
5827    FnPtr,
5828    FnImpl(FnTrait),
5829}
5830
5831impl<'db> Callable<'db> {
5832    fn erased_sig(&self) -> FnSig<'db> {
5833        DbInterner::conjure().instantiate_bound_regions_with_erased(self.sig)
5834    }
5835
5836    pub fn kind(&self) -> CallableKind<'db> {
5837        match self.callee {
5838            Callee::Def(CallableDefId::FunctionId(it)) => CallableKind::Function(it.into()),
5839            Callee::BuiltinDeriveImplMethod { method, impl_ } => CallableKind::Function(Function {
5840                id: AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ },
5841            }),
5842            Callee::Def(CallableDefId::StructId(it)) => CallableKind::TupleStruct(it.into()),
5843            Callee::Def(CallableDefId::EnumVariantId(it)) => {
5844                CallableKind::TupleEnumVariant(it.into())
5845            }
5846            Callee::Closure(id, subst) => CallableKind::Closure(Closure {
5847                id: AnyClosureId::ClosureId(id),
5848                subst,
5849                owner: self.ty.owner,
5850            }),
5851            Callee::CoroutineClosure(id, subst) => CallableKind::Closure(Closure {
5852                id: AnyClosureId::CoroutineClosureId(id),
5853                subst,
5854                owner: self.ty.owner,
5855            }),
5856            Callee::FnPtr => CallableKind::FnPtr,
5857            Callee::FnImpl(fn_) => CallableKind::FnImpl(fn_.into()),
5858        }
5859    }
5860
5861    fn as_function(&self) -> Option<Function> {
5862        match self.callee {
5863            Callee::Def(CallableDefId::FunctionId(it)) => Some(it.into()),
5864            Callee::BuiltinDeriveImplMethod { method, impl_ } => {
5865                Some(Function { id: AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ } })
5866            }
5867            _ => None,
5868        }
5869    }
5870
5871    pub fn receiver_param(&self, db: &'db dyn HirDatabase) -> Option<(SelfParam, Type<'db>)> {
5872        if !self.is_bound_method {
5873            return None;
5874        }
5875        let func = self.as_function()?;
5876        Some((func.self_param(db)?, self.ty.derived(self.erased_sig().inputs()[0])))
5877    }
5878    pub fn n_params(&self) -> usize {
5879        self.sig.skip_binder().inputs_and_output.inputs().len()
5880            - if self.is_bound_method { 1 } else { 0 }
5881    }
5882    pub fn params(&self) -> Vec<Param<'db>> {
5883        self.erased_sig()
5884            .inputs()
5885            .iter()
5886            .enumerate()
5887            .skip(if self.is_bound_method { 1 } else { 0 })
5888            .map(|(idx, ty)| (idx, self.ty.derived(*ty)))
5889            .map(|(idx, ty)| Param { func: self.callee.clone(), idx, ty })
5890            .collect()
5891    }
5892    pub fn return_type(&self) -> Type<'db> {
5893        self.ty.derived(self.erased_sig().output())
5894    }
5895    pub fn sig(&self) -> impl Eq {
5896        &self.sig
5897    }
5898
5899    pub fn ty(&self) -> &Type<'db> {
5900        &self.ty
5901    }
5902}
5903
5904#[derive(Clone, Debug, Eq, PartialEq)]
5905pub struct Layout<'db>(Arc<TyLayout>, &'db TargetDataLayout);
5906
5907impl<'db> Layout<'db> {
5908    pub fn size(&self) -> u64 {
5909        self.0.size.bytes()
5910    }
5911
5912    pub fn align(&self) -> u64 {
5913        self.0.align.bytes()
5914    }
5915
5916    pub fn niches(&self) -> Option<u128> {
5917        Some(self.0.largest_niche?.available(self.1))
5918    }
5919
5920    pub fn field_offset(&self, field: Field) -> Option<u64> {
5921        match self.0.fields {
5922            layout::FieldsShape::Primitive => None,
5923            layout::FieldsShape::Union(_) => Some(0),
5924            layout::FieldsShape::Array { stride, count } => {
5925                let i = u64::try_from(field.index()).ok()?;
5926                (i < count).then_some((stride * i).bytes())
5927            }
5928            layout::FieldsShape::Arbitrary { ref offsets, .. } => {
5929                Some(offsets.get(RustcFieldIdx(field.id))?.bytes())
5930            }
5931        }
5932    }
5933
5934    pub fn tuple_field_offset(&self, field: usize) -> Option<u64> {
5935        match self.0.fields {
5936            layout::FieldsShape::Primitive => None,
5937            layout::FieldsShape::Union(_) => Some(0),
5938            layout::FieldsShape::Array { stride, count } => {
5939                let i = u64::try_from(field).ok()?;
5940                (i < count).then_some((stride * i).bytes())
5941            }
5942            layout::FieldsShape::Arbitrary { ref offsets, .. } => {
5943                Some(offsets.get(RustcFieldIdx::new(field))?.bytes())
5944            }
5945        }
5946    }
5947
5948    pub fn tail_padding(&self, field_size: &mut impl FnMut(usize) -> Option<u64>) -> Option<u64> {
5949        match self.0.fields {
5950            layout::FieldsShape::Primitive => None,
5951            layout::FieldsShape::Union(_) => None,
5952            layout::FieldsShape::Array { stride, count } => count.checked_sub(1).and_then(|tail| {
5953                let tail_field_size = field_size(tail as usize)?;
5954                let offset = stride.bytes() * tail;
5955                self.0.size.bytes().checked_sub(offset)?.checked_sub(tail_field_size)
5956            }),
5957            layout::FieldsShape::Arbitrary { ref offsets, ref in_memory_order } => {
5958                let tail = in_memory_order[in_memory_order.len().checked_sub(1)? as u32];
5959                let tail_field_size = field_size(tail.0.into_raw().into_u32() as usize)?;
5960                let offset = offsets.get(tail)?.bytes();
5961                self.0.size.bytes().checked_sub(offset)?.checked_sub(tail_field_size)
5962            }
5963        }
5964    }
5965
5966    pub fn largest_padding(
5967        &self,
5968        field_size: &mut impl FnMut(usize) -> Option<u64>,
5969    ) -> Option<u64> {
5970        match self.0.fields {
5971            layout::FieldsShape::Primitive => None,
5972            layout::FieldsShape::Union(_) => None,
5973            layout::FieldsShape::Array { stride: _, count: 0 } => None,
5974            layout::FieldsShape::Array { stride, .. } => {
5975                let size = field_size(0)?;
5976                stride.bytes().checked_sub(size)
5977            }
5978            layout::FieldsShape::Arbitrary { ref offsets, ref in_memory_order } => {
5979                let mut reverse_index = vec![None; in_memory_order.len()];
5980                for (mem, src) in in_memory_order.iter().enumerate() {
5981                    reverse_index[mem] =
5982                        Some((src.0.into_raw().into_u32() as usize, offsets[*src].bytes()));
5983                }
5984                if reverse_index.iter().any(|it| it.is_none()) {
5985                    stdx::never!();
5986                    return None;
5987                }
5988                reverse_index
5989                    .into_iter()
5990                    .flatten()
5991                    .chain(iter::once((0, self.0.size.bytes())))
5992                    .array_windows()
5993                    .filter_map(|[(i, start), (_, end)]| {
5994                        let size = field_size(i)?;
5995                        end.checked_sub(start)?.checked_sub(size)
5996                    })
5997                    .max()
5998            }
5999        }
6000    }
6001
6002    pub fn enum_tag_size(&self) -> Option<usize> {
6003        let tag_size =
6004            if let layout::Variants::Multiple { tag, tag_encoding, .. } = &self.0.variants {
6005                match tag_encoding {
6006                    TagEncoding::Direct => tag.size(self.1).bytes_usize(),
6007                    TagEncoding::Niche { .. } => 0,
6008                }
6009            } else {
6010                return None;
6011            };
6012        Some(tag_size)
6013    }
6014}
6015
6016#[derive(Copy, Clone, Debug, Eq, PartialEq)]
6017pub enum BindingMode {
6018    Move,
6019    Ref(Mutability),
6020}
6021
6022/// For IDE only
6023#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
6024pub enum ScopeDef<'db> {
6025    ModuleDef(ModuleDef),
6026    GenericParam(GenericParam),
6027    ImplSelfType(Impl),
6028    AdtSelfType(Adt),
6029    Local(Local<'db>),
6030    Label(Label),
6031    Unknown,
6032}
6033
6034impl ScopeDef<'_> {
6035    pub fn all_items(def: PerNs) -> ArrayVec<Self, 3> {
6036        let mut items = ArrayVec::new();
6037
6038        match (def.take_types(), def.take_values()) {
6039            (Some(m1), None) => items.push(ScopeDef::ModuleDef(m1.into())),
6040            (None, Some(m2)) => items.push(ScopeDef::ModuleDef(m2.into())),
6041            (Some(m1), Some(m2)) => {
6042                // Some items, like unit structs and enum variants, are
6043                // returned as both a type and a value. Here we want
6044                // to de-duplicate them.
6045                if m1 != m2 {
6046                    items.push(ScopeDef::ModuleDef(m1.into()));
6047                    items.push(ScopeDef::ModuleDef(m2.into()));
6048                } else {
6049                    items.push(ScopeDef::ModuleDef(m1.into()));
6050                }
6051            }
6052            (None, None) => {}
6053        };
6054
6055        if let Some(macro_def_id) = def.take_macros() {
6056            items.push(ScopeDef::ModuleDef(ModuleDef::Macro(macro_def_id.into())));
6057        }
6058
6059        if items.is_empty() {
6060            items.push(ScopeDef::Unknown);
6061        }
6062
6063        items
6064    }
6065
6066    pub fn attrs(&self, db: &dyn HirDatabase) -> Option<AttrsWithOwner> {
6067        match self {
6068            ScopeDef::ModuleDef(it) => it.attrs(db),
6069            ScopeDef::GenericParam(it) => Some(it.attrs(db)),
6070            ScopeDef::ImplSelfType(_)
6071            | ScopeDef::AdtSelfType(_)
6072            | ScopeDef::Local(_)
6073            | ScopeDef::Label(_)
6074            | ScopeDef::Unknown => None,
6075        }
6076    }
6077
6078    pub fn krate(&self, db: &dyn HirDatabase) -> Option<Crate> {
6079        match self {
6080            ScopeDef::ModuleDef(it) => it.module(db).map(|m| m.krate(db)),
6081            ScopeDef::GenericParam(it) => Some(it.module(db).krate(db)),
6082            ScopeDef::ImplSelfType(_) => None,
6083            ScopeDef::AdtSelfType(it) => Some(it.module(db).krate(db)),
6084            ScopeDef::Local(it) => Some(it.module(db).krate(db)),
6085            ScopeDef::Label(it) => Some(it.module(db).krate(db)),
6086            ScopeDef::Unknown => None,
6087        }
6088    }
6089}
6090
6091impl_from!(
6092    impl<'db>
6093    ItemInNs { Types => ModuleDef, Values => ModuleDef, Macros => ModuleDef }
6094    for ScopeDef<'db>
6095);
6096
6097#[derive(Clone, Debug, PartialEq, Eq)]
6098pub struct Adjustment<'db> {
6099    pub source: Type<'db>,
6100    pub target: Type<'db>,
6101    pub kind: Adjust,
6102}
6103
6104#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
6105pub enum Adjust {
6106    /// Go from ! to any type.
6107    NeverToAny,
6108    /// Dereference once, producing a place.
6109    Deref(Option<OverloadedDeref>),
6110    /// Take the address and produce either a `&` or `*` pointer.
6111    Borrow(AutoBorrow),
6112    Pointer(PointerCast),
6113}
6114
6115#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
6116pub enum AutoBorrow {
6117    /// Converts from T to &T.
6118    Ref(Mutability),
6119    /// Converts from T to *T.
6120    RawPtr(Mutability),
6121}
6122
6123#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
6124pub struct OverloadedDeref(pub Mutability);
6125
6126pub trait HasVisibility {
6127    fn visibility(&self, db: &dyn HirDatabase) -> Visibility;
6128    fn is_visible_from(&self, db: &dyn HirDatabase, module: Module) -> bool {
6129        let vis = self.visibility(db);
6130        vis.is_visible_from(db, module.id)
6131    }
6132}
6133
6134#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6135pub enum PredicatePolarity {
6136    /// `T: Trait`
6137    Positive,
6138    /// `T: !Trait`
6139    Negative,
6140}
6141
6142#[derive(Debug, Clone, PartialEq, Eq)]
6143pub struct TraitPredicate<'db> {
6144    inner: hir_ty::next_solver::TraitPredicate<'db>,
6145    owner: TypeOwnerId,
6146}
6147
6148impl<'db> TraitPredicate<'db> {
6149    pub fn polarity(&self) -> PredicatePolarity {
6150        match self.inner.polarity {
6151            rustc_type_ir::PredicatePolarity::Positive => PredicatePolarity::Positive,
6152            rustc_type_ir::PredicatePolarity::Negative => PredicatePolarity::Negative,
6153        }
6154    }
6155
6156    pub fn trait_ref(&self) -> TraitRef<'db> {
6157        TraitRef { owner: self.owner, trait_ref: self.inner.trait_ref }
6158    }
6159}
6160
6161/// Trait for obtaining the defining crate of an item.
6162pub trait HasCrate {
6163    fn krate(&self, db: &dyn HirDatabase) -> Crate;
6164}
6165
6166impl<T: hir_def::HasModule> HasCrate for T {
6167    fn krate(&self, db: &dyn HirDatabase) -> Crate {
6168        self.module(db).krate(db).into()
6169    }
6170}
6171
6172impl HasCrate for AssocItem {
6173    fn krate(&self, db: &dyn HirDatabase) -> Crate {
6174        self.module(db).krate(db)
6175    }
6176}
6177
6178impl HasCrate for Struct {
6179    fn krate(&self, db: &dyn HirDatabase) -> Crate {
6180        self.module(db).krate(db)
6181    }
6182}
6183
6184impl HasCrate for Union {
6185    fn krate(&self, db: &dyn HirDatabase) -> Crate {
6186        self.module(db).krate(db)
6187    }
6188}
6189
6190impl HasCrate for Enum {
6191    fn krate(&self, db: &dyn HirDatabase) -> Crate {
6192        self.module(db).krate(db)
6193    }
6194}
6195
6196impl HasCrate for Field {
6197    fn krate(&self, db: &dyn HirDatabase) -> Crate {
6198        self.parent_def(db).module(db).krate(db)
6199    }
6200}
6201
6202impl HasCrate for EnumVariant {
6203    fn krate(&self, db: &dyn HirDatabase) -> Crate {
6204        self.module(db).krate(db)
6205    }
6206}
6207
6208impl HasCrate for Function {
6209    fn krate(&self, db: &dyn HirDatabase) -> Crate {
6210        self.module(db).krate(db)
6211    }
6212}
6213
6214impl HasCrate for Const {
6215    fn krate(&self, db: &dyn HirDatabase) -> Crate {
6216        self.module(db).krate(db)
6217    }
6218}
6219
6220impl HasCrate for TypeAlias {
6221    fn krate(&self, db: &dyn HirDatabase) -> Crate {
6222        self.module(db).krate(db)
6223    }
6224}
6225
6226impl HasCrate for Type<'_> {
6227    fn krate(&self, db: &dyn HirDatabase) -> Crate {
6228        self.krate(db).into()
6229    }
6230}
6231
6232impl HasCrate for Macro {
6233    fn krate(&self, db: &dyn HirDatabase) -> Crate {
6234        self.module(db).krate(db)
6235    }
6236}
6237
6238impl HasCrate for Trait {
6239    fn krate(&self, db: &dyn HirDatabase) -> Crate {
6240        self.module(db).krate(db)
6241    }
6242}
6243
6244impl HasCrate for Static {
6245    fn krate(&self, db: &dyn HirDatabase) -> Crate {
6246        self.module(db).krate(db)
6247    }
6248}
6249
6250impl HasCrate for Adt {
6251    fn krate(&self, db: &dyn HirDatabase) -> Crate {
6252        self.module(db).krate(db)
6253    }
6254}
6255
6256impl HasCrate for Impl {
6257    fn krate(&self, db: &dyn HirDatabase) -> Crate {
6258        self.module(db).krate(db)
6259    }
6260}
6261
6262impl HasCrate for Module {
6263    fn krate(&self, db: &dyn HirDatabase) -> Crate {
6264        Module::krate(*self, db)
6265    }
6266}
6267
6268impl<'db> HasCrate for AnonConst<'db> {
6269    fn krate(&self, db: &dyn HirDatabase) -> Crate {
6270        hir_def::HasModule::krate(&self.id.loc(db).owner, db).into()
6271    }
6272}
6273
6274pub trait HasContainer {
6275    fn container(&self, db: &dyn HirDatabase) -> ItemContainer;
6276}
6277
6278impl HasContainer for ExternCrateDecl {
6279    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
6280        container_id_to_hir(self.id.lookup(db).container.into())
6281    }
6282}
6283
6284impl HasContainer for Module {
6285    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
6286        // FIXME: handle block expressions as modules (their parent is in a different DefMap)
6287        let def_map = self.id.def_map(db);
6288        match def_map[self.id].parent {
6289            Some(parent_id) => ItemContainer::Module(Module { id: parent_id }),
6290            None => ItemContainer::Crate(def_map.krate().into()),
6291        }
6292    }
6293}
6294
6295impl HasContainer for Function {
6296    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
6297        match self.id {
6298            AnyFunctionId::FunctionId(id) => container_id_to_hir(id.lookup(db).container),
6299            AnyFunctionId::BuiltinDeriveImplMethod { impl_, .. } => {
6300                ItemContainer::Impl(Impl { id: AnyImplId::BuiltinDeriveImplId(impl_) })
6301            }
6302        }
6303    }
6304}
6305
6306impl HasContainer for Struct {
6307    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
6308        ItemContainer::Module(Module { id: self.id.lookup(db).container })
6309    }
6310}
6311
6312impl HasContainer for Union {
6313    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
6314        ItemContainer::Module(Module { id: self.id.lookup(db).container })
6315    }
6316}
6317
6318impl HasContainer for Enum {
6319    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
6320        ItemContainer::Module(Module { id: self.id.lookup(db).container })
6321    }
6322}
6323
6324impl HasContainer for TypeAlias {
6325    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
6326        container_id_to_hir(self.id.lookup(db).container)
6327    }
6328}
6329
6330impl HasContainer for Const {
6331    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
6332        container_id_to_hir(self.id.lookup(db).container)
6333    }
6334}
6335
6336impl HasContainer for Static {
6337    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
6338        container_id_to_hir(self.id.lookup(db).container)
6339    }
6340}
6341
6342impl HasContainer for Trait {
6343    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
6344        ItemContainer::Module(Module { id: self.id.lookup(db).container })
6345    }
6346}
6347
6348impl HasContainer for ExternBlock {
6349    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
6350        ItemContainer::Module(Module { id: self.id.lookup(db).container })
6351    }
6352}
6353
6354pub trait HasName {
6355    fn name(&self, db: &dyn HirDatabase) -> Option<Name>;
6356}
6357
6358macro_rules! impl_has_name {
6359    ( $( $ty:ident ),* $(,)? ) => {
6360        $(
6361            impl HasName for $ty {
6362                fn name(&self, db: &dyn HirDatabase) -> Option<Name> {
6363                    (*self).name(db).into()
6364                }
6365            }
6366        )*
6367    };
6368}
6369
6370impl_has_name!(
6371    ModuleDef,
6372    Module,
6373    Field,
6374    Struct,
6375    Union,
6376    Enum,
6377    EnumVariant,
6378    Adt,
6379    Variant,
6380    DefWithBody,
6381    Function,
6382    ExternCrateDecl,
6383    Const,
6384    Static,
6385    Trait,
6386    TypeAlias,
6387    Macro,
6388    ExternAssocItem,
6389    AssocItem,
6390    DeriveHelper,
6391    ToolModule,
6392    Label,
6393    GenericParam,
6394    TypeParam,
6395    LifetimeParam,
6396    ConstParam,
6397    TypeOrConstParam,
6398    InlineAsmOperand,
6399);
6400
6401macro_rules! impl_has_name_no_db {
6402    ( $( $ty:ident ),* $(,)? ) => {
6403        $(
6404            impl HasName for $ty {
6405                fn name(&self, _db: &dyn HirDatabase) -> Option<Name> {
6406                    (*self).name().into()
6407                }
6408            }
6409        )*
6410    };
6411}
6412
6413impl_has_name_no_db!(StaticLifetime, BuiltinType, BuiltinAttr);
6414
6415impl HasName for Local<'_> {
6416    fn name(&self, db: &dyn HirDatabase) -> Option<Name> {
6417        (*self).name(db).into()
6418    }
6419}
6420
6421impl HasName for TupleField<'_> {
6422    fn name(&self, _db: &dyn HirDatabase) -> Option<Name> {
6423        (*self).name().into()
6424    }
6425}
6426
6427impl HasName for Param<'_> {
6428    fn name(&self, db: &dyn HirDatabase) -> Option<Name> {
6429        self.name(db)
6430    }
6431}
6432
6433fn container_id_to_hir(c: ItemContainerId) -> ItemContainer {
6434    match c {
6435        ItemContainerId::ExternBlockId(id) => ItemContainer::ExternBlock(ExternBlock { id }),
6436        ItemContainerId::ModuleId(id) => ItemContainer::Module(Module { id }),
6437        ItemContainerId::ImplId(id) => ItemContainer::Impl(id.into()),
6438        ItemContainerId::TraitId(id) => ItemContainer::Trait(Trait { id }),
6439    }
6440}
6441
6442#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6443pub enum ItemContainer {
6444    Trait(Trait),
6445    Impl(Impl),
6446    Module(Module),
6447    ExternBlock(ExternBlock),
6448    Crate(Crate),
6449}
6450
6451/// Subset of `ide_db::Definition` that doc links can resolve to.
6452pub enum DocLinkDef {
6453    ModuleDef(ModuleDef),
6454    Field(Field),
6455    SelfType(Trait),
6456}
6457
6458pub trait MethodCandidateCallback {
6459    fn on_inherent_method(&mut self, f: Function) -> ControlFlow<()>;
6460
6461    fn on_trait_method(&mut self, f: Function) -> ControlFlow<()>;
6462}
6463
6464impl<F> MethodCandidateCallback for F
6465where
6466    F: FnMut(Function) -> ControlFlow<()>,
6467{
6468    fn on_inherent_method(&mut self, f: Function) -> ControlFlow<()> {
6469        self(f)
6470    }
6471
6472    fn on_trait_method(&mut self, f: Function) -> ControlFlow<()> {
6473        self(f)
6474    }
6475}
6476
6477pub trait PathCandidateCallback {
6478    fn on_inherent_item(&mut self, item: AssocItem) -> ControlFlow<()>;
6479
6480    fn on_trait_item(&mut self, item: AssocItem) -> ControlFlow<()>;
6481}
6482
6483impl<F> PathCandidateCallback for F
6484where
6485    F: FnMut(AssocItem) -> ControlFlow<()>,
6486{
6487    fn on_inherent_item(&mut self, item: AssocItem) -> ControlFlow<()> {
6488        self(item)
6489    }
6490
6491    fn on_trait_item(&mut self, item: AssocItem) -> ControlFlow<()> {
6492        self(item)
6493    }
6494}
6495
6496pub fn resolve_absolute_path<'a, I: Iterator<Item = Symbol> + Clone + 'a>(
6497    db: &'a dyn HirDatabase,
6498    mut segments: I,
6499) -> impl Iterator<Item = ItemInNs> + use<'a, I> {
6500    segments
6501        .next()
6502        .into_iter()
6503        .flat_map(move |crate_name| {
6504            all_crates(db)
6505                .iter()
6506                .filter(|&krate| {
6507                    krate
6508                        .extra_data(db)
6509                        .display_name
6510                        .as_ref()
6511                        .is_some_and(|name| *name.crate_name().symbol() == crate_name)
6512                })
6513                .filter_map(|&krate| {
6514                    let segments = segments.clone();
6515                    let mut def_map = crate_def_map(db, krate);
6516                    let mut module = &def_map[def_map.root_module_id()];
6517                    let mut segments = segments.with_position().peekable();
6518                    while let Some((_, segment)) =
6519                        segments.next_if(|&(position, _)| !position.is_last)
6520                    {
6521                        let res = module
6522                            .scope
6523                            .get(&Name::new_symbol_root(segment))
6524                            .take_types()
6525                            .and_then(|res| match res {
6526                                ModuleDefId::ModuleId(it) => Some(it),
6527                                _ => None,
6528                            })?;
6529                        def_map = res.def_map(db);
6530                        module = &def_map[res];
6531                    }
6532                    let (_, item_name) = segments.next()?;
6533                    let res = module.scope.get(&Name::new_symbol_root(item_name));
6534                    Some(res.iter_items().map(|(item, _)| item.into()))
6535                })
6536                .collect::<Vec<_>>()
6537        })
6538        .flatten()
6539}
6540
6541fn as_name_opt(name: Option<impl AsName>) -> Name {
6542    name.map_or_else(Name::missing, |name| name.as_name())
6543}
6544
6545#[track_caller]
6546fn generic_args_from_tys<'db>(
6547    interner: DbInterner<'db>,
6548    def_id: SolverDefId<'db>,
6549    args: impl IntoIterator<Item: Borrow<Type<'db>>>,
6550) -> (GenericArgs<'db>, TypeOwnerId) {
6551    let mut owner = None::<TypeOwnerId>;
6552    let mut args = args.into_iter();
6553    let args = GenericArgs::for_item(interner, def_id, |_, id, _, _| {
6554        if matches!(id, GenericParamId::TypeParamId(_))
6555            && let Some(arg) = args.next()
6556        {
6557            let arg = arg.borrow();
6558
6559            match &mut owner {
6560                Some(owner) => *owner = owner.must_unify(arg.owner),
6561                None => owner = Some(arg.owner),
6562            }
6563
6564            arg.ty.skip_binder().into()
6565        } else {
6566            next_solver::GenericArg::error_from_id(interner, id)
6567        }
6568    });
6569    let owner =
6570        owner.unwrap_or_else(|| TypeOwnerId::NoParams(Type::builtin_type_crate(interner.db())));
6571    (args, owner)
6572}
6573
6574fn has_non_default_type_params(db: &dyn HirDatabase, generic_def: GenericDefId) -> bool {
6575    let params = GenericParams::of(db, generic_def);
6576    let defaults = db.generic_defaults(generic_def);
6577    params
6578        .iter_type_or_consts()
6579        .filter(|(_, param)| matches!(param, TypeOrConstParamData::TypeParamData(_)))
6580        .map(|(local_id, _)| TypeOrConstParamId { parent: generic_def, local_id })
6581        .any(|param| {
6582            let param = hir_ty::type_or_const_param_idx(db, param);
6583            defaults.get(param as usize).is_none()
6584        })
6585}
6586
6587fn param_env_from_has_crate<'db>(
6588    db: &'db dyn HirDatabase,
6589    id: impl hir_def::HasModule + Into<GenericDefId> + Copy,
6590) -> ParamEnvAndCrate<'db> {
6591    ParamEnvAndCrate { param_env: db.trait_environment(id.into()), krate: id.krate(db) }
6592}
6593
6594// FIXME: We probably don't want to expose this.
6595pub trait MacroCallIdExt {
6596    fn loc(self, db: &dyn HirDatabase) -> &hir_expand::MacroCallLoc;
6597}
6598impl MacroCallIdExt for span::MacroCallId {
6599    #[inline]
6600    fn loc(self, db: &dyn HirDatabase) -> &hir_expand::MacroCallLoc {
6601        hir_expand::MacroCallId::from(self).loc(db)
6602    }
6603}
6604
6605// Like https://github.com/rust-lang/rust/blob/7c3c88f42ad444f4688b865591d84660be4ece2f/compiler/rustc_middle/src/ty/util.rs#L254-L310
6606fn struct_tail_raw<'db>(
6607    db: &'db dyn HirDatabase,
6608    interner: DbInterner<'db>,
6609    mut ty: Ty<'db>,
6610    mut normalize: impl FnMut(Ty<'db>) -> Ty<'db>,
6611) -> Ty<'db> {
6612    let recursion_limit = 16;
6613    for iteration in 0.. {
6614        if iteration >= recursion_limit {
6615            return Ty::new_error(interner, ErrorGuaranteed);
6616        }
6617        match ty.kind() {
6618            TyKind::Adt(def, args) => {
6619                let AdtId::StructId(def_id) = def.def_id() else { break };
6620                let last_field = db.field_types(def_id.into()).iter().next_back();
6621                match last_field {
6622                    Some((_, field)) => {
6623                        ty = normalize(field.ty().instantiate(interner, args).skip_norm_wip())
6624                    }
6625                    None => break,
6626                }
6627            }
6628            TyKind::Tuple(tys) if let Some((&last_ty, _)) = tys.split_last() => {
6629                ty = last_ty;
6630            }
6631            TyKind::Tuple(_) => break,
6632            TyKind::Pat(inner, _) => {
6633                ty = inner;
6634            }
6635            _ => {
6636                break;
6637            }
6638        }
6639    }
6640    ty
6641}