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