ra_ap_hir/
lib.rs

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