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