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