• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #![warn(rust_2018_idioms, unused_lifetimes, semicolon_in_expressions_from_macros)]
21 #![recursion_limit = "512"]
22 
23 mod semantics;
24 mod source_analyzer;
25 
26 mod from_id;
27 mod attrs;
28 mod has_source;
29 
30 pub mod diagnostics;
31 pub mod db;
32 pub mod symbols;
33 
34 mod display;
35 
36 use std::{iter, ops::ControlFlow};
37 
38 use arrayvec::ArrayVec;
39 use base_db::{CrateDisplayName, CrateId, CrateOrigin, Edition, FileId, ProcMacroKind};
40 use either::Either;
41 use hir_def::{
42     body::{BodyDiagnostic, SyntheticSyntax},
43     data::adt::VariantData,
44     generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
45     hir::{BindingAnnotation, BindingId, ExprOrPatId, LabelId, Pat},
46     item_tree::ItemTreeNode,
47     lang_item::LangItemTarget,
48     layout::{self, ReprOptions, TargetDataLayout},
49     macro_id_to_def_id,
50     nameres::{self, diagnostics::DefDiagnostic, ModuleOrigin},
51     per_ns::PerNs,
52     resolver::{HasResolver, Resolver},
53     src::HasSource as _,
54     AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId,
55     EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, InTypeConstId, ItemContainerId,
56     LifetimeParamId, LocalEnumVariantId, LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId,
57     StaticId, StructId, TraitAliasId, TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId,
58     UnionId,
59 };
60 use hir_expand::{name::name, MacroCallKind};
61 use hir_ty::{
62     all_super_traits, autoderef,
63     consteval::{try_const_usize, unknown_const_as_generic, ConstEvalError, ConstExt},
64     diagnostics::BodyValidationDiagnostic,
65     display::HexifiedConst,
66     layout::{Layout as TyLayout, RustcEnumVariantIdx, TagEncoding},
67     method_resolution::{self, TyFingerprint},
68     mir::{self, interpret_mir},
69     primitive::UintTy,
70     traits::FnTrait,
71     AliasTy, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, ClosureId,
72     GenericArgData, Interner, ParamKind, QuantifiedWhereClause, Scalar, Substitution,
73     TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind, ValueTyDefId,
74     WhereClause,
75 };
76 use itertools::Itertools;
77 use nameres::diagnostics::DefDiagnosticKind;
78 use once_cell::unsync::Lazy;
79 use rustc_hash::FxHashSet;
80 use stdx::{impl_from, never};
81 use syntax::{
82     ast::{self, HasAttrs as _, HasDocComments, HasName},
83     AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, TextRange, T,
84 };
85 use triomphe::Arc;
86 
87 use crate::db::{DefDatabase, HirDatabase};
88 
89 pub use crate::{
90     attrs::{HasAttrs, Namespace},
91     diagnostics::{
92         AnyDiagnostic, BreakOutsideOfLoop, ExpectedFunction, InactiveCode, IncoherentImpl,
93         IncorrectCase, InvalidDeriveTarget, MacroDefError, MacroError, MacroExpansionParseError,
94         MalformedDerive, MismatchedArgCount, MissingFields, MissingMatchArms, MissingUnsafe,
95         MovedOutOfRef, NeedMut, NoSuchField, PrivateAssocItem, PrivateField,
96         ReplaceFilterMapNextWithFindMap, TypeMismatch, TypedHole, UndeclaredLabel,
97         UnimplementedBuiltinMacro, UnreachableLabel, UnresolvedExternCrate, UnresolvedField,
98         UnresolvedImport, UnresolvedMacroCall, UnresolvedMethodCall, UnresolvedModule,
99         UnresolvedProcMacro, UnusedMut,
100     },
101     has_source::HasSource,
102     semantics::{PathResolution, Semantics, SemanticsScope, TypeInfo, VisibleTraits},
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!
114 pub use {
115     cfg::{CfgAtom, CfgExpr, CfgOptions},
116     hir_def::{
117         attr::{builtin::AttributeTemplate, Attrs, AttrsWithOwner, Documentation},
118         data::adt::StructKind,
119         find_path::PrefixKind,
120         import_map,
121         lang_item::LangItem,
122         nameres::{DefMap, ModuleSource},
123         path::{ModPath, PathKind},
124         type_ref::{Mutability, TypeRef},
125         visibility::Visibility,
126         // FIXME: This is here since some queries take it as input that are used
127         // outside of hir.
128         {AdtId, ModuleDefId},
129     },
130     hir_expand::{
131         attrs::Attr,
132         name::{known, Name},
133         ExpandResult, HirFileId, InFile, MacroFile, Origin,
134     },
135     hir_ty::{
136         display::{ClosureStyle, HirDisplay, HirDisplayError, HirWrite},
137         layout::LayoutError,
138         mir::MirEvalError,
139         PointerCast, Safety,
140     },
141 };
142 
143 // These are negative re-exports: pub using these names is forbidden, they
144 // should remain private to hir internals.
145 #[allow(unused)]
146 use {
147     hir_def::path::Path,
148     hir_expand::{hygiene::Hygiene, name::AsName},
149 };
150 
151 /// hir::Crate describes a single crate. It's the main interface with which
152 /// a crate's dependencies interact. Mostly, it should be just a proxy for the
153 /// root module.
154 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
155 pub struct Crate {
156     pub(crate) id: CrateId,
157 }
158 
159 #[derive(Debug)]
160 pub struct CrateDependency {
161     pub krate: Crate,
162     pub name: Name,
163 }
164 
165 impl Crate {
origin(self, db: &dyn HirDatabase) -> CrateOrigin166     pub fn origin(self, db: &dyn HirDatabase) -> CrateOrigin {
167         db.crate_graph()[self.id].origin.clone()
168     }
169 
is_builtin(self, db: &dyn HirDatabase) -> bool170     pub fn is_builtin(self, db: &dyn HirDatabase) -> bool {
171         matches!(self.origin(db), CrateOrigin::Lang(_))
172     }
173 
dependencies(self, db: &dyn HirDatabase) -> Vec<CrateDependency>174     pub fn dependencies(self, db: &dyn HirDatabase) -> Vec<CrateDependency> {
175         db.crate_graph()[self.id]
176             .dependencies
177             .iter()
178             .map(|dep| {
179                 let krate = Crate { id: dep.crate_id };
180                 let name = dep.as_name();
181                 CrateDependency { krate, name }
182             })
183             .collect()
184     }
185 
reverse_dependencies(self, db: &dyn HirDatabase) -> Vec<Crate>186     pub fn reverse_dependencies(self, db: &dyn HirDatabase) -> Vec<Crate> {
187         let crate_graph = db.crate_graph();
188         crate_graph
189             .iter()
190             .filter(|&krate| {
191                 crate_graph[krate].dependencies.iter().any(|it| it.crate_id == self.id)
192             })
193             .map(|id| Crate { id })
194             .collect()
195     }
196 
transitive_reverse_dependencies( self, db: &dyn HirDatabase, ) -> impl Iterator<Item = Crate>197     pub fn transitive_reverse_dependencies(
198         self,
199         db: &dyn HirDatabase,
200     ) -> impl Iterator<Item = Crate> {
201         db.crate_graph().transitive_rev_deps(self.id).map(|id| Crate { id })
202     }
203 
root_module(self, db: &dyn HirDatabase) -> Module204     pub fn root_module(self, db: &dyn HirDatabase) -> Module {
205         let def_map = db.crate_def_map(self.id);
206         Module { id: def_map.crate_root().into() }
207     }
208 
modules(self, db: &dyn HirDatabase) -> Vec<Module>209     pub fn modules(self, db: &dyn HirDatabase) -> Vec<Module> {
210         let def_map = db.crate_def_map(self.id);
211         def_map.modules().map(|(id, _)| def_map.module_id(id).into()).collect()
212     }
213 
root_file(self, db: &dyn HirDatabase) -> FileId214     pub fn root_file(self, db: &dyn HirDatabase) -> FileId {
215         db.crate_graph()[self.id].root_file_id
216     }
217 
edition(self, db: &dyn HirDatabase) -> Edition218     pub fn edition(self, db: &dyn HirDatabase) -> Edition {
219         db.crate_graph()[self.id].edition
220     }
221 
version(self, db: &dyn HirDatabase) -> Option<String>222     pub fn version(self, db: &dyn HirDatabase) -> Option<String> {
223         db.crate_graph()[self.id].version.clone()
224     }
225 
display_name(self, db: &dyn HirDatabase) -> Option<CrateDisplayName>226     pub fn display_name(self, db: &dyn HirDatabase) -> Option<CrateDisplayName> {
227         db.crate_graph()[self.id].display_name.clone()
228     }
229 
query_external_importables( self, db: &dyn DefDatabase, query: import_map::Query, ) -> impl Iterator<Item = Either<ModuleDef, Macro>>230     pub fn query_external_importables(
231         self,
232         db: &dyn DefDatabase,
233         query: import_map::Query,
234     ) -> impl Iterator<Item = Either<ModuleDef, Macro>> {
235         let _p = profile::span("query_external_importables");
236         import_map::search_dependencies(db, self.into(), query).into_iter().map(|item| {
237             match ItemInNs::from(item) {
238                 ItemInNs::Types(mod_id) | ItemInNs::Values(mod_id) => Either::Left(mod_id),
239                 ItemInNs::Macros(mac_id) => Either::Right(mac_id),
240             }
241         })
242     }
243 
all(db: &dyn HirDatabase) -> Vec<Crate>244     pub fn all(db: &dyn HirDatabase) -> Vec<Crate> {
245         db.crate_graph().iter().map(|id| Crate { id }).collect()
246     }
247 
248     /// Try to get the root URL of the documentation of a crate.
get_html_root_url(self: &Crate, db: &dyn HirDatabase) -> Option<String>249     pub fn get_html_root_url(self: &Crate, db: &dyn HirDatabase) -> Option<String> {
250         // Look for #![doc(html_root_url = "...")]
251         let attrs = db.attrs(AttrDefId::ModuleId(self.root_module(db).into()));
252         let doc_url = attrs.by_key("doc").find_string_value_in_tt("html_root_url");
253         doc_url.map(|s| s.trim_matches('"').trim_end_matches('/').to_owned() + "/")
254     }
255 
cfg(&self, db: &dyn HirDatabase) -> CfgOptions256     pub fn cfg(&self, db: &dyn HirDatabase) -> CfgOptions {
257         db.crate_graph()[self.id].cfg_options.clone()
258     }
259 
potential_cfg(&self, db: &dyn HirDatabase) -> CfgOptions260     pub fn potential_cfg(&self, db: &dyn HirDatabase) -> CfgOptions {
261         let data = &db.crate_graph()[self.id];
262         data.potential_cfg_options.clone().unwrap_or_else(|| data.cfg_options.clone())
263     }
264 }
265 
266 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
267 pub struct Module {
268     pub(crate) id: ModuleId,
269 }
270 
271 /// The defs which can be visible in the module.
272 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
273 pub enum ModuleDef {
274     Module(Module),
275     Function(Function),
276     Adt(Adt),
277     // Can't be directly declared, but can be imported.
278     Variant(Variant),
279     Const(Const),
280     Static(Static),
281     Trait(Trait),
282     TraitAlias(TraitAlias),
283     TypeAlias(TypeAlias),
284     BuiltinType(BuiltinType),
285     Macro(Macro),
286 }
287 impl_from!(
288     Module,
289     Function,
290     Adt(Struct, Enum, Union),
291     Variant,
292     Const,
293     Static,
294     Trait,
295     TraitAlias,
296     TypeAlias,
297     BuiltinType,
298     Macro
299     for ModuleDef
300 );
301 
302 impl From<VariantDef> for ModuleDef {
from(var: VariantDef) -> Self303     fn from(var: VariantDef) -> Self {
304         match var {
305             VariantDef::Struct(t) => Adt::from(t).into(),
306             VariantDef::Union(t) => Adt::from(t).into(),
307             VariantDef::Variant(t) => t.into(),
308         }
309     }
310 }
311 
312 impl ModuleDef {
module(self, db: &dyn HirDatabase) -> Option<Module>313     pub fn module(self, db: &dyn HirDatabase) -> Option<Module> {
314         match self {
315             ModuleDef::Module(it) => it.parent(db),
316             ModuleDef::Function(it) => Some(it.module(db)),
317             ModuleDef::Adt(it) => Some(it.module(db)),
318             ModuleDef::Variant(it) => Some(it.module(db)),
319             ModuleDef::Const(it) => Some(it.module(db)),
320             ModuleDef::Static(it) => Some(it.module(db)),
321             ModuleDef::Trait(it) => Some(it.module(db)),
322             ModuleDef::TraitAlias(it) => Some(it.module(db)),
323             ModuleDef::TypeAlias(it) => Some(it.module(db)),
324             ModuleDef::Macro(it) => Some(it.module(db)),
325             ModuleDef::BuiltinType(_) => None,
326         }
327     }
328 
canonical_path(&self, db: &dyn HirDatabase) -> Option<String>329     pub fn canonical_path(&self, db: &dyn HirDatabase) -> Option<String> {
330         let mut segments = vec![self.name(db)?];
331         for m in self.module(db)?.path_to_root(db) {
332             segments.extend(m.name(db))
333         }
334         segments.reverse();
335         Some(segments.iter().map(|it| it.display(db.upcast())).join("::"))
336     }
337 
canonical_module_path( &self, db: &dyn HirDatabase, ) -> Option<impl Iterator<Item = Module>>338     pub fn canonical_module_path(
339         &self,
340         db: &dyn HirDatabase,
341     ) -> Option<impl Iterator<Item = Module>> {
342         self.module(db).map(|it| it.path_to_root(db).into_iter().rev())
343     }
344 
name(self, db: &dyn HirDatabase) -> Option<Name>345     pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
346         let name = match self {
347             ModuleDef::Module(it) => it.name(db)?,
348             ModuleDef::Const(it) => it.name(db)?,
349             ModuleDef::Adt(it) => it.name(db),
350             ModuleDef::Trait(it) => it.name(db),
351             ModuleDef::TraitAlias(it) => it.name(db),
352             ModuleDef::Function(it) => it.name(db),
353             ModuleDef::Variant(it) => it.name(db),
354             ModuleDef::TypeAlias(it) => it.name(db),
355             ModuleDef::Static(it) => it.name(db),
356             ModuleDef::Macro(it) => it.name(db),
357             ModuleDef::BuiltinType(it) => it.name(),
358         };
359         Some(name)
360     }
361 
diagnostics(self, db: &dyn HirDatabase) -> Vec<AnyDiagnostic>362     pub fn diagnostics(self, db: &dyn HirDatabase) -> Vec<AnyDiagnostic> {
363         let id = match self {
364             ModuleDef::Adt(it) => match it {
365                 Adt::Struct(it) => it.id.into(),
366                 Adt::Enum(it) => it.id.into(),
367                 Adt::Union(it) => it.id.into(),
368             },
369             ModuleDef::Trait(it) => it.id.into(),
370             ModuleDef::TraitAlias(it) => it.id.into(),
371             ModuleDef::Function(it) => it.id.into(),
372             ModuleDef::TypeAlias(it) => it.id.into(),
373             ModuleDef::Module(it) => it.id.into(),
374             ModuleDef::Const(it) => it.id.into(),
375             ModuleDef::Static(it) => it.id.into(),
376             ModuleDef::Variant(it) => {
377                 EnumVariantId { parent: it.parent.into(), local_id: it.id }.into()
378             }
379             ModuleDef::BuiltinType(_) | ModuleDef::Macro(_) => return Vec::new(),
380         };
381 
382         let module = match self.module(db) {
383             Some(it) => it,
384             None => return Vec::new(),
385         };
386 
387         let mut acc = Vec::new();
388 
389         match self.as_def_with_body() {
390             Some(def) => {
391                 def.diagnostics(db, &mut acc);
392             }
393             None => {
394                 for diag in hir_ty::diagnostics::incorrect_case(db, module.id.krate(), id) {
395                     acc.push(diag.into())
396                 }
397             }
398         }
399 
400         acc
401     }
402 
as_def_with_body(self) -> Option<DefWithBody>403     pub fn as_def_with_body(self) -> Option<DefWithBody> {
404         match self {
405             ModuleDef::Function(it) => Some(it.into()),
406             ModuleDef::Const(it) => Some(it.into()),
407             ModuleDef::Static(it) => Some(it.into()),
408             ModuleDef::Variant(it) => Some(it.into()),
409 
410             ModuleDef::Module(_)
411             | ModuleDef::Adt(_)
412             | ModuleDef::Trait(_)
413             | ModuleDef::TraitAlias(_)
414             | ModuleDef::TypeAlias(_)
415             | ModuleDef::Macro(_)
416             | ModuleDef::BuiltinType(_) => None,
417         }
418     }
419 
attrs(&self, db: &dyn HirDatabase) -> Option<AttrsWithOwner>420     pub fn attrs(&self, db: &dyn HirDatabase) -> Option<AttrsWithOwner> {
421         Some(match self {
422             ModuleDef::Module(it) => it.attrs(db),
423             ModuleDef::Function(it) => it.attrs(db),
424             ModuleDef::Adt(it) => it.attrs(db),
425             ModuleDef::Variant(it) => it.attrs(db),
426             ModuleDef::Const(it) => it.attrs(db),
427             ModuleDef::Static(it) => it.attrs(db),
428             ModuleDef::Trait(it) => it.attrs(db),
429             ModuleDef::TraitAlias(it) => it.attrs(db),
430             ModuleDef::TypeAlias(it) => it.attrs(db),
431             ModuleDef::Macro(it) => it.attrs(db),
432             ModuleDef::BuiltinType(_) => return None,
433         })
434     }
435 }
436 
437 impl HasVisibility for ModuleDef {
visibility(&self, db: &dyn HirDatabase) -> Visibility438     fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
439         match *self {
440             ModuleDef::Module(it) => it.visibility(db),
441             ModuleDef::Function(it) => it.visibility(db),
442             ModuleDef::Adt(it) => it.visibility(db),
443             ModuleDef::Const(it) => it.visibility(db),
444             ModuleDef::Static(it) => it.visibility(db),
445             ModuleDef::Trait(it) => it.visibility(db),
446             ModuleDef::TraitAlias(it) => it.visibility(db),
447             ModuleDef::TypeAlias(it) => it.visibility(db),
448             ModuleDef::Variant(it) => it.visibility(db),
449             ModuleDef::Macro(it) => it.visibility(db),
450             ModuleDef::BuiltinType(_) => Visibility::Public,
451         }
452     }
453 }
454 
455 impl Module {
456     /// Name of this module.
name(self, db: &dyn HirDatabase) -> Option<Name>457     pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
458         let def_map = self.id.def_map(db.upcast());
459         let parent = def_map[self.id.local_id].parent?;
460         def_map[parent].children.iter().find_map(|(name, module_id)| {
461             if *module_id == self.id.local_id {
462                 Some(name.clone())
463             } else {
464                 None
465             }
466         })
467     }
468 
469     /// Returns the crate this module is part of.
krate(self) -> Crate470     pub fn krate(self) -> Crate {
471         Crate { id: self.id.krate() }
472     }
473 
474     /// Topmost parent of this module. Every module has a `crate_root`, but some
475     /// might be missing `krate`. This can happen if a module's file is not included
476     /// in the module tree of any target in `Cargo.toml`.
crate_root(self, db: &dyn HirDatabase) -> Module477     pub fn crate_root(self, db: &dyn HirDatabase) -> Module {
478         let def_map = db.crate_def_map(self.id.krate());
479         Module { id: def_map.crate_root().into() }
480     }
481 
is_crate_root(self) -> bool482     pub fn is_crate_root(self) -> bool {
483         DefMap::ROOT == self.id.local_id
484     }
485 
486     /// Iterates over all child modules.
children(self, db: &dyn HirDatabase) -> impl Iterator<Item = Module>487     pub fn children(self, db: &dyn HirDatabase) -> impl Iterator<Item = Module> {
488         let def_map = self.id.def_map(db.upcast());
489         let children = def_map[self.id.local_id]
490             .children
491             .values()
492             .map(|module_id| Module { id: def_map.module_id(*module_id) })
493             .collect::<Vec<_>>();
494         children.into_iter()
495     }
496 
497     /// Finds a parent module.
parent(self, db: &dyn HirDatabase) -> Option<Module>498     pub fn parent(self, db: &dyn HirDatabase) -> Option<Module> {
499         // FIXME: handle block expressions as modules (their parent is in a different DefMap)
500         let def_map = self.id.def_map(db.upcast());
501         let parent_id = def_map[self.id.local_id].parent?;
502         Some(Module { id: def_map.module_id(parent_id) })
503     }
504 
505     /// Finds nearest non-block ancestor `Module` (`self` included).
nearest_non_block_module(self, db: &dyn HirDatabase) -> Module506     pub fn nearest_non_block_module(self, db: &dyn HirDatabase) -> Module {
507         let mut id = self.id;
508         loop {
509             let def_map = id.def_map(db.upcast());
510             let origin = def_map[id.local_id].origin;
511             if matches!(origin, ModuleOrigin::BlockExpr { .. }) {
512                 id = id.containing_module(db.upcast()).expect("block without parent module")
513             } else {
514                 return Module { id };
515             }
516         }
517     }
518 
path_to_root(self, db: &dyn HirDatabase) -> Vec<Module>519     pub fn path_to_root(self, db: &dyn HirDatabase) -> Vec<Module> {
520         let mut res = vec![self];
521         let mut curr = self;
522         while let Some(next) = curr.parent(db) {
523             res.push(next);
524             curr = next
525         }
526         res
527     }
528 
529     /// Returns a `ModuleScope`: a set of items, visible in this module.
scope( self, db: &dyn HirDatabase, visible_from: Option<Module>, ) -> Vec<(Name, ScopeDef)>530     pub fn scope(
531         self,
532         db: &dyn HirDatabase,
533         visible_from: Option<Module>,
534     ) -> Vec<(Name, ScopeDef)> {
535         self.id.def_map(db.upcast())[self.id.local_id]
536             .scope
537             .entries()
538             .filter_map(|(name, def)| {
539                 if let Some(m) = visible_from {
540                     let filtered =
541                         def.filter_visibility(|vis| vis.is_visible_from(db.upcast(), m.id));
542                     if filtered.is_none() && !def.is_none() {
543                         None
544                     } else {
545                         Some((name, filtered))
546                     }
547                 } else {
548                     Some((name, def))
549                 }
550             })
551             .flat_map(|(name, def)| {
552                 ScopeDef::all_items(def).into_iter().map(move |item| (name.clone(), item))
553             })
554             .collect()
555     }
556 
557     /// Fills `acc` with the module's diagnostics.
diagnostics(self, db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>)558     pub fn diagnostics(self, db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>) {
559         let _p = profile::span("Module::diagnostics").detail(|| {
560             format!(
561                 "{:?}",
562                 self.name(db)
563                     .map_or("<unknown>".into(), |name| name.display(db.upcast()).to_string())
564             )
565         });
566         let def_map = self.id.def_map(db.upcast());
567         for diag in def_map.diagnostics() {
568             if diag.in_module != self.id.local_id {
569                 // FIXME: This is accidentally quadratic.
570                 continue;
571             }
572             emit_def_diagnostic(db, acc, diag);
573         }
574 
575         for decl in self.declarations(db) {
576             match decl {
577                 ModuleDef::Module(m) => {
578                     // Only add diagnostics from inline modules
579                     if def_map[m.id.local_id].origin.is_inline() {
580                         m.diagnostics(db, acc)
581                     }
582                 }
583                 ModuleDef::Trait(t) => {
584                     for diag in db.trait_data_with_diagnostics(t.id).1.iter() {
585                         emit_def_diagnostic(db, acc, diag);
586                     }
587                     acc.extend(decl.diagnostics(db))
588                 }
589                 ModuleDef::Adt(adt) => {
590                     match adt {
591                         Adt::Struct(s) => {
592                             for diag in db.struct_data_with_diagnostics(s.id).1.iter() {
593                                 emit_def_diagnostic(db, acc, diag);
594                             }
595                         }
596                         Adt::Union(u) => {
597                             for diag in db.union_data_with_diagnostics(u.id).1.iter() {
598                                 emit_def_diagnostic(db, acc, diag);
599                             }
600                         }
601                         Adt::Enum(e) => {
602                             for v in e.variants(db) {
603                                 acc.extend(ModuleDef::Variant(v).diagnostics(db));
604                             }
605 
606                             for diag in db.enum_data_with_diagnostics(e.id).1.iter() {
607                                 emit_def_diagnostic(db, acc, diag);
608                             }
609                         }
610                     }
611                     acc.extend(decl.diagnostics(db))
612                 }
613                 ModuleDef::Macro(m) => emit_macro_def_diagnostics(db, acc, m),
614                 _ => acc.extend(decl.diagnostics(db)),
615             }
616         }
617         self.legacy_macros(db).into_iter().for_each(|m| emit_macro_def_diagnostics(db, acc, m));
618 
619         let inherent_impls = db.inherent_impls_in_crate(self.id.krate());
620 
621         for impl_def in self.impl_defs(db) {
622             for diag in db.impl_data_with_diagnostics(impl_def.id).1.iter() {
623                 emit_def_diagnostic(db, acc, diag);
624             }
625 
626             if inherent_impls.invalid_impls().contains(&impl_def.id) {
627                 let loc = impl_def.id.lookup(db.upcast());
628                 let tree = loc.id.item_tree(db.upcast());
629                 let node = &tree[loc.id.value];
630                 let file_id = loc.id.file_id();
631                 let ast_id_map = db.ast_id_map(file_id);
632 
633                 acc.push(IncoherentImpl { impl_: ast_id_map.get(node.ast_id()), file_id }.into())
634             }
635 
636             for item in impl_def.items(db) {
637                 let def: DefWithBody = match item {
638                     AssocItem::Function(it) => it.into(),
639                     AssocItem::Const(it) => it.into(),
640                     AssocItem::TypeAlias(_) => continue,
641                 };
642 
643                 def.diagnostics(db, acc);
644             }
645         }
646     }
647 
declarations(self, db: &dyn HirDatabase) -> Vec<ModuleDef>648     pub fn declarations(self, db: &dyn HirDatabase) -> Vec<ModuleDef> {
649         let def_map = self.id.def_map(db.upcast());
650         let scope = &def_map[self.id.local_id].scope;
651         scope
652             .declarations()
653             .map(ModuleDef::from)
654             .chain(scope.unnamed_consts().map(|id| ModuleDef::Const(Const::from(id))))
655             .collect()
656     }
657 
legacy_macros(self, db: &dyn HirDatabase) -> Vec<Macro>658     pub fn legacy_macros(self, db: &dyn HirDatabase) -> Vec<Macro> {
659         let def_map = self.id.def_map(db.upcast());
660         let scope = &def_map[self.id.local_id].scope;
661         scope.legacy_macros().flat_map(|(_, it)| it).map(|&it| it.into()).collect()
662     }
663 
impl_defs(self, db: &dyn HirDatabase) -> Vec<Impl>664     pub fn impl_defs(self, db: &dyn HirDatabase) -> Vec<Impl> {
665         let def_map = self.id.def_map(db.upcast());
666         def_map[self.id.local_id].scope.impls().map(Impl::from).collect()
667     }
668 
669     /// Finds a path that can be used to refer to the given item from within
670     /// this module, if possible.
find_use_path( self, db: &dyn DefDatabase, item: impl Into<ItemInNs>, prefer_no_std: bool, ) -> Option<ModPath>671     pub fn find_use_path(
672         self,
673         db: &dyn DefDatabase,
674         item: impl Into<ItemInNs>,
675         prefer_no_std: bool,
676     ) -> Option<ModPath> {
677         hir_def::find_path::find_path(db, item.into().into(), self.into(), prefer_no_std)
678     }
679 
680     /// Finds a path that can be used to refer to the given item from within
681     /// this module, if possible. This is used for returning import paths for use-statements.
find_use_path_prefixed( self, db: &dyn DefDatabase, item: impl Into<ItemInNs>, prefix_kind: PrefixKind, prefer_no_std: bool, ) -> Option<ModPath>682     pub fn find_use_path_prefixed(
683         self,
684         db: &dyn DefDatabase,
685         item: impl Into<ItemInNs>,
686         prefix_kind: PrefixKind,
687         prefer_no_std: bool,
688     ) -> Option<ModPath> {
689         hir_def::find_path::find_path_prefixed(
690             db,
691             item.into().into(),
692             self.into(),
693             prefix_kind,
694             prefer_no_std,
695         )
696     }
697 }
698 
emit_macro_def_diagnostics(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, m: Macro)699 fn emit_macro_def_diagnostics(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, m: Macro) {
700     let id = macro_id_to_def_id(db.upcast(), m.id);
701     if let Err(e) = db.macro_def(id) {
702         let Some(ast) = id.ast_id().left() else {
703                 never!("MacroDefError for proc-macro: {:?}", e);
704                 return;
705             };
706         emit_def_diagnostic_(
707             db,
708             acc,
709             &DefDiagnosticKind::MacroDefError { ast, message: e.to_string() },
710         );
711     }
712 }
713 
emit_def_diagnostic(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, diag: &DefDiagnostic)714 fn emit_def_diagnostic(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, diag: &DefDiagnostic) {
715     emit_def_diagnostic_(db, acc, &diag.kind)
716 }
717 
emit_def_diagnostic_( db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, diag: &DefDiagnosticKind, )718 fn emit_def_diagnostic_(
719     db: &dyn HirDatabase,
720     acc: &mut Vec<AnyDiagnostic>,
721     diag: &DefDiagnosticKind,
722 ) {
723     match diag {
724         DefDiagnosticKind::UnresolvedModule { ast: declaration, candidates } => {
725             let decl = declaration.to_node(db.upcast());
726             acc.push(
727                 UnresolvedModule {
728                     decl: InFile::new(declaration.file_id, AstPtr::new(&decl)),
729                     candidates: candidates.clone(),
730                 }
731                 .into(),
732             )
733         }
734         DefDiagnosticKind::UnresolvedExternCrate { ast } => {
735             let item = ast.to_node(db.upcast());
736             acc.push(
737                 UnresolvedExternCrate { decl: InFile::new(ast.file_id, AstPtr::new(&item)) }.into(),
738             );
739         }
740 
741         DefDiagnosticKind::UnresolvedImport { id, index } => {
742             let file_id = id.file_id();
743             let item_tree = id.item_tree(db.upcast());
744             let import = &item_tree[id.value];
745 
746             let use_tree = import.use_tree_to_ast(db.upcast(), file_id, *index);
747             acc.push(
748                 UnresolvedImport { decl: InFile::new(file_id, AstPtr::new(&use_tree)) }.into(),
749             );
750         }
751 
752         DefDiagnosticKind::UnconfiguredCode { ast, cfg, opts } => {
753             let item = ast.to_node(db.upcast());
754             acc.push(
755                 InactiveCode {
756                     node: ast.with_value(AstPtr::new(&item).into()),
757                     cfg: cfg.clone(),
758                     opts: opts.clone(),
759                 }
760                 .into(),
761             );
762         }
763         DefDiagnosticKind::UnresolvedProcMacro { ast, krate } => {
764             let (node, precise_location, macro_name, kind) = precise_macro_call_location(ast, db);
765             acc.push(
766                 UnresolvedProcMacro { node, precise_location, macro_name, kind, krate: *krate }
767                     .into(),
768             );
769         }
770         DefDiagnosticKind::UnresolvedMacroCall { ast, path } => {
771             let (node, precise_location, _, _) = precise_macro_call_location(ast, db);
772             acc.push(
773                 UnresolvedMacroCall {
774                     macro_call: node,
775                     precise_location,
776                     path: path.clone(),
777                     is_bang: matches!(ast, MacroCallKind::FnLike { .. }),
778                 }
779                 .into(),
780             );
781         }
782         DefDiagnosticKind::MacroError { ast, message } => {
783             let (node, precise_location, _, _) = precise_macro_call_location(ast, db);
784             acc.push(MacroError { node, precise_location, message: message.clone() }.into());
785         }
786         DefDiagnosticKind::MacroExpansionParseError { ast, errors } => {
787             let (node, precise_location, _, _) = precise_macro_call_location(ast, db);
788             acc.push(
789                 MacroExpansionParseError { node, precise_location, errors: errors.clone() }.into(),
790             );
791         }
792         DefDiagnosticKind::UnimplementedBuiltinMacro { ast } => {
793             let node = ast.to_node(db.upcast());
794             // Must have a name, otherwise we wouldn't emit it.
795             let name = node.name().expect("unimplemented builtin macro with no name");
796             acc.push(
797                 UnimplementedBuiltinMacro {
798                     node: ast.with_value(SyntaxNodePtr::from(AstPtr::new(&name))),
799                 }
800                 .into(),
801             );
802         }
803         DefDiagnosticKind::InvalidDeriveTarget { ast, id } => {
804             let node = ast.to_node(db.upcast());
805             let derive = node.attrs().nth(*id as usize);
806             match derive {
807                 Some(derive) => {
808                     acc.push(
809                         InvalidDeriveTarget {
810                             node: ast.with_value(SyntaxNodePtr::from(AstPtr::new(&derive))),
811                         }
812                         .into(),
813                     );
814                 }
815                 None => stdx::never!("derive diagnostic on item without derive attribute"),
816             }
817         }
818         DefDiagnosticKind::MalformedDerive { ast, id } => {
819             let node = ast.to_node(db.upcast());
820             let derive = node.attrs().nth(*id as usize);
821             match derive {
822                 Some(derive) => {
823                     acc.push(
824                         MalformedDerive {
825                             node: ast.with_value(SyntaxNodePtr::from(AstPtr::new(&derive))),
826                         }
827                         .into(),
828                     );
829                 }
830                 None => stdx::never!("derive diagnostic on item without derive attribute"),
831             }
832         }
833         DefDiagnosticKind::MacroDefError { ast, message } => {
834             let node = ast.to_node(db.upcast());
835             acc.push(
836                 MacroDefError {
837                     node: InFile::new(ast.file_id, AstPtr::new(&node)),
838                     name: node.name().map(|it| it.syntax().text_range()),
839                     message: message.clone(),
840                 }
841                 .into(),
842             );
843         }
844     }
845 }
846 
precise_macro_call_location( ast: &MacroCallKind, db: &dyn HirDatabase, ) -> (InFile<SyntaxNodePtr>, Option<TextRange>, Option<String>, MacroKind)847 fn precise_macro_call_location(
848     ast: &MacroCallKind,
849     db: &dyn HirDatabase,
850 ) -> (InFile<SyntaxNodePtr>, Option<TextRange>, Option<String>, MacroKind) {
851     // FIXME: maybe we actually want slightly different ranges for the different macro diagnostics
852     // - e.g. the full attribute for macro errors, but only the name for name resolution
853     match ast {
854         MacroCallKind::FnLike { ast_id, .. } => {
855             let node = ast_id.to_node(db.upcast());
856             (
857                 ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node))),
858                 node.path()
859                     .and_then(|it| it.segment())
860                     .and_then(|it| it.name_ref())
861                     .map(|it| it.syntax().text_range()),
862                 node.path().and_then(|it| it.segment()).map(|it| it.to_string()),
863                 MacroKind::ProcMacro,
864             )
865         }
866         MacroCallKind::Derive { ast_id, derive_attr_index, derive_index } => {
867             let node = ast_id.to_node(db.upcast());
868             // Compute the precise location of the macro name's token in the derive
869             // list.
870             let token = (|| {
871                 let derive_attr = node
872                     .doc_comments_and_attrs()
873                     .nth(derive_attr_index.ast_index())
874                     .and_then(Either::left)?;
875                 let token_tree = derive_attr.meta()?.token_tree()?;
876                 let group_by = token_tree
877                     .syntax()
878                     .children_with_tokens()
879                     .filter_map(|elem| match elem {
880                         syntax::NodeOrToken::Token(tok) => Some(tok),
881                         _ => None,
882                     })
883                     .group_by(|t| t.kind() == T![,]);
884                 let (_, mut group) = group_by
885                     .into_iter()
886                     .filter(|&(comma, _)| !comma)
887                     .nth(*derive_index as usize)?;
888                 group.find(|t| t.kind() == T![ident])
889             })();
890             (
891                 ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node))),
892                 token.as_ref().map(|tok| tok.text_range()),
893                 token.as_ref().map(ToString::to_string),
894                 MacroKind::Derive,
895             )
896         }
897         MacroCallKind::Attr { ast_id, invoc_attr_index, .. } => {
898             let node = ast_id.to_node(db.upcast());
899             let attr = node
900                 .doc_comments_and_attrs()
901                 .nth(invoc_attr_index.ast_index())
902                 .and_then(Either::left)
903                 .unwrap_or_else(|| {
904                     panic!("cannot find attribute #{}", invoc_attr_index.ast_index())
905                 });
906 
907             (
908                 ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&attr))),
909                 Some(attr.syntax().text_range()),
910                 attr.path()
911                     .and_then(|path| path.segment())
912                     .and_then(|seg| seg.name_ref())
913                     .as_ref()
914                     .map(ToString::to_string),
915                 MacroKind::Attr,
916             )
917         }
918     }
919 }
920 
921 impl HasVisibility for Module {
visibility(&self, db: &dyn HirDatabase) -> Visibility922     fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
923         let def_map = self.id.def_map(db.upcast());
924         let module_data = &def_map[self.id.local_id];
925         module_data.visibility
926     }
927 }
928 
929 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
930 pub struct Field {
931     pub(crate) parent: VariantDef,
932     pub(crate) id: LocalFieldId,
933 }
934 
935 #[derive(Debug, PartialEq, Eq)]
936 pub enum FieldSource {
937     Named(ast::RecordField),
938     Pos(ast::TupleField),
939 }
940 
941 impl Field {
name(&self, db: &dyn HirDatabase) -> Name942     pub fn name(&self, db: &dyn HirDatabase) -> Name {
943         self.parent.variant_data(db).fields()[self.id].name.clone()
944     }
945 
index(&self) -> usize946     pub fn index(&self) -> usize {
947         u32::from(self.id.into_raw()) as usize
948     }
949 
950     /// Returns the type as in the signature of the struct (i.e., with
951     /// placeholder types for type parameters). Only use this in the context of
952     /// the field definition.
ty(&self, db: &dyn HirDatabase) -> Type953     pub fn ty(&self, db: &dyn HirDatabase) -> Type {
954         let var_id = self.parent.into();
955         let generic_def_id: GenericDefId = match self.parent {
956             VariantDef::Struct(it) => it.id.into(),
957             VariantDef::Union(it) => it.id.into(),
958             VariantDef::Variant(it) => it.parent.id.into(),
959         };
960         let substs = TyBuilder::placeholder_subst(db, generic_def_id);
961         let ty = db.field_types(var_id)[self.id].clone().substitute(Interner, &substs);
962         Type::new(db, var_id, ty)
963     }
964 
layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError>965     pub fn layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
966         db.layout_of_ty(self.ty(db).ty.clone(), self.parent.module(db).krate().into())
967             .map(|layout| Layout(layout, db.target_data_layout(self.krate(db).into()).unwrap()))
968     }
969 
parent_def(&self, _db: &dyn HirDatabase) -> VariantDef970     pub fn parent_def(&self, _db: &dyn HirDatabase) -> VariantDef {
971         self.parent
972     }
973 }
974 
975 impl HasVisibility for Field {
visibility(&self, db: &dyn HirDatabase) -> Visibility976     fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
977         let variant_data = self.parent.variant_data(db);
978         let visibility = &variant_data.fields()[self.id].visibility;
979         let parent_id: hir_def::VariantId = self.parent.into();
980         visibility.resolve(db.upcast(), &parent_id.resolver(db.upcast()))
981     }
982 }
983 
984 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
985 pub struct Struct {
986     pub(crate) id: StructId,
987 }
988 
989 impl Struct {
module(self, db: &dyn HirDatabase) -> Module990     pub fn module(self, db: &dyn HirDatabase) -> Module {
991         Module { id: self.id.lookup(db.upcast()).container }
992     }
993 
name(self, db: &dyn HirDatabase) -> Name994     pub fn name(self, db: &dyn HirDatabase) -> Name {
995         db.struct_data(self.id).name.clone()
996     }
997 
fields(self, db: &dyn HirDatabase) -> Vec<Field>998     pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
999         db.struct_data(self.id)
1000             .variant_data
1001             .fields()
1002             .iter()
1003             .map(|(id, _)| Field { parent: self.into(), id })
1004             .collect()
1005     }
1006 
ty(self, db: &dyn HirDatabase) -> Type1007     pub fn ty(self, db: &dyn HirDatabase) -> Type {
1008         Type::from_def(db, self.id)
1009     }
1010 
constructor_ty(self, db: &dyn HirDatabase) -> Type1011     pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type {
1012         Type::from_value_def(db, self.id)
1013     }
1014 
repr(self, db: &dyn HirDatabase) -> Option<ReprOptions>1015     pub fn repr(self, db: &dyn HirDatabase) -> Option<ReprOptions> {
1016         db.struct_data(self.id).repr
1017     }
1018 
kind(self, db: &dyn HirDatabase) -> StructKind1019     pub fn kind(self, db: &dyn HirDatabase) -> StructKind {
1020         self.variant_data(db).kind()
1021     }
1022 
variant_data(self, db: &dyn HirDatabase) -> Arc<VariantData>1023     fn variant_data(self, db: &dyn HirDatabase) -> Arc<VariantData> {
1024         db.struct_data(self.id).variant_data.clone()
1025     }
1026 }
1027 
1028 impl HasVisibility for Struct {
visibility(&self, db: &dyn HirDatabase) -> Visibility1029     fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
1030         db.struct_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
1031     }
1032 }
1033 
1034 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1035 pub struct Union {
1036     pub(crate) id: UnionId,
1037 }
1038 
1039 impl Union {
name(self, db: &dyn HirDatabase) -> Name1040     pub fn name(self, db: &dyn HirDatabase) -> Name {
1041         db.union_data(self.id).name.clone()
1042     }
1043 
module(self, db: &dyn HirDatabase) -> Module1044     pub fn module(self, db: &dyn HirDatabase) -> Module {
1045         Module { id: self.id.lookup(db.upcast()).container }
1046     }
1047 
ty(self, db: &dyn HirDatabase) -> Type1048     pub fn ty(self, db: &dyn HirDatabase) -> Type {
1049         Type::from_def(db, self.id)
1050     }
1051 
constructor_ty(self, db: &dyn HirDatabase) -> Type1052     pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type {
1053         Type::from_value_def(db, self.id)
1054     }
1055 
fields(self, db: &dyn HirDatabase) -> Vec<Field>1056     pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
1057         db.union_data(self.id)
1058             .variant_data
1059             .fields()
1060             .iter()
1061             .map(|(id, _)| Field { parent: self.into(), id })
1062             .collect()
1063     }
1064 
variant_data(self, db: &dyn HirDatabase) -> Arc<VariantData>1065     fn variant_data(self, db: &dyn HirDatabase) -> Arc<VariantData> {
1066         db.union_data(self.id).variant_data.clone()
1067     }
1068 }
1069 
1070 impl HasVisibility for Union {
visibility(&self, db: &dyn HirDatabase) -> Visibility1071     fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
1072         db.union_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
1073     }
1074 }
1075 
1076 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1077 pub struct Enum {
1078     pub(crate) id: EnumId,
1079 }
1080 
1081 impl Enum {
module(self, db: &dyn HirDatabase) -> Module1082     pub fn module(self, db: &dyn HirDatabase) -> Module {
1083         Module { id: self.id.lookup(db.upcast()).container }
1084     }
1085 
name(self, db: &dyn HirDatabase) -> Name1086     pub fn name(self, db: &dyn HirDatabase) -> Name {
1087         db.enum_data(self.id).name.clone()
1088     }
1089 
variants(self, db: &dyn HirDatabase) -> Vec<Variant>1090     pub fn variants(self, db: &dyn HirDatabase) -> Vec<Variant> {
1091         db.enum_data(self.id).variants.iter().map(|(id, _)| Variant { parent: self, id }).collect()
1092     }
1093 
repr(self, db: &dyn HirDatabase) -> Option<ReprOptions>1094     pub fn repr(self, db: &dyn HirDatabase) -> Option<ReprOptions> {
1095         db.enum_data(self.id).repr
1096     }
1097 
ty(self, db: &dyn HirDatabase) -> Type1098     pub fn ty(self, db: &dyn HirDatabase) -> Type {
1099         Type::from_def(db, self.id)
1100     }
1101 
1102     /// The type of the enum variant bodies.
variant_body_ty(self, db: &dyn HirDatabase) -> Type1103     pub fn variant_body_ty(self, db: &dyn HirDatabase) -> Type {
1104         Type::new_for_crate(
1105             self.id.lookup(db.upcast()).container.krate(),
1106             TyBuilder::builtin(match db.enum_data(self.id).variant_body_type() {
1107                 layout::IntegerType::Pointer(sign) => match sign {
1108                     true => hir_def::builtin_type::BuiltinType::Int(
1109                         hir_def::builtin_type::BuiltinInt::Isize,
1110                     ),
1111                     false => hir_def::builtin_type::BuiltinType::Uint(
1112                         hir_def::builtin_type::BuiltinUint::Usize,
1113                     ),
1114                 },
1115                 layout::IntegerType::Fixed(i, sign) => match sign {
1116                     true => hir_def::builtin_type::BuiltinType::Int(match i {
1117                         layout::Integer::I8 => hir_def::builtin_type::BuiltinInt::I8,
1118                         layout::Integer::I16 => hir_def::builtin_type::BuiltinInt::I16,
1119                         layout::Integer::I32 => hir_def::builtin_type::BuiltinInt::I32,
1120                         layout::Integer::I64 => hir_def::builtin_type::BuiltinInt::I64,
1121                         layout::Integer::I128 => hir_def::builtin_type::BuiltinInt::I128,
1122                     }),
1123                     false => hir_def::builtin_type::BuiltinType::Uint(match i {
1124                         layout::Integer::I8 => hir_def::builtin_type::BuiltinUint::U8,
1125                         layout::Integer::I16 => hir_def::builtin_type::BuiltinUint::U16,
1126                         layout::Integer::I32 => hir_def::builtin_type::BuiltinUint::U32,
1127                         layout::Integer::I64 => hir_def::builtin_type::BuiltinUint::U64,
1128                         layout::Integer::I128 => hir_def::builtin_type::BuiltinUint::U128,
1129                     }),
1130                 },
1131             }),
1132         )
1133     }
1134 
1135     /// Returns true if at least one variant of this enum is a non-unit variant.
is_data_carrying(self, db: &dyn HirDatabase) -> bool1136     pub fn is_data_carrying(self, db: &dyn HirDatabase) -> bool {
1137         self.variants(db).iter().any(|v| !matches!(v.kind(db), StructKind::Unit))
1138     }
1139 
layout(self, db: &dyn HirDatabase) -> Result<Layout, LayoutError>1140     pub fn layout(self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
1141         Adt::from(self).layout(db)
1142     }
1143 }
1144 
1145 impl HasVisibility for Enum {
visibility(&self, db: &dyn HirDatabase) -> Visibility1146     fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
1147         db.enum_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
1148     }
1149 }
1150 
1151 impl From<&Variant> for DefWithBodyId {
from(&v: &Variant) -> Self1152     fn from(&v: &Variant) -> Self {
1153         DefWithBodyId::VariantId(v.into())
1154     }
1155 }
1156 
1157 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1158 pub struct Variant {
1159     pub(crate) parent: Enum,
1160     pub(crate) id: LocalEnumVariantId,
1161 }
1162 
1163 impl Variant {
module(self, db: &dyn HirDatabase) -> Module1164     pub fn module(self, db: &dyn HirDatabase) -> Module {
1165         self.parent.module(db)
1166     }
1167 
parent_enum(self, _db: &dyn HirDatabase) -> Enum1168     pub fn parent_enum(self, _db: &dyn HirDatabase) -> Enum {
1169         self.parent
1170     }
1171 
constructor_ty(self, db: &dyn HirDatabase) -> Type1172     pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type {
1173         Type::from_value_def(db, EnumVariantId { parent: self.parent.id, local_id: self.id })
1174     }
1175 
name(self, db: &dyn HirDatabase) -> Name1176     pub fn name(self, db: &dyn HirDatabase) -> Name {
1177         db.enum_data(self.parent.id).variants[self.id].name.clone()
1178     }
1179 
fields(self, db: &dyn HirDatabase) -> Vec<Field>1180     pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
1181         self.variant_data(db)
1182             .fields()
1183             .iter()
1184             .map(|(id, _)| Field { parent: self.into(), id })
1185             .collect()
1186     }
1187 
kind(self, db: &dyn HirDatabase) -> StructKind1188     pub fn kind(self, db: &dyn HirDatabase) -> StructKind {
1189         self.variant_data(db).kind()
1190     }
1191 
variant_data(self, db: &dyn HirDatabase) -> Arc<VariantData>1192     pub(crate) fn variant_data(self, db: &dyn HirDatabase) -> Arc<VariantData> {
1193         db.enum_data(self.parent.id).variants[self.id].variant_data.clone()
1194     }
1195 
value(self, db: &dyn HirDatabase) -> Option<ast::Expr>1196     pub fn value(self, db: &dyn HirDatabase) -> Option<ast::Expr> {
1197         self.source(db)?.value.expr()
1198     }
1199 
eval(self, db: &dyn HirDatabase) -> Result<i128, ConstEvalError>1200     pub fn eval(self, db: &dyn HirDatabase) -> Result<i128, ConstEvalError> {
1201         db.const_eval_discriminant(self.into())
1202     }
1203 
layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError>1204     pub fn layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
1205         let parent_enum = self.parent_enum(db);
1206         let parent_layout = parent_enum.layout(db)?;
1207         Ok(match &parent_layout.0.variants {
1208             layout::Variants::Multiple { variants, .. } => Layout(
1209                 Arc::new(variants[RustcEnumVariantIdx(self.id)].clone()),
1210                 db.target_data_layout(parent_enum.krate(db).into()).unwrap(),
1211             ),
1212             _ => parent_layout,
1213         })
1214     }
1215 }
1216 
1217 /// Variants inherit visibility from the parent enum.
1218 impl HasVisibility for Variant {
visibility(&self, db: &dyn HirDatabase) -> Visibility1219     fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
1220         self.parent_enum(db).visibility(db)
1221     }
1222 }
1223 
1224 /// A Data Type
1225 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1226 pub enum Adt {
1227     Struct(Struct),
1228     Union(Union),
1229     Enum(Enum),
1230 }
1231 impl_from!(Struct, Union, Enum for Adt);
1232 
1233 impl Adt {
has_non_default_type_params(self, db: &dyn HirDatabase) -> bool1234     pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
1235         let subst = db.generic_defaults(self.into());
1236         subst.iter().any(|ty| match ty.skip_binders().data(Interner) {
1237             GenericArgData::Ty(x) => x.is_unknown(),
1238             _ => false,
1239         })
1240     }
1241 
layout(self, db: &dyn HirDatabase) -> Result<Layout, LayoutError>1242     pub fn layout(self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
1243         if db.generic_params(self.into()).iter().count() != 0 {
1244             return Err(LayoutError::HasPlaceholder);
1245         }
1246         let krate = self.krate(db).id;
1247         db.layout_of_adt(self.into(), Substitution::empty(Interner), krate)
1248             .map(|layout| Layout(layout, db.target_data_layout(krate).unwrap()))
1249     }
1250 
1251     /// Turns this ADT into a type. Any type parameters of the ADT will be
1252     /// turned into unknown types, which is good for e.g. finding the most
1253     /// general set of completions, but will not look very nice when printed.
ty(self, db: &dyn HirDatabase) -> Type1254     pub fn ty(self, db: &dyn HirDatabase) -> Type {
1255         let id = AdtId::from(self);
1256         Type::from_def(db, id)
1257     }
1258 
1259     /// Turns this ADT into a type with the given type parameters. This isn't
1260     /// the greatest API, FIXME find a better one.
ty_with_args(self, db: &dyn HirDatabase, args: &[Type]) -> Type1261     pub fn ty_with_args(self, db: &dyn HirDatabase, args: &[Type]) -> Type {
1262         let id = AdtId::from(self);
1263         let mut it = args.iter().map(|t| t.ty.clone());
1264         let ty = TyBuilder::def_ty(db, id.into(), None)
1265             .fill(|x| {
1266                 let r = it.next().unwrap_or_else(|| TyKind::Error.intern(Interner));
1267                 match x {
1268                     ParamKind::Type => GenericArgData::Ty(r).intern(Interner),
1269                     ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
1270                 }
1271             })
1272             .build();
1273         Type::new(db, id, ty)
1274     }
1275 
module(self, db: &dyn HirDatabase) -> Module1276     pub fn module(self, db: &dyn HirDatabase) -> Module {
1277         match self {
1278             Adt::Struct(s) => s.module(db),
1279             Adt::Union(s) => s.module(db),
1280             Adt::Enum(e) => e.module(db),
1281         }
1282     }
1283 
name(self, db: &dyn HirDatabase) -> Name1284     pub fn name(self, db: &dyn HirDatabase) -> Name {
1285         match self {
1286             Adt::Struct(s) => s.name(db),
1287             Adt::Union(u) => u.name(db),
1288             Adt::Enum(e) => e.name(db),
1289         }
1290     }
1291 
1292     /// Returns the lifetime of the DataType
lifetime(&self, db: &dyn HirDatabase) -> Option<LifetimeParamData>1293     pub fn lifetime(&self, db: &dyn HirDatabase) -> Option<LifetimeParamData> {
1294         let resolver = match self {
1295             Adt::Struct(s) => s.id.resolver(db.upcast()),
1296             Adt::Union(u) => u.id.resolver(db.upcast()),
1297             Adt::Enum(e) => e.id.resolver(db.upcast()),
1298         };
1299         resolver
1300             .generic_params()
1301             .and_then(|gp| {
1302                 (&gp.lifetimes)
1303                     .iter()
1304                     // there should only be a single lifetime
1305                     // but `Arena` requires to use an iterator
1306                     .nth(0)
1307             })
1308             .map(|arena| arena.1.clone())
1309     }
1310 
as_enum(&self) -> Option<Enum>1311     pub fn as_enum(&self) -> Option<Enum> {
1312         if let Self::Enum(v) = self {
1313             Some(*v)
1314         } else {
1315             None
1316         }
1317     }
1318 }
1319 
1320 impl HasVisibility for Adt {
visibility(&self, db: &dyn HirDatabase) -> Visibility1321     fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
1322         match self {
1323             Adt::Struct(it) => it.visibility(db),
1324             Adt::Union(it) => it.visibility(db),
1325             Adt::Enum(it) => it.visibility(db),
1326         }
1327     }
1328 }
1329 
1330 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1331 pub enum VariantDef {
1332     Struct(Struct),
1333     Union(Union),
1334     Variant(Variant),
1335 }
1336 impl_from!(Struct, Union, Variant for VariantDef);
1337 
1338 impl VariantDef {
fields(self, db: &dyn HirDatabase) -> Vec<Field>1339     pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
1340         match self {
1341             VariantDef::Struct(it) => it.fields(db),
1342             VariantDef::Union(it) => it.fields(db),
1343             VariantDef::Variant(it) => it.fields(db),
1344         }
1345     }
1346 
module(self, db: &dyn HirDatabase) -> Module1347     pub fn module(self, db: &dyn HirDatabase) -> Module {
1348         match self {
1349             VariantDef::Struct(it) => it.module(db),
1350             VariantDef::Union(it) => it.module(db),
1351             VariantDef::Variant(it) => it.module(db),
1352         }
1353     }
1354 
name(&self, db: &dyn HirDatabase) -> Name1355     pub fn name(&self, db: &dyn HirDatabase) -> Name {
1356         match self {
1357             VariantDef::Struct(s) => s.name(db),
1358             VariantDef::Union(u) => u.name(db),
1359             VariantDef::Variant(e) => e.name(db),
1360         }
1361     }
1362 
variant_data(self, db: &dyn HirDatabase) -> Arc<VariantData>1363     pub(crate) fn variant_data(self, db: &dyn HirDatabase) -> Arc<VariantData> {
1364         match self {
1365             VariantDef::Struct(it) => it.variant_data(db),
1366             VariantDef::Union(it) => it.variant_data(db),
1367             VariantDef::Variant(it) => it.variant_data(db),
1368         }
1369     }
1370 }
1371 
1372 /// The defs which have a body.
1373 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1374 pub enum DefWithBody {
1375     Function(Function),
1376     Static(Static),
1377     Const(Const),
1378     Variant(Variant),
1379     InTypeConst(InTypeConst),
1380 }
1381 impl_from!(Function, Const, Static, Variant, InTypeConst for DefWithBody);
1382 
1383 impl DefWithBody {
module(self, db: &dyn HirDatabase) -> Module1384     pub fn module(self, db: &dyn HirDatabase) -> Module {
1385         match self {
1386             DefWithBody::Const(c) => c.module(db),
1387             DefWithBody::Function(f) => f.module(db),
1388             DefWithBody::Static(s) => s.module(db),
1389             DefWithBody::Variant(v) => v.module(db),
1390             DefWithBody::InTypeConst(c) => c.module(db),
1391         }
1392     }
1393 
name(self, db: &dyn HirDatabase) -> Option<Name>1394     pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
1395         match self {
1396             DefWithBody::Function(f) => Some(f.name(db)),
1397             DefWithBody::Static(s) => Some(s.name(db)),
1398             DefWithBody::Const(c) => c.name(db),
1399             DefWithBody::Variant(v) => Some(v.name(db)),
1400             DefWithBody::InTypeConst(_) => None,
1401         }
1402     }
1403 
1404     /// Returns the type this def's body has to evaluate to.
body_type(self, db: &dyn HirDatabase) -> Type1405     pub fn body_type(self, db: &dyn HirDatabase) -> Type {
1406         match self {
1407             DefWithBody::Function(it) => it.ret_type(db),
1408             DefWithBody::Static(it) => it.ty(db),
1409             DefWithBody::Const(it) => it.ty(db),
1410             DefWithBody::Variant(it) => it.parent.variant_body_ty(db),
1411             DefWithBody::InTypeConst(it) => Type::new_with_resolver_inner(
1412                 db,
1413                 &DefWithBodyId::from(it.id).resolver(db.upcast()),
1414                 TyKind::Error.intern(Interner),
1415             ),
1416         }
1417     }
1418 
id(&self) -> DefWithBodyId1419     fn id(&self) -> DefWithBodyId {
1420         match self {
1421             DefWithBody::Function(it) => it.id.into(),
1422             DefWithBody::Static(it) => it.id.into(),
1423             DefWithBody::Const(it) => it.id.into(),
1424             DefWithBody::Variant(it) => it.into(),
1425             DefWithBody::InTypeConst(it) => it.id.into(),
1426         }
1427     }
1428 
1429     /// A textual representation of the HIR of this def's body for debugging purposes.
debug_hir(self, db: &dyn HirDatabase) -> String1430     pub fn debug_hir(self, db: &dyn HirDatabase) -> String {
1431         let body = db.body(self.id());
1432         body.pretty_print(db.upcast(), self.id())
1433     }
1434 
1435     /// A textual representation of the MIR of this def's body for debugging purposes.
debug_mir(self, db: &dyn HirDatabase) -> String1436     pub fn debug_mir(self, db: &dyn HirDatabase) -> String {
1437         let body = db.mir_body(self.id());
1438         match body {
1439             Ok(body) => body.pretty_print(db),
1440             Err(e) => format!("error:\n{e:?}"),
1441         }
1442     }
1443 
diagnostics(self, db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>)1444     pub fn diagnostics(self, db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>) {
1445         let krate = self.module(db).id.krate();
1446 
1447         let (body, source_map) = db.body_with_source_map(self.into());
1448 
1449         for (_, def_map) in body.blocks(db.upcast()) {
1450             for diag in def_map.diagnostics() {
1451                 emit_def_diagnostic(db, acc, diag);
1452             }
1453         }
1454 
1455         for diag in source_map.diagnostics() {
1456             match diag {
1457                 BodyDiagnostic::InactiveCode { node, cfg, opts } => acc.push(
1458                     InactiveCode { node: node.clone(), cfg: cfg.clone(), opts: opts.clone() }
1459                         .into(),
1460                 ),
1461                 BodyDiagnostic::MacroError { node, message } => acc.push(
1462                     MacroError {
1463                         node: node.clone().map(|it| it.into()),
1464                         precise_location: None,
1465                         message: message.to_string(),
1466                     }
1467                     .into(),
1468                 ),
1469                 BodyDiagnostic::UnresolvedProcMacro { node, krate } => acc.push(
1470                     UnresolvedProcMacro {
1471                         node: node.clone().map(|it| it.into()),
1472                         precise_location: None,
1473                         macro_name: None,
1474                         kind: MacroKind::ProcMacro,
1475                         krate: *krate,
1476                     }
1477                     .into(),
1478                 ),
1479                 BodyDiagnostic::UnresolvedMacroCall { node, path } => acc.push(
1480                     UnresolvedMacroCall {
1481                         macro_call: node.clone().map(|ast_ptr| ast_ptr.into()),
1482                         precise_location: None,
1483                         path: path.clone(),
1484                         is_bang: true,
1485                     }
1486                     .into(),
1487                 ),
1488                 BodyDiagnostic::UnreachableLabel { node, name } => {
1489                     acc.push(UnreachableLabel { node: node.clone(), name: name.clone() }.into())
1490                 }
1491                 BodyDiagnostic::UndeclaredLabel { node, name } => {
1492                     acc.push(UndeclaredLabel { node: node.clone(), name: name.clone() }.into())
1493                 }
1494             }
1495         }
1496 
1497         let infer = db.infer(self.into());
1498         let source_map = Lazy::new(|| db.body_with_source_map(self.into()).1);
1499         let expr_syntax = |expr| source_map.expr_syntax(expr).expect("unexpected synthetic");
1500         for d in &infer.diagnostics {
1501             match d {
1502                 &hir_ty::InferenceDiagnostic::NoSuchField { expr } => {
1503                     let field = source_map.field_syntax(expr);
1504                     acc.push(NoSuchField { field }.into())
1505                 }
1506                 &hir_ty::InferenceDiagnostic::MismatchedArgCount { call_expr, expected, found } => {
1507                     acc.push(
1508                         MismatchedArgCount { call_expr: expr_syntax(call_expr), expected, found }
1509                             .into(),
1510                     )
1511                 }
1512                 &hir_ty::InferenceDiagnostic::PrivateField { expr, field } => {
1513                     let expr = expr_syntax(expr);
1514                     let field = field.into();
1515                     acc.push(PrivateField { expr, field }.into())
1516                 }
1517                 &hir_ty::InferenceDiagnostic::PrivateAssocItem { id, item } => {
1518                     let expr_or_pat = match id {
1519                         ExprOrPatId::ExprId(expr) => expr_syntax(expr).map(Either::Left),
1520                         ExprOrPatId::PatId(pat) => source_map
1521                             .pat_syntax(pat)
1522                             .expect("unexpected synthetic")
1523                             .map(Either::Right),
1524                     };
1525                     let item = item.into();
1526                     acc.push(PrivateAssocItem { expr_or_pat, item }.into())
1527                 }
1528                 hir_ty::InferenceDiagnostic::ExpectedFunction { call_expr, found } => {
1529                     let call_expr = expr_syntax(*call_expr);
1530 
1531                     acc.push(
1532                         ExpectedFunction {
1533                             call: call_expr,
1534                             found: Type::new(db, DefWithBodyId::from(self), found.clone()),
1535                         }
1536                         .into(),
1537                     )
1538                 }
1539                 hir_ty::InferenceDiagnostic::UnresolvedField {
1540                     expr,
1541                     receiver,
1542                     name,
1543                     method_with_same_name_exists,
1544                 } => {
1545                     let expr = expr_syntax(*expr);
1546 
1547                     acc.push(
1548                         UnresolvedField {
1549                             expr,
1550                             name: name.clone(),
1551                             receiver: Type::new(db, DefWithBodyId::from(self), receiver.clone()),
1552                             method_with_same_name_exists: *method_with_same_name_exists,
1553                         }
1554                         .into(),
1555                     )
1556                 }
1557                 hir_ty::InferenceDiagnostic::UnresolvedMethodCall {
1558                     expr,
1559                     receiver,
1560                     name,
1561                     field_with_same_name,
1562                 } => {
1563                     let expr = expr_syntax(*expr);
1564 
1565                     acc.push(
1566                         UnresolvedMethodCall {
1567                             expr,
1568                             name: name.clone(),
1569                             receiver: Type::new(db, DefWithBodyId::from(self), receiver.clone()),
1570                             field_with_same_name: field_with_same_name
1571                                 .clone()
1572                                 .map(|ty| Type::new(db, DefWithBodyId::from(self), ty)),
1573                         }
1574                         .into(),
1575                     )
1576                 }
1577                 &hir_ty::InferenceDiagnostic::BreakOutsideOfLoop {
1578                     expr,
1579                     is_break,
1580                     bad_value_break,
1581                 } => {
1582                     let expr = expr_syntax(expr);
1583                     acc.push(BreakOutsideOfLoop { expr, is_break, bad_value_break }.into())
1584                 }
1585                 hir_ty::InferenceDiagnostic::TypedHole { expr, expected } => {
1586                     let expr = expr_syntax(*expr);
1587                     acc.push(
1588                         TypedHole {
1589                             expr,
1590                             expected: Type::new(db, DefWithBodyId::from(self), expected.clone()),
1591                         }
1592                         .into(),
1593                     )
1594                 }
1595             }
1596         }
1597         for (pat_or_expr, mismatch) in infer.type_mismatches() {
1598             let expr_or_pat = match pat_or_expr {
1599                 ExprOrPatId::ExprId(expr) => source_map.expr_syntax(expr).map(Either::Left),
1600                 ExprOrPatId::PatId(pat) => source_map.pat_syntax(pat).map(Either::Right),
1601             };
1602             let expr_or_pat = match expr_or_pat {
1603                 Ok(Either::Left(expr)) => Either::Left(expr),
1604                 Ok(Either::Right(InFile { file_id, value: Either::Left(pat) })) => {
1605                     Either::Right(InFile { file_id, value: pat })
1606                 }
1607                 Ok(Either::Right(_)) | Err(SyntheticSyntax) => continue,
1608             };
1609 
1610             acc.push(
1611                 TypeMismatch {
1612                     expr_or_pat,
1613                     expected: Type::new(db, DefWithBodyId::from(self), mismatch.expected.clone()),
1614                     actual: Type::new(db, DefWithBodyId::from(self), mismatch.actual.clone()),
1615                 }
1616                 .into(),
1617             );
1618         }
1619 
1620         for expr in hir_ty::diagnostics::missing_unsafe(db, self.into()) {
1621             match source_map.expr_syntax(expr) {
1622                 Ok(expr) => acc.push(MissingUnsafe { expr }.into()),
1623                 Err(SyntheticSyntax) => {
1624                     // FIXME: Here and elsewhere in this file, the `expr` was
1625                     // desugared, report or assert that this doesn't happen.
1626                 }
1627             }
1628         }
1629 
1630         let hir_body = db.body(self.into());
1631 
1632         if let Ok(borrowck_results) = db.borrowck(self.into()) {
1633             for borrowck_result in borrowck_results.iter() {
1634                 let mir_body = &borrowck_result.mir_body;
1635                 for moof in &borrowck_result.moved_out_of_ref {
1636                     let span: InFile<SyntaxNodePtr> = match moof.span {
1637                         mir::MirSpan::ExprId(e) => match source_map.expr_syntax(e) {
1638                             Ok(s) => s.map(|x| x.into()),
1639                             Err(_) => continue,
1640                         },
1641                         mir::MirSpan::PatId(p) => match source_map.pat_syntax(p) {
1642                             Ok(s) => s.map(|x| match x {
1643                                 Either::Left(e) => e.into(),
1644                                 Either::Right(e) => e.into(),
1645                             }),
1646                             Err(_) => continue,
1647                         },
1648                         mir::MirSpan::Unknown => continue,
1649                     };
1650                     acc.push(
1651                         MovedOutOfRef { ty: Type::new_for_crate(krate, moof.ty.clone()), span }
1652                             .into(),
1653                     )
1654                 }
1655                 let mol = &borrowck_result.mutability_of_locals;
1656                 for (binding_id, binding_data) in hir_body.bindings.iter() {
1657                     if binding_data.problems.is_some() {
1658                         // We should report specific diagnostics for these problems, not `need-mut` and `unused-mut`.
1659                         continue;
1660                     }
1661                     let Some(&local) = mir_body.binding_locals.get(binding_id) else {
1662                         continue;
1663                     };
1664                     let need_mut = &mol[local];
1665                     let local = Local { parent: self.into(), binding_id };
1666                     match (need_mut, local.is_mut(db)) {
1667                         (mir::MutabilityReason::Mut { .. }, true)
1668                         | (mir::MutabilityReason::Not, false) => (),
1669                         (mir::MutabilityReason::Mut { spans }, false) => {
1670                             for span in spans {
1671                                 let span: InFile<SyntaxNodePtr> = match span {
1672                                     mir::MirSpan::ExprId(e) => match source_map.expr_syntax(*e) {
1673                                         Ok(s) => s.map(|x| x.into()),
1674                                         Err(_) => continue,
1675                                     },
1676                                     mir::MirSpan::PatId(p) => match source_map.pat_syntax(*p) {
1677                                         Ok(s) => s.map(|x| match x {
1678                                             Either::Left(e) => e.into(),
1679                                             Either::Right(e) => e.into(),
1680                                         }),
1681                                         Err(_) => continue,
1682                                     },
1683                                     mir::MirSpan::Unknown => continue,
1684                                 };
1685                                 acc.push(NeedMut { local, span }.into());
1686                             }
1687                         }
1688                         (mir::MutabilityReason::Not, true) => {
1689                             if !infer.mutated_bindings_in_closure.contains(&binding_id) {
1690                                 let should_ignore = matches!(body[binding_id].name.as_str(), Some(x) if x.starts_with("_"));
1691                                 if !should_ignore {
1692                                     acc.push(UnusedMut { local }.into())
1693                                 }
1694                             }
1695                         }
1696                     }
1697                 }
1698             }
1699         }
1700 
1701         for diagnostic in BodyValidationDiagnostic::collect(db, self.into()) {
1702             match diagnostic {
1703                 BodyValidationDiagnostic::RecordMissingFields {
1704                     record,
1705                     variant,
1706                     missed_fields,
1707                 } => {
1708                     let variant_data = variant.variant_data(db.upcast());
1709                     let missed_fields = missed_fields
1710                         .into_iter()
1711                         .map(|idx| variant_data.fields()[idx].name.clone())
1712                         .collect();
1713 
1714                     match record {
1715                         Either::Left(record_expr) => match source_map.expr_syntax(record_expr) {
1716                             Ok(source_ptr) => {
1717                                 let root = source_ptr.file_syntax(db.upcast());
1718                                 if let ast::Expr::RecordExpr(record_expr) =
1719                                     &source_ptr.value.to_node(&root)
1720                                 {
1721                                     if record_expr.record_expr_field_list().is_some() {
1722                                         acc.push(
1723                                             MissingFields {
1724                                                 file: source_ptr.file_id,
1725                                                 field_list_parent: Either::Left(AstPtr::new(
1726                                                     record_expr,
1727                                                 )),
1728                                                 field_list_parent_path: record_expr
1729                                                     .path()
1730                                                     .map(|path| AstPtr::new(&path)),
1731                                                 missed_fields,
1732                                             }
1733                                             .into(),
1734                                         )
1735                                     }
1736                                 }
1737                             }
1738                             Err(SyntheticSyntax) => (),
1739                         },
1740                         Either::Right(record_pat) => match source_map.pat_syntax(record_pat) {
1741                             Ok(source_ptr) => {
1742                                 if let Some(expr) = source_ptr.value.as_ref().left() {
1743                                     let root = source_ptr.file_syntax(db.upcast());
1744                                     if let ast::Pat::RecordPat(record_pat) = expr.to_node(&root) {
1745                                         if record_pat.record_pat_field_list().is_some() {
1746                                             acc.push(
1747                                                 MissingFields {
1748                                                     file: source_ptr.file_id,
1749                                                     field_list_parent: Either::Right(AstPtr::new(
1750                                                         &record_pat,
1751                                                     )),
1752                                                     field_list_parent_path: record_pat
1753                                                         .path()
1754                                                         .map(|path| AstPtr::new(&path)),
1755                                                     missed_fields,
1756                                                 }
1757                                                 .into(),
1758                                             )
1759                                         }
1760                                     }
1761                                 }
1762                             }
1763                             Err(SyntheticSyntax) => (),
1764                         },
1765                     }
1766                 }
1767                 BodyValidationDiagnostic::ReplaceFilterMapNextWithFindMap { method_call_expr } => {
1768                     if let Ok(next_source_ptr) = source_map.expr_syntax(method_call_expr) {
1769                         acc.push(
1770                             ReplaceFilterMapNextWithFindMap {
1771                                 file: next_source_ptr.file_id,
1772                                 next_expr: next_source_ptr.value,
1773                             }
1774                             .into(),
1775                         );
1776                     }
1777                 }
1778                 BodyValidationDiagnostic::MissingMatchArms { match_expr, uncovered_patterns } => {
1779                     match source_map.expr_syntax(match_expr) {
1780                         Ok(source_ptr) => {
1781                             let root = source_ptr.file_syntax(db.upcast());
1782                             if let ast::Expr::MatchExpr(match_expr) =
1783                                 &source_ptr.value.to_node(&root)
1784                             {
1785                                 if let Some(scrut_expr) = match_expr.expr() {
1786                                     acc.push(
1787                                         MissingMatchArms {
1788                                             scrutinee_expr: InFile::new(
1789                                                 source_ptr.file_id,
1790                                                 AstPtr::new(&scrut_expr),
1791                                             ),
1792                                             uncovered_patterns,
1793                                         }
1794                                         .into(),
1795                                     );
1796                                 }
1797                             }
1798                         }
1799                         Err(SyntheticSyntax) => (),
1800                     }
1801                 }
1802             }
1803         }
1804 
1805         let def: ModuleDef = match self {
1806             DefWithBody::Function(it) => it.into(),
1807             DefWithBody::Static(it) => it.into(),
1808             DefWithBody::Const(it) => it.into(),
1809             DefWithBody::Variant(it) => it.into(),
1810             // FIXME: don't ignore diagnostics for in type const
1811             DefWithBody::InTypeConst(_) => return,
1812         };
1813         for diag in hir_ty::diagnostics::incorrect_case(db, krate, def.into()) {
1814             acc.push(diag.into())
1815         }
1816     }
1817 }
1818 
1819 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1820 pub struct Function {
1821     pub(crate) id: FunctionId,
1822 }
1823 
1824 impl Function {
module(self, db: &dyn HirDatabase) -> Module1825     pub fn module(self, db: &dyn HirDatabase) -> Module {
1826         self.id.lookup(db.upcast()).module(db.upcast()).into()
1827     }
1828 
name(self, db: &dyn HirDatabase) -> Name1829     pub fn name(self, db: &dyn HirDatabase) -> Name {
1830         db.function_data(self.id).name.clone()
1831     }
1832 
ty(self, db: &dyn HirDatabase) -> Type1833     pub fn ty(self, db: &dyn HirDatabase) -> Type {
1834         Type::from_value_def(db, self.id)
1835     }
1836 
1837     /// Get this function's return type
ret_type(self, db: &dyn HirDatabase) -> Type1838     pub fn ret_type(self, db: &dyn HirDatabase) -> Type {
1839         let resolver = self.id.resolver(db.upcast());
1840         let substs = TyBuilder::placeholder_subst(db, self.id);
1841         let callable_sig = db.callable_item_signature(self.id.into()).substitute(Interner, &substs);
1842         let ty = callable_sig.ret().clone();
1843         Type::new_with_resolver_inner(db, &resolver, ty)
1844     }
1845 
async_ret_type(self, db: &dyn HirDatabase) -> Option<Type>1846     pub fn async_ret_type(self, db: &dyn HirDatabase) -> Option<Type> {
1847         if !self.is_async(db) {
1848             return None;
1849         }
1850         let resolver = self.id.resolver(db.upcast());
1851         let substs = TyBuilder::placeholder_subst(db, self.id);
1852         let callable_sig = db.callable_item_signature(self.id.into()).substitute(Interner, &substs);
1853         let ret_ty = callable_sig.ret().clone();
1854         for pred in ret_ty.impl_trait_bounds(db).into_iter().flatten() {
1855             if let WhereClause::AliasEq(output_eq) = pred.into_value_and_skipped_binders().0 {
1856                 return Type::new_with_resolver_inner(db, &resolver, output_eq.ty).into();
1857             }
1858         }
1859         never!("Async fn ret_type should be impl Future");
1860         None
1861     }
1862 
has_self_param(self, db: &dyn HirDatabase) -> bool1863     pub fn has_self_param(self, db: &dyn HirDatabase) -> bool {
1864         db.function_data(self.id).has_self_param()
1865     }
1866 
self_param(self, db: &dyn HirDatabase) -> Option<SelfParam>1867     pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> {
1868         self.has_self_param(db).then_some(SelfParam { func: self.id })
1869     }
1870 
assoc_fn_params(self, db: &dyn HirDatabase) -> Vec<Param>1871     pub fn assoc_fn_params(self, db: &dyn HirDatabase) -> Vec<Param> {
1872         let environment = db.trait_environment(self.id.into());
1873         let substs = TyBuilder::placeholder_subst(db, self.id);
1874         let callable_sig = db.callable_item_signature(self.id.into()).substitute(Interner, &substs);
1875         callable_sig
1876             .params()
1877             .iter()
1878             .enumerate()
1879             .map(|(idx, ty)| {
1880                 let ty = Type { env: environment.clone(), ty: ty.clone() };
1881                 Param { func: self, ty, idx }
1882             })
1883             .collect()
1884     }
1885 
num_params(self, db: &dyn HirDatabase) -> usize1886     pub fn num_params(self, db: &dyn HirDatabase) -> usize {
1887         db.function_data(self.id).params.len()
1888     }
1889 
method_params(self, db: &dyn HirDatabase) -> Option<Vec<Param>>1890     pub fn method_params(self, db: &dyn HirDatabase) -> Option<Vec<Param>> {
1891         if self.self_param(db).is_none() {
1892             return None;
1893         }
1894         Some(self.params_without_self(db))
1895     }
1896 
params_without_self(self, db: &dyn HirDatabase) -> Vec<Param>1897     pub fn params_without_self(self, db: &dyn HirDatabase) -> Vec<Param> {
1898         let environment = db.trait_environment(self.id.into());
1899         let substs = TyBuilder::placeholder_subst(db, self.id);
1900         let callable_sig = db.callable_item_signature(self.id.into()).substitute(Interner, &substs);
1901         let skip = if db.function_data(self.id).has_self_param() { 1 } else { 0 };
1902         callable_sig
1903             .params()
1904             .iter()
1905             .enumerate()
1906             .skip(skip)
1907             .map(|(idx, ty)| {
1908                 let ty = Type { env: environment.clone(), ty: ty.clone() };
1909                 Param { func: self, ty, idx }
1910             })
1911             .collect()
1912     }
1913 
is_const(self, db: &dyn HirDatabase) -> bool1914     pub fn is_const(self, db: &dyn HirDatabase) -> bool {
1915         db.function_data(self.id).has_const_kw()
1916     }
1917 
is_async(self, db: &dyn HirDatabase) -> bool1918     pub fn is_async(self, db: &dyn HirDatabase) -> bool {
1919         db.function_data(self.id).has_async_kw()
1920     }
1921 
is_unsafe_to_call(self, db: &dyn HirDatabase) -> bool1922     pub fn is_unsafe_to_call(self, db: &dyn HirDatabase) -> bool {
1923         hir_ty::is_fn_unsafe_to_call(db, self.id)
1924     }
1925 
1926     /// Whether this function declaration has a definition.
1927     ///
1928     /// This is false in the case of required (not provided) trait methods.
has_body(self, db: &dyn HirDatabase) -> bool1929     pub fn has_body(self, db: &dyn HirDatabase) -> bool {
1930         db.function_data(self.id).has_body()
1931     }
1932 
as_proc_macro(self, db: &dyn HirDatabase) -> Option<Macro>1933     pub fn as_proc_macro(self, db: &dyn HirDatabase) -> Option<Macro> {
1934         let function_data = db.function_data(self.id);
1935         let attrs = &function_data.attrs;
1936         // FIXME: Store this in FunctionData flags?
1937         if !(attrs.is_proc_macro()
1938             || attrs.is_proc_macro_attribute()
1939             || attrs.is_proc_macro_derive())
1940         {
1941             return None;
1942         }
1943         let loc = self.id.lookup(db.upcast());
1944         let def_map = db.crate_def_map(loc.krate(db).into());
1945         def_map.fn_as_proc_macro(self.id).map(|id| Macro { id: id.into() })
1946     }
1947 
eval( self, db: &dyn HirDatabase, span_formatter: impl Fn(FileId, TextRange) -> String, ) -> String1948     pub fn eval(
1949         self,
1950         db: &dyn HirDatabase,
1951         span_formatter: impl Fn(FileId, TextRange) -> String,
1952     ) -> String {
1953         let body = match db.monomorphized_mir_body(
1954             self.id.into(),
1955             Substitution::empty(Interner),
1956             db.trait_environment(self.id.into()),
1957         ) {
1958             Ok(body) => body,
1959             Err(e) => {
1960                 let mut r = String::new();
1961                 _ = e.pretty_print(&mut r, db, &span_formatter);
1962                 return r;
1963             }
1964         };
1965         let (result, stdout, stderr) = interpret_mir(db, &body, false);
1966         let mut text = match result {
1967             Ok(_) => "pass".to_string(),
1968             Err(e) => {
1969                 let mut r = String::new();
1970                 _ = e.pretty_print(&mut r, db, &span_formatter);
1971                 r
1972             }
1973         };
1974         if !stdout.is_empty() {
1975             text += "\n--------- stdout ---------\n";
1976             text += &stdout;
1977         }
1978         if !stderr.is_empty() {
1979             text += "\n--------- stderr ---------\n";
1980             text += &stderr;
1981         }
1982         text
1983     }
1984 }
1985 
1986 // Note: logically, this belongs to `hir_ty`, but we are not using it there yet.
1987 #[derive(Clone, Copy, PartialEq, Eq)]
1988 pub enum Access {
1989     Shared,
1990     Exclusive,
1991     Owned,
1992 }
1993 
1994 impl From<hir_ty::Mutability> for Access {
from(mutability: hir_ty::Mutability) -> Access1995     fn from(mutability: hir_ty::Mutability) -> Access {
1996         match mutability {
1997             hir_ty::Mutability::Not => Access::Shared,
1998             hir_ty::Mutability::Mut => Access::Exclusive,
1999         }
2000     }
2001 }
2002 
2003 #[derive(Clone, Debug)]
2004 pub struct Param {
2005     func: Function,
2006     /// The index in parameter list, including self parameter.
2007     idx: usize,
2008     ty: Type,
2009 }
2010 
2011 impl Param {
ty(&self) -> &Type2012     pub fn ty(&self) -> &Type {
2013         &self.ty
2014     }
2015 
name(&self, db: &dyn HirDatabase) -> Option<Name>2016     pub fn name(&self, db: &dyn HirDatabase) -> Option<Name> {
2017         Some(self.as_local(db)?.name(db))
2018     }
2019 
as_local(&self, db: &dyn HirDatabase) -> Option<Local>2020     pub fn as_local(&self, db: &dyn HirDatabase) -> Option<Local> {
2021         let parent = DefWithBodyId::FunctionId(self.func.into());
2022         let body = db.body(parent);
2023         let pat_id = body.params[self.idx];
2024         if let Pat::Bind { id, .. } = &body[pat_id] {
2025             Some(Local { parent, binding_id: *id })
2026         } else {
2027             None
2028         }
2029     }
2030 
pattern_source(&self, db: &dyn HirDatabase) -> Option<ast::Pat>2031     pub fn pattern_source(&self, db: &dyn HirDatabase) -> Option<ast::Pat> {
2032         self.source(db).and_then(|p| p.value.pat())
2033     }
2034 
source(&self, db: &dyn HirDatabase) -> Option<InFile<ast::Param>>2035     pub fn source(&self, db: &dyn HirDatabase) -> Option<InFile<ast::Param>> {
2036         let InFile { file_id, value } = self.func.source(db)?;
2037         let params = value.param_list()?;
2038         if params.self_param().is_some() {
2039             params.params().nth(self.idx.checked_sub(1)?)
2040         } else {
2041             params.params().nth(self.idx)
2042         }
2043         .map(|value| InFile { file_id, value })
2044     }
2045 }
2046 
2047 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2048 pub struct SelfParam {
2049     func: FunctionId,
2050 }
2051 
2052 impl SelfParam {
access(self, db: &dyn HirDatabase) -> Access2053     pub fn access(self, db: &dyn HirDatabase) -> Access {
2054         let func_data = db.function_data(self.func);
2055         func_data
2056             .params
2057             .first()
2058             .map(|param| match &**param {
2059                 TypeRef::Reference(.., mutability) => match mutability {
2060                     hir_def::type_ref::Mutability::Shared => Access::Shared,
2061                     hir_def::type_ref::Mutability::Mut => Access::Exclusive,
2062                 },
2063                 _ => Access::Owned,
2064             })
2065             .unwrap_or(Access::Owned)
2066     }
2067 
display(self, db: &dyn HirDatabase) -> &'static str2068     pub fn display(self, db: &dyn HirDatabase) -> &'static str {
2069         match self.access(db) {
2070             Access::Shared => "&self",
2071             Access::Exclusive => "&mut self",
2072             Access::Owned => "self",
2073         }
2074     }
2075 
source(&self, db: &dyn HirDatabase) -> Option<InFile<ast::SelfParam>>2076     pub fn source(&self, db: &dyn HirDatabase) -> Option<InFile<ast::SelfParam>> {
2077         let InFile { file_id, value } = Function::from(self.func).source(db)?;
2078         value
2079             .param_list()
2080             .and_then(|params| params.self_param())
2081             .map(|value| InFile { file_id, value })
2082     }
2083 
ty(&self, db: &dyn HirDatabase) -> Type2084     pub fn ty(&self, db: &dyn HirDatabase) -> Type {
2085         let substs = TyBuilder::placeholder_subst(db, self.func);
2086         let callable_sig =
2087             db.callable_item_signature(self.func.into()).substitute(Interner, &substs);
2088         let environment = db.trait_environment(self.func.into());
2089         let ty = callable_sig.params()[0].clone();
2090         Type { env: environment, ty }
2091     }
2092 }
2093 
2094 impl HasVisibility for Function {
visibility(&self, db: &dyn HirDatabase) -> Visibility2095     fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
2096         db.function_visibility(self.id)
2097     }
2098 }
2099 
2100 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2101 pub struct InTypeConst {
2102     pub(crate) id: InTypeConstId,
2103 }
2104 
2105 impl InTypeConst {
module(self, db: &dyn HirDatabase) -> Module2106     pub fn module(self, db: &dyn HirDatabase) -> Module {
2107         Module { id: self.id.lookup(db.upcast()).owner.module(db.upcast()) }
2108     }
2109 }
2110 
2111 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2112 pub struct Const {
2113     pub(crate) id: ConstId,
2114 }
2115 
2116 impl Const {
module(self, db: &dyn HirDatabase) -> Module2117     pub fn module(self, db: &dyn HirDatabase) -> Module {
2118         Module { id: self.id.lookup(db.upcast()).module(db.upcast()) }
2119     }
2120 
name(self, db: &dyn HirDatabase) -> Option<Name>2121     pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
2122         db.const_data(self.id).name.clone()
2123     }
2124 
value(self, db: &dyn HirDatabase) -> Option<ast::Expr>2125     pub fn value(self, db: &dyn HirDatabase) -> Option<ast::Expr> {
2126         self.source(db)?.value.body()
2127     }
2128 
ty(self, db: &dyn HirDatabase) -> Type2129     pub fn ty(self, db: &dyn HirDatabase) -> Type {
2130         Type::from_value_def(db, self.id)
2131     }
2132 
render_eval(self, db: &dyn HirDatabase) -> Result<String, ConstEvalError>2133     pub fn render_eval(self, db: &dyn HirDatabase) -> Result<String, ConstEvalError> {
2134         let c = db.const_eval(self.id.into(), Substitution::empty(Interner))?;
2135         let r = format!("{}", HexifiedConst(c).display(db));
2136         return Ok(r);
2137     }
2138 }
2139 
2140 impl HasVisibility for Const {
visibility(&self, db: &dyn HirDatabase) -> Visibility2141     fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
2142         db.const_visibility(self.id)
2143     }
2144 }
2145 
2146 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2147 pub struct Static {
2148     pub(crate) id: StaticId,
2149 }
2150 
2151 impl Static {
module(self, db: &dyn HirDatabase) -> Module2152     pub fn module(self, db: &dyn HirDatabase) -> Module {
2153         Module { id: self.id.lookup(db.upcast()).module(db.upcast()) }
2154     }
2155 
name(self, db: &dyn HirDatabase) -> Name2156     pub fn name(self, db: &dyn HirDatabase) -> Name {
2157         db.static_data(self.id).name.clone()
2158     }
2159 
is_mut(self, db: &dyn HirDatabase) -> bool2160     pub fn is_mut(self, db: &dyn HirDatabase) -> bool {
2161         db.static_data(self.id).mutable
2162     }
2163 
value(self, db: &dyn HirDatabase) -> Option<ast::Expr>2164     pub fn value(self, db: &dyn HirDatabase) -> Option<ast::Expr> {
2165         self.source(db)?.value.body()
2166     }
2167 
ty(self, db: &dyn HirDatabase) -> Type2168     pub fn ty(self, db: &dyn HirDatabase) -> Type {
2169         Type::from_value_def(db, self.id)
2170     }
2171 }
2172 
2173 impl HasVisibility for Static {
visibility(&self, db: &dyn HirDatabase) -> Visibility2174     fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
2175         db.static_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
2176     }
2177 }
2178 
2179 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2180 pub struct Trait {
2181     pub(crate) id: TraitId,
2182 }
2183 
2184 impl Trait {
lang(db: &dyn HirDatabase, krate: Crate, name: &Name) -> Option<Trait>2185     pub fn lang(db: &dyn HirDatabase, krate: Crate, name: &Name) -> Option<Trait> {
2186         db.lang_item(krate.into(), LangItem::from_name(name)?)
2187             .and_then(LangItemTarget::as_trait)
2188             .map(Into::into)
2189     }
2190 
module(self, db: &dyn HirDatabase) -> Module2191     pub fn module(self, db: &dyn HirDatabase) -> Module {
2192         Module { id: self.id.lookup(db.upcast()).container }
2193     }
2194 
name(self, db: &dyn HirDatabase) -> Name2195     pub fn name(self, db: &dyn HirDatabase) -> Name {
2196         db.trait_data(self.id).name.clone()
2197     }
2198 
items(self, db: &dyn HirDatabase) -> Vec<AssocItem>2199     pub fn items(self, db: &dyn HirDatabase) -> Vec<AssocItem> {
2200         db.trait_data(self.id).items.iter().map(|(_name, it)| (*it).into()).collect()
2201     }
2202 
items_with_supertraits(self, db: &dyn HirDatabase) -> Vec<AssocItem>2203     pub fn items_with_supertraits(self, db: &dyn HirDatabase) -> Vec<AssocItem> {
2204         let traits = all_super_traits(db.upcast(), self.into());
2205         traits.iter().flat_map(|tr| Trait::from(*tr).items(db)).collect()
2206     }
2207 
is_auto(self, db: &dyn HirDatabase) -> bool2208     pub fn is_auto(self, db: &dyn HirDatabase) -> bool {
2209         db.trait_data(self.id).is_auto
2210     }
2211 
is_unsafe(&self, db: &dyn HirDatabase) -> bool2212     pub fn is_unsafe(&self, db: &dyn HirDatabase) -> bool {
2213         db.trait_data(self.id).is_unsafe
2214     }
2215 
type_or_const_param_count( &self, db: &dyn HirDatabase, count_required_only: bool, ) -> usize2216     pub fn type_or_const_param_count(
2217         &self,
2218         db: &dyn HirDatabase,
2219         count_required_only: bool,
2220     ) -> usize {
2221         db.generic_params(GenericDefId::from(self.id))
2222             .type_or_consts
2223             .iter()
2224             .filter(|(_, ty)| match ty {
2225                 TypeOrConstParamData::TypeParamData(ty)
2226                     if ty.provenance != TypeParamProvenance::TypeParamList =>
2227                 {
2228                     false
2229                 }
2230                 _ => true,
2231             })
2232             .filter(|(_, ty)| !count_required_only || !ty.has_default())
2233             .count()
2234     }
2235 }
2236 
2237 impl HasVisibility for Trait {
visibility(&self, db: &dyn HirDatabase) -> Visibility2238     fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
2239         db.trait_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
2240     }
2241 }
2242 
2243 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2244 pub struct TraitAlias {
2245     pub(crate) id: TraitAliasId,
2246 }
2247 
2248 impl TraitAlias {
module(self, db: &dyn HirDatabase) -> Module2249     pub fn module(self, db: &dyn HirDatabase) -> Module {
2250         Module { id: self.id.lookup(db.upcast()).container }
2251     }
2252 
name(self, db: &dyn HirDatabase) -> Name2253     pub fn name(self, db: &dyn HirDatabase) -> Name {
2254         db.trait_alias_data(self.id).name.clone()
2255     }
2256 }
2257 
2258 impl HasVisibility for TraitAlias {
visibility(&self, db: &dyn HirDatabase) -> Visibility2259     fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
2260         db.trait_alias_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
2261     }
2262 }
2263 
2264 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2265 pub struct TypeAlias {
2266     pub(crate) id: TypeAliasId,
2267 }
2268 
2269 impl TypeAlias {
has_non_default_type_params(self, db: &dyn HirDatabase) -> bool2270     pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
2271         let subst = db.generic_defaults(self.id.into());
2272         subst.iter().any(|ty| match ty.skip_binders().data(Interner) {
2273             GenericArgData::Ty(x) => x.is_unknown(),
2274             _ => false,
2275         })
2276     }
2277 
module(self, db: &dyn HirDatabase) -> Module2278     pub fn module(self, db: &dyn HirDatabase) -> Module {
2279         Module { id: self.id.lookup(db.upcast()).module(db.upcast()) }
2280     }
2281 
type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef>2282     pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> {
2283         db.type_alias_data(self.id).type_ref.as_deref().cloned()
2284     }
2285 
ty(self, db: &dyn HirDatabase) -> Type2286     pub fn ty(self, db: &dyn HirDatabase) -> Type {
2287         Type::from_def(db, self.id)
2288     }
2289 
name(self, db: &dyn HirDatabase) -> Name2290     pub fn name(self, db: &dyn HirDatabase) -> Name {
2291         db.type_alias_data(self.id).name.clone()
2292     }
2293 }
2294 
2295 impl HasVisibility for TypeAlias {
visibility(&self, db: &dyn HirDatabase) -> Visibility2296     fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
2297         let function_data = db.type_alias_data(self.id);
2298         let visibility = &function_data.visibility;
2299         visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
2300     }
2301 }
2302 
2303 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2304 pub struct BuiltinType {
2305     pub(crate) inner: hir_def::builtin_type::BuiltinType,
2306 }
2307 
2308 impl BuiltinType {
str() -> BuiltinType2309     pub fn str() -> BuiltinType {
2310         BuiltinType { inner: hir_def::builtin_type::BuiltinType::Str }
2311     }
2312 
ty(self, db: &dyn HirDatabase) -> Type2313     pub fn ty(self, db: &dyn HirDatabase) -> Type {
2314         Type::new_for_crate(db.crate_graph().iter().next().unwrap(), TyBuilder::builtin(self.inner))
2315     }
2316 
name(self) -> Name2317     pub fn name(self) -> Name {
2318         self.inner.as_name()
2319     }
2320 
is_int(&self) -> bool2321     pub fn is_int(&self) -> bool {
2322         matches!(self.inner, hir_def::builtin_type::BuiltinType::Int(_))
2323     }
2324 
is_uint(&self) -> bool2325     pub fn is_uint(&self) -> bool {
2326         matches!(self.inner, hir_def::builtin_type::BuiltinType::Uint(_))
2327     }
2328 
is_float(&self) -> bool2329     pub fn is_float(&self) -> bool {
2330         matches!(self.inner, hir_def::builtin_type::BuiltinType::Float(_))
2331     }
2332 
is_char(&self) -> bool2333     pub fn is_char(&self) -> bool {
2334         matches!(self.inner, hir_def::builtin_type::BuiltinType::Char)
2335     }
2336 
is_bool(&self) -> bool2337     pub fn is_bool(&self) -> bool {
2338         matches!(self.inner, hir_def::builtin_type::BuiltinType::Bool)
2339     }
2340 
is_str(&self) -> bool2341     pub fn is_str(&self) -> bool {
2342         matches!(self.inner, hir_def::builtin_type::BuiltinType::Str)
2343     }
2344 }
2345 
2346 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2347 pub enum MacroKind {
2348     /// `macro_rules!` or Macros 2.0 macro.
2349     Declarative,
2350     /// A built-in or custom derive.
2351     Derive,
2352     /// A built-in function-like macro.
2353     BuiltIn,
2354     /// A procedural attribute macro.
2355     Attr,
2356     /// A function-like procedural macro.
2357     ProcMacro,
2358 }
2359 
2360 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2361 pub struct Macro {
2362     pub(crate) id: MacroId,
2363 }
2364 
2365 impl Macro {
module(self, db: &dyn HirDatabase) -> Module2366     pub fn module(self, db: &dyn HirDatabase) -> Module {
2367         Module { id: self.id.module(db.upcast()) }
2368     }
2369 
name(self, db: &dyn HirDatabase) -> Name2370     pub fn name(self, db: &dyn HirDatabase) -> Name {
2371         match self.id {
2372             MacroId::Macro2Id(id) => db.macro2_data(id).name.clone(),
2373             MacroId::MacroRulesId(id) => db.macro_rules_data(id).name.clone(),
2374             MacroId::ProcMacroId(id) => db.proc_macro_data(id).name.clone(),
2375         }
2376     }
2377 
is_macro_export(self, db: &dyn HirDatabase) -> bool2378     pub fn is_macro_export(self, db: &dyn HirDatabase) -> bool {
2379         matches!(self.id, MacroId::MacroRulesId(id) if db.macro_rules_data(id).macro_export)
2380     }
2381 
kind(&self, db: &dyn HirDatabase) -> MacroKind2382     pub fn kind(&self, db: &dyn HirDatabase) -> MacroKind {
2383         match self.id {
2384             MacroId::Macro2Id(it) => match it.lookup(db.upcast()).expander {
2385                 MacroExpander::Declarative => MacroKind::Declarative,
2386                 MacroExpander::BuiltIn(_) | MacroExpander::BuiltInEager(_) => MacroKind::BuiltIn,
2387                 MacroExpander::BuiltInAttr(_) => MacroKind::Attr,
2388                 MacroExpander::BuiltInDerive(_) => MacroKind::Derive,
2389             },
2390             MacroId::MacroRulesId(it) => match it.lookup(db.upcast()).expander {
2391                 MacroExpander::Declarative => MacroKind::Declarative,
2392                 MacroExpander::BuiltIn(_) | MacroExpander::BuiltInEager(_) => MacroKind::BuiltIn,
2393                 MacroExpander::BuiltInAttr(_) => MacroKind::Attr,
2394                 MacroExpander::BuiltInDerive(_) => MacroKind::Derive,
2395             },
2396             MacroId::ProcMacroId(it) => match it.lookup(db.upcast()).kind {
2397                 ProcMacroKind::CustomDerive => MacroKind::Derive,
2398                 ProcMacroKind::FuncLike => MacroKind::ProcMacro,
2399                 ProcMacroKind::Attr => MacroKind::Attr,
2400             },
2401         }
2402     }
2403 
is_fn_like(&self, db: &dyn HirDatabase) -> bool2404     pub fn is_fn_like(&self, db: &dyn HirDatabase) -> bool {
2405         match self.kind(db) {
2406             MacroKind::Declarative | MacroKind::BuiltIn | MacroKind::ProcMacro => true,
2407             MacroKind::Attr | MacroKind::Derive => false,
2408         }
2409     }
2410 
is_builtin_derive(&self, db: &dyn HirDatabase) -> bool2411     pub fn is_builtin_derive(&self, db: &dyn HirDatabase) -> bool {
2412         match self.id {
2413             MacroId::Macro2Id(it) => {
2414                 matches!(it.lookup(db.upcast()).expander, MacroExpander::BuiltInDerive(_))
2415             }
2416             MacroId::MacroRulesId(it) => {
2417                 matches!(it.lookup(db.upcast()).expander, MacroExpander::BuiltInDerive(_))
2418             }
2419             MacroId::ProcMacroId(_) => false,
2420         }
2421     }
2422 
is_attr(&self, db: &dyn HirDatabase) -> bool2423     pub fn is_attr(&self, db: &dyn HirDatabase) -> bool {
2424         matches!(self.kind(db), MacroKind::Attr)
2425     }
2426 
is_derive(&self, db: &dyn HirDatabase) -> bool2427     pub fn is_derive(&self, db: &dyn HirDatabase) -> bool {
2428         matches!(self.kind(db), MacroKind::Derive)
2429     }
2430 }
2431 
2432 impl HasVisibility for Macro {
visibility(&self, db: &dyn HirDatabase) -> Visibility2433     fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
2434         match self.id {
2435             MacroId::Macro2Id(id) => {
2436                 let data = db.macro2_data(id);
2437                 let visibility = &data.visibility;
2438                 visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
2439             }
2440             MacroId::MacroRulesId(_) => Visibility::Public,
2441             MacroId::ProcMacroId(_) => Visibility::Public,
2442         }
2443     }
2444 }
2445 
2446 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
2447 pub enum ItemInNs {
2448     Types(ModuleDef),
2449     Values(ModuleDef),
2450     Macros(Macro),
2451 }
2452 
2453 impl From<Macro> for ItemInNs {
from(it: Macro) -> Self2454     fn from(it: Macro) -> Self {
2455         Self::Macros(it)
2456     }
2457 }
2458 
2459 impl From<ModuleDef> for ItemInNs {
from(module_def: ModuleDef) -> Self2460     fn from(module_def: ModuleDef) -> Self {
2461         match module_def {
2462             ModuleDef::Static(_) | ModuleDef::Const(_) | ModuleDef::Function(_) => {
2463                 ItemInNs::Values(module_def)
2464             }
2465             _ => ItemInNs::Types(module_def),
2466         }
2467     }
2468 }
2469 
2470 impl ItemInNs {
as_module_def(self) -> Option<ModuleDef>2471     pub fn as_module_def(self) -> Option<ModuleDef> {
2472         match self {
2473             ItemInNs::Types(id) | ItemInNs::Values(id) => Some(id),
2474             ItemInNs::Macros(_) => None,
2475         }
2476     }
2477 
2478     /// Returns the crate defining this item (or `None` if `self` is built-in).
krate(&self, db: &dyn HirDatabase) -> Option<Crate>2479     pub fn krate(&self, db: &dyn HirDatabase) -> Option<Crate> {
2480         match self {
2481             ItemInNs::Types(did) | ItemInNs::Values(did) => did.module(db).map(|m| m.krate()),
2482             ItemInNs::Macros(id) => Some(id.module(db).krate()),
2483         }
2484     }
2485 
attrs(&self, db: &dyn HirDatabase) -> Option<AttrsWithOwner>2486     pub fn attrs(&self, db: &dyn HirDatabase) -> Option<AttrsWithOwner> {
2487         match self {
2488             ItemInNs::Types(it) | ItemInNs::Values(it) => it.attrs(db),
2489             ItemInNs::Macros(it) => Some(it.attrs(db)),
2490         }
2491     }
2492 }
2493 
2494 /// Invariant: `inner.as_assoc_item(db).is_some()`
2495 /// We do not actively enforce this invariant.
2496 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2497 pub enum AssocItem {
2498     Function(Function),
2499     Const(Const),
2500     TypeAlias(TypeAlias),
2501 }
2502 #[derive(Debug, Clone)]
2503 pub enum AssocItemContainer {
2504     Trait(Trait),
2505     Impl(Impl),
2506 }
2507 pub trait AsAssocItem {
as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem>2508     fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem>;
2509 }
2510 
2511 impl AsAssocItem for Function {
as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem>2512     fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem> {
2513         as_assoc_item(db, AssocItem::Function, self.id)
2514     }
2515 }
2516 impl AsAssocItem for Const {
as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem>2517     fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem> {
2518         as_assoc_item(db, AssocItem::Const, self.id)
2519     }
2520 }
2521 impl AsAssocItem for TypeAlias {
as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem>2522     fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem> {
2523         as_assoc_item(db, AssocItem::TypeAlias, self.id)
2524     }
2525 }
2526 impl AsAssocItem for ModuleDef {
as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem>2527     fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem> {
2528         match self {
2529             ModuleDef::Function(it) => it.as_assoc_item(db),
2530             ModuleDef::Const(it) => it.as_assoc_item(db),
2531             ModuleDef::TypeAlias(it) => it.as_assoc_item(db),
2532             _ => None,
2533         }
2534     }
2535 }
2536 impl AsAssocItem for DefWithBody {
as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem>2537     fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem> {
2538         match self {
2539             DefWithBody::Function(it) => it.as_assoc_item(db),
2540             DefWithBody::Const(it) => it.as_assoc_item(db),
2541             DefWithBody::Static(_) | DefWithBody::Variant(_) | DefWithBody::InTypeConst(_) => None,
2542         }
2543     }
2544 }
2545 
as_assoc_item<ID, DEF, CTOR, AST>(db: &dyn HirDatabase, ctor: CTOR, id: ID) -> Option<AssocItem> where ID: Lookup<Data = AssocItemLoc<AST>>, DEF: From<ID>, CTOR: FnOnce(DEF) -> AssocItem, AST: ItemTreeNode,2546 fn as_assoc_item<ID, DEF, CTOR, AST>(db: &dyn HirDatabase, ctor: CTOR, id: ID) -> Option<AssocItem>
2547 where
2548     ID: Lookup<Data = AssocItemLoc<AST>>,
2549     DEF: From<ID>,
2550     CTOR: FnOnce(DEF) -> AssocItem,
2551     AST: ItemTreeNode,
2552 {
2553     match id.lookup(db.upcast()).container {
2554         ItemContainerId::TraitId(_) | ItemContainerId::ImplId(_) => Some(ctor(DEF::from(id))),
2555         ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => None,
2556     }
2557 }
2558 
2559 impl AssocItem {
name(self, db: &dyn HirDatabase) -> Option<Name>2560     pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
2561         match self {
2562             AssocItem::Function(it) => Some(it.name(db)),
2563             AssocItem::Const(it) => it.name(db),
2564             AssocItem::TypeAlias(it) => Some(it.name(db)),
2565         }
2566     }
module(self, db: &dyn HirDatabase) -> Module2567     pub fn module(self, db: &dyn HirDatabase) -> Module {
2568         match self {
2569             AssocItem::Function(f) => f.module(db),
2570             AssocItem::Const(c) => c.module(db),
2571             AssocItem::TypeAlias(t) => t.module(db),
2572         }
2573     }
container(self, db: &dyn HirDatabase) -> AssocItemContainer2574     pub fn container(self, db: &dyn HirDatabase) -> AssocItemContainer {
2575         let container = match self {
2576             AssocItem::Function(it) => it.id.lookup(db.upcast()).container,
2577             AssocItem::Const(it) => it.id.lookup(db.upcast()).container,
2578             AssocItem::TypeAlias(it) => it.id.lookup(db.upcast()).container,
2579         };
2580         match container {
2581             ItemContainerId::TraitId(id) => AssocItemContainer::Trait(id.into()),
2582             ItemContainerId::ImplId(id) => AssocItemContainer::Impl(id.into()),
2583             ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => {
2584                 panic!("invalid AssocItem")
2585             }
2586         }
2587     }
2588 
containing_trait(self, db: &dyn HirDatabase) -> Option<Trait>2589     pub fn containing_trait(self, db: &dyn HirDatabase) -> Option<Trait> {
2590         match self.container(db) {
2591             AssocItemContainer::Trait(t) => Some(t),
2592             _ => None,
2593         }
2594     }
2595 
containing_trait_impl(self, db: &dyn HirDatabase) -> Option<Trait>2596     pub fn containing_trait_impl(self, db: &dyn HirDatabase) -> Option<Trait> {
2597         match self.container(db) {
2598             AssocItemContainer::Impl(i) => i.trait_(db),
2599             _ => None,
2600         }
2601     }
2602 
containing_trait_or_trait_impl(self, db: &dyn HirDatabase) -> Option<Trait>2603     pub fn containing_trait_or_trait_impl(self, db: &dyn HirDatabase) -> Option<Trait> {
2604         match self.container(db) {
2605             AssocItemContainer::Trait(t) => Some(t),
2606             AssocItemContainer::Impl(i) => i.trait_(db),
2607         }
2608     }
2609 }
2610 
2611 impl HasVisibility for AssocItem {
visibility(&self, db: &dyn HirDatabase) -> Visibility2612     fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
2613         match self {
2614             AssocItem::Function(f) => f.visibility(db),
2615             AssocItem::Const(c) => c.visibility(db),
2616             AssocItem::TypeAlias(t) => t.visibility(db),
2617         }
2618     }
2619 }
2620 
2621 impl From<AssocItem> for ModuleDef {
from(assoc: AssocItem) -> Self2622     fn from(assoc: AssocItem) -> Self {
2623         match assoc {
2624             AssocItem::Function(it) => ModuleDef::Function(it),
2625             AssocItem::Const(it) => ModuleDef::Const(it),
2626             AssocItem::TypeAlias(it) => ModuleDef::TypeAlias(it),
2627         }
2628     }
2629 }
2630 
2631 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
2632 pub enum GenericDef {
2633     Function(Function),
2634     Adt(Adt),
2635     Trait(Trait),
2636     TraitAlias(TraitAlias),
2637     TypeAlias(TypeAlias),
2638     Impl(Impl),
2639     // enum variants cannot have generics themselves, but their parent enums
2640     // can, and this makes some code easier to write
2641     Variant(Variant),
2642     // consts can have type parameters from their parents (i.e. associated consts of traits)
2643     Const(Const),
2644 }
2645 impl_from!(
2646     Function,
2647     Adt(Struct, Enum, Union),
2648     Trait,
2649     TraitAlias,
2650     TypeAlias,
2651     Impl,
2652     Variant,
2653     Const
2654     for GenericDef
2655 );
2656 
2657 impl GenericDef {
params(self, db: &dyn HirDatabase) -> Vec<GenericParam>2658     pub fn params(self, db: &dyn HirDatabase) -> Vec<GenericParam> {
2659         let generics = db.generic_params(self.into());
2660         let ty_params = generics.type_or_consts.iter().map(|(local_id, _)| {
2661             let toc = TypeOrConstParam { id: TypeOrConstParamId { parent: self.into(), local_id } };
2662             match toc.split(db) {
2663                 Either::Left(x) => GenericParam::ConstParam(x),
2664                 Either::Right(x) => GenericParam::TypeParam(x),
2665             }
2666         });
2667         self.lifetime_params(db)
2668             .into_iter()
2669             .map(GenericParam::LifetimeParam)
2670             .chain(ty_params)
2671             .collect()
2672     }
2673 
lifetime_params(self, db: &dyn HirDatabase) -> Vec<LifetimeParam>2674     pub fn lifetime_params(self, db: &dyn HirDatabase) -> Vec<LifetimeParam> {
2675         let generics = db.generic_params(self.into());
2676         generics
2677             .lifetimes
2678             .iter()
2679             .map(|(local_id, _)| LifetimeParam {
2680                 id: LifetimeParamId { parent: self.into(), local_id },
2681             })
2682             .collect()
2683     }
2684 
type_params(self, db: &dyn HirDatabase) -> Vec<TypeOrConstParam>2685     pub fn type_params(self, db: &dyn HirDatabase) -> Vec<TypeOrConstParam> {
2686         let generics = db.generic_params(self.into());
2687         generics
2688             .type_or_consts
2689             .iter()
2690             .map(|(local_id, _)| TypeOrConstParam {
2691                 id: TypeOrConstParamId { parent: self.into(), local_id },
2692             })
2693             .collect()
2694     }
2695 }
2696 
2697 /// A single local definition.
2698 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
2699 pub struct Local {
2700     pub(crate) parent: DefWithBodyId,
2701     pub(crate) binding_id: BindingId,
2702 }
2703 
2704 pub struct LocalSource {
2705     pub local: Local,
2706     pub source: InFile<Either<ast::IdentPat, ast::SelfParam>>,
2707 }
2708 
2709 impl LocalSource {
as_ident_pat(&self) -> Option<&ast::IdentPat>2710     pub fn as_ident_pat(&self) -> Option<&ast::IdentPat> {
2711         match &self.source.value {
2712             Either::Left(x) => Some(x),
2713             Either::Right(_) => None,
2714         }
2715     }
2716 
into_ident_pat(self) -> Option<ast::IdentPat>2717     pub fn into_ident_pat(self) -> Option<ast::IdentPat> {
2718         match self.source.value {
2719             Either::Left(x) => Some(x),
2720             Either::Right(_) => None,
2721         }
2722     }
2723 
original_file(&self, db: &dyn HirDatabase) -> FileId2724     pub fn original_file(&self, db: &dyn HirDatabase) -> FileId {
2725         self.source.file_id.original_file(db.upcast())
2726     }
2727 
file(&self) -> HirFileId2728     pub fn file(&self) -> HirFileId {
2729         self.source.file_id
2730     }
2731 
name(&self) -> Option<InFile<ast::Name>>2732     pub fn name(&self) -> Option<InFile<ast::Name>> {
2733         self.source.as_ref().map(|it| it.name()).transpose()
2734     }
2735 
syntax(&self) -> &SyntaxNode2736     pub fn syntax(&self) -> &SyntaxNode {
2737         self.source.value.syntax()
2738     }
2739 
syntax_ptr(self) -> InFile<SyntaxNodePtr>2740     pub fn syntax_ptr(self) -> InFile<SyntaxNodePtr> {
2741         self.source.map(|x| SyntaxNodePtr::new(x.syntax()))
2742     }
2743 }
2744 
2745 impl Local {
is_param(self, db: &dyn HirDatabase) -> bool2746     pub fn is_param(self, db: &dyn HirDatabase) -> bool {
2747         let src = self.primary_source(db);
2748         match src.source.value {
2749             Either::Left(pat) => pat
2750                 .syntax()
2751                 .ancestors()
2752                 .map(|it| it.kind())
2753                 .take_while(|&kind| ast::Pat::can_cast(kind) || ast::Param::can_cast(kind))
2754                 .any(ast::Param::can_cast),
2755             Either::Right(_) => true,
2756         }
2757     }
2758 
as_self_param(self, db: &dyn HirDatabase) -> Option<SelfParam>2759     pub fn as_self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> {
2760         match self.parent {
2761             DefWithBodyId::FunctionId(func) if self.is_self(db) => Some(SelfParam { func }),
2762             _ => None,
2763         }
2764     }
2765 
name(self, db: &dyn HirDatabase) -> Name2766     pub fn name(self, db: &dyn HirDatabase) -> Name {
2767         let body = db.body(self.parent);
2768         body[self.binding_id].name.clone()
2769     }
2770 
is_self(self, db: &dyn HirDatabase) -> bool2771     pub fn is_self(self, db: &dyn HirDatabase) -> bool {
2772         self.name(db) == name![self]
2773     }
2774 
is_mut(self, db: &dyn HirDatabase) -> bool2775     pub fn is_mut(self, db: &dyn HirDatabase) -> bool {
2776         let body = db.body(self.parent);
2777         body[self.binding_id].mode == BindingAnnotation::Mutable
2778     }
2779 
is_ref(self, db: &dyn HirDatabase) -> bool2780     pub fn is_ref(self, db: &dyn HirDatabase) -> bool {
2781         let body = db.body(self.parent);
2782         matches!(body[self.binding_id].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut)
2783     }
2784 
parent(self, _db: &dyn HirDatabase) -> DefWithBody2785     pub fn parent(self, _db: &dyn HirDatabase) -> DefWithBody {
2786         self.parent.into()
2787     }
2788 
module(self, db: &dyn HirDatabase) -> Module2789     pub fn module(self, db: &dyn HirDatabase) -> Module {
2790         self.parent(db).module(db)
2791     }
2792 
ty(self, db: &dyn HirDatabase) -> Type2793     pub fn ty(self, db: &dyn HirDatabase) -> Type {
2794         let def = self.parent;
2795         let infer = db.infer(def);
2796         let ty = infer[self.binding_id].clone();
2797         Type::new(db, def, ty)
2798     }
2799 
2800     /// All definitions for this local. Example: `let (a$0, _) | (_, a$0) = x;`
sources(self, db: &dyn HirDatabase) -> Vec<LocalSource>2801     pub fn sources(self, db: &dyn HirDatabase) -> Vec<LocalSource> {
2802         let (body, source_map) = db.body_with_source_map(self.parent);
2803         self.sources_(db, &body, &source_map).collect()
2804     }
2805 
2806     /// The leftmost definition for this local. Example: `let (a$0, _) | (_, a) = x;`
primary_source(self, db: &dyn HirDatabase) -> LocalSource2807     pub fn primary_source(self, db: &dyn HirDatabase) -> LocalSource {
2808         let (body, source_map) = db.body_with_source_map(self.parent);
2809         let src = self.sources_(db, &body, &source_map).next().unwrap();
2810         src
2811     }
2812 
sources_<'a>( self, db: &'a dyn HirDatabase, body: &'a hir_def::body::Body, source_map: &'a hir_def::body::BodySourceMap, ) -> impl Iterator<Item = LocalSource> + 'a2813     fn sources_<'a>(
2814         self,
2815         db: &'a dyn HirDatabase,
2816         body: &'a hir_def::body::Body,
2817         source_map: &'a hir_def::body::BodySourceMap,
2818     ) -> impl Iterator<Item = LocalSource> + 'a {
2819         body[self.binding_id]
2820             .definitions
2821             .iter()
2822             .map(|&definition| {
2823                 let src = source_map.pat_syntax(definition).unwrap(); // Hmm...
2824                 let root = src.file_syntax(db.upcast());
2825                 src.map(|ast| match ast {
2826                     // Suspicious unwrap
2827                     Either::Left(it) => Either::Left(it.cast().unwrap().to_node(&root)),
2828                     Either::Right(it) => Either::Right(it.to_node(&root)),
2829                 })
2830             })
2831             .map(move |source| LocalSource { local: self, source })
2832     }
2833 }
2834 
2835 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
2836 pub struct DeriveHelper {
2837     pub(crate) derive: MacroId,
2838     pub(crate) idx: u32,
2839 }
2840 
2841 impl DeriveHelper {
derive(&self) -> Macro2842     pub fn derive(&self) -> Macro {
2843         Macro { id: self.derive }
2844     }
2845 
name(&self, db: &dyn HirDatabase) -> Name2846     pub fn name(&self, db: &dyn HirDatabase) -> Name {
2847         match self.derive {
2848             MacroId::Macro2Id(it) => db
2849                 .macro2_data(it)
2850                 .helpers
2851                 .as_deref()
2852                 .and_then(|it| it.get(self.idx as usize))
2853                 .cloned(),
2854             MacroId::MacroRulesId(_) => None,
2855             MacroId::ProcMacroId(proc_macro) => db
2856                 .proc_macro_data(proc_macro)
2857                 .helpers
2858                 .as_deref()
2859                 .and_then(|it| it.get(self.idx as usize))
2860                 .cloned(),
2861         }
2862         .unwrap_or_else(|| Name::missing())
2863     }
2864 }
2865 
2866 // FIXME: Wrong name? This is could also be a registered attribute
2867 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
2868 pub struct BuiltinAttr {
2869     krate: Option<CrateId>,
2870     idx: u32,
2871 }
2872 
2873 impl BuiltinAttr {
2874     // FIXME: consider crates\hir_def\src\nameres\attr_resolution.rs?
by_name(db: &dyn HirDatabase, krate: Crate, name: &str) -> Option<Self>2875     pub(crate) fn by_name(db: &dyn HirDatabase, krate: Crate, name: &str) -> Option<Self> {
2876         if let builtin @ Some(_) = Self::builtin(name) {
2877             return builtin;
2878         }
2879         let idx =
2880             db.crate_def_map(krate.id).registered_attrs().iter().position(|it| it == name)? as u32;
2881         Some(BuiltinAttr { krate: Some(krate.id), idx })
2882     }
2883 
builtin(name: &str) -> Option<Self>2884     fn builtin(name: &str) -> Option<Self> {
2885         hir_def::attr::builtin::find_builtin_attr_idx(name)
2886             .map(|idx| BuiltinAttr { krate: None, idx: idx as u32 })
2887     }
2888 
name(&self, db: &dyn HirDatabase) -> SmolStr2889     pub fn name(&self, db: &dyn HirDatabase) -> SmolStr {
2890         // FIXME: Return a `Name` here
2891         match self.krate {
2892             Some(krate) => db.crate_def_map(krate).registered_attrs()[self.idx as usize].clone(),
2893             None => SmolStr::new(hir_def::attr::builtin::INERT_ATTRIBUTES[self.idx as usize].name),
2894         }
2895     }
2896 
template(&self, _: &dyn HirDatabase) -> Option<AttributeTemplate>2897     pub fn template(&self, _: &dyn HirDatabase) -> Option<AttributeTemplate> {
2898         match self.krate {
2899             Some(_) => None,
2900             None => Some(hir_def::attr::builtin::INERT_ATTRIBUTES[self.idx as usize].template),
2901         }
2902     }
2903 }
2904 
2905 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
2906 pub struct ToolModule {
2907     krate: Option<CrateId>,
2908     idx: u32,
2909 }
2910 
2911 impl ToolModule {
2912     // FIXME: consider crates\hir_def\src\nameres\attr_resolution.rs?
by_name(db: &dyn HirDatabase, krate: Crate, name: &str) -> Option<Self>2913     pub(crate) fn by_name(db: &dyn HirDatabase, krate: Crate, name: &str) -> Option<Self> {
2914         if let builtin @ Some(_) = Self::builtin(name) {
2915             return builtin;
2916         }
2917         let idx =
2918             db.crate_def_map(krate.id).registered_tools().iter().position(|it| it == name)? as u32;
2919         Some(ToolModule { krate: Some(krate.id), idx })
2920     }
2921 
builtin(name: &str) -> Option<Self>2922     fn builtin(name: &str) -> Option<Self> {
2923         hir_def::attr::builtin::TOOL_MODULES
2924             .iter()
2925             .position(|&tool| tool == name)
2926             .map(|idx| ToolModule { krate: None, idx: idx as u32 })
2927     }
2928 
name(&self, db: &dyn HirDatabase) -> SmolStr2929     pub fn name(&self, db: &dyn HirDatabase) -> SmolStr {
2930         // FIXME: Return a `Name` here
2931         match self.krate {
2932             Some(krate) => db.crate_def_map(krate).registered_tools()[self.idx as usize].clone(),
2933             None => SmolStr::new(hir_def::attr::builtin::TOOL_MODULES[self.idx as usize]),
2934         }
2935     }
2936 }
2937 
2938 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
2939 pub struct Label {
2940     pub(crate) parent: DefWithBodyId,
2941     pub(crate) label_id: LabelId,
2942 }
2943 
2944 impl Label {
module(self, db: &dyn HirDatabase) -> Module2945     pub fn module(self, db: &dyn HirDatabase) -> Module {
2946         self.parent(db).module(db)
2947     }
2948 
parent(self, _db: &dyn HirDatabase) -> DefWithBody2949     pub fn parent(self, _db: &dyn HirDatabase) -> DefWithBody {
2950         self.parent.into()
2951     }
2952 
name(self, db: &dyn HirDatabase) -> Name2953     pub fn name(self, db: &dyn HirDatabase) -> Name {
2954         let body = db.body(self.parent);
2955         body[self.label_id].name.clone()
2956     }
2957 
source(self, db: &dyn HirDatabase) -> InFile<ast::Label>2958     pub fn source(self, db: &dyn HirDatabase) -> InFile<ast::Label> {
2959         let (_body, source_map) = db.body_with_source_map(self.parent);
2960         let src = source_map.label_syntax(self.label_id);
2961         let root = src.file_syntax(db.upcast());
2962         src.map(|ast| ast.to_node(&root))
2963     }
2964 }
2965 
2966 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
2967 pub enum GenericParam {
2968     TypeParam(TypeParam),
2969     ConstParam(ConstParam),
2970     LifetimeParam(LifetimeParam),
2971 }
2972 impl_from!(TypeParam, ConstParam, LifetimeParam for GenericParam);
2973 
2974 impl GenericParam {
module(self, db: &dyn HirDatabase) -> Module2975     pub fn module(self, db: &dyn HirDatabase) -> Module {
2976         match self {
2977             GenericParam::TypeParam(it) => it.module(db),
2978             GenericParam::ConstParam(it) => it.module(db),
2979             GenericParam::LifetimeParam(it) => it.module(db),
2980         }
2981     }
2982 
name(self, db: &dyn HirDatabase) -> Name2983     pub fn name(self, db: &dyn HirDatabase) -> Name {
2984         match self {
2985             GenericParam::TypeParam(it) => it.name(db),
2986             GenericParam::ConstParam(it) => it.name(db),
2987             GenericParam::LifetimeParam(it) => it.name(db),
2988         }
2989     }
2990 
parent(self) -> GenericDef2991     pub fn parent(self) -> GenericDef {
2992         match self {
2993             GenericParam::TypeParam(it) => it.id.parent().into(),
2994             GenericParam::ConstParam(it) => it.id.parent().into(),
2995             GenericParam::LifetimeParam(it) => it.id.parent.into(),
2996         }
2997     }
2998 }
2999 
3000 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3001 pub struct TypeParam {
3002     pub(crate) id: TypeParamId,
3003 }
3004 
3005 impl TypeParam {
merge(self) -> TypeOrConstParam3006     pub fn merge(self) -> TypeOrConstParam {
3007         TypeOrConstParam { id: self.id.into() }
3008     }
3009 
name(self, db: &dyn HirDatabase) -> Name3010     pub fn name(self, db: &dyn HirDatabase) -> Name {
3011         self.merge().name(db)
3012     }
3013 
module(self, db: &dyn HirDatabase) -> Module3014     pub fn module(self, db: &dyn HirDatabase) -> Module {
3015         self.id.parent().module(db.upcast()).into()
3016     }
3017 
3018     /// Is this type parameter implicitly introduced (eg. `Self` in a trait or an `impl Trait`
3019     /// argument)?
is_implicit(self, db: &dyn HirDatabase) -> bool3020     pub fn is_implicit(self, db: &dyn HirDatabase) -> bool {
3021         let params = db.generic_params(self.id.parent());
3022         let data = &params.type_or_consts[self.id.local_id()];
3023         match data.type_param().unwrap().provenance {
3024             hir_def::generics::TypeParamProvenance::TypeParamList => false,
3025             hir_def::generics::TypeParamProvenance::TraitSelf
3026             | hir_def::generics::TypeParamProvenance::ArgumentImplTrait => true,
3027         }
3028     }
3029 
ty(self, db: &dyn HirDatabase) -> Type3030     pub fn ty(self, db: &dyn HirDatabase) -> Type {
3031         let resolver = self.id.parent().resolver(db.upcast());
3032         let ty =
3033             TyKind::Placeholder(hir_ty::to_placeholder_idx(db, self.id.into())).intern(Interner);
3034         Type::new_with_resolver_inner(db, &resolver, ty)
3035     }
3036 
3037     /// FIXME: this only lists trait bounds from the item defining the type
3038     /// parameter, not additional bounds that might be added e.g. by a method if
3039     /// the parameter comes from an impl!
trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait>3040     pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> {
3041         db.generic_predicates_for_param(self.id.parent(), self.id.into(), None)
3042             .iter()
3043             .filter_map(|pred| match &pred.skip_binders().skip_binders() {
3044                 hir_ty::WhereClause::Implemented(trait_ref) => {
3045                     Some(Trait::from(trait_ref.hir_trait_id()))
3046                 }
3047                 _ => None,
3048             })
3049             .collect()
3050     }
3051 
default(self, db: &dyn HirDatabase) -> Option<Type>3052     pub fn default(self, db: &dyn HirDatabase) -> Option<Type> {
3053         let params = db.generic_defaults(self.id.parent());
3054         let local_idx = hir_ty::param_idx(db, self.id.into())?;
3055         let resolver = self.id.parent().resolver(db.upcast());
3056         let ty = params.get(local_idx)?.clone();
3057         let subst = TyBuilder::placeholder_subst(db, self.id.parent());
3058         let ty = ty.substitute(Interner, &subst);
3059         match ty.data(Interner) {
3060             GenericArgData::Ty(x) => Some(Type::new_with_resolver_inner(db, &resolver, x.clone())),
3061             _ => None,
3062         }
3063     }
3064 }
3065 
3066 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3067 pub struct LifetimeParam {
3068     pub(crate) id: LifetimeParamId,
3069 }
3070 
3071 impl LifetimeParam {
name(self, db: &dyn HirDatabase) -> Name3072     pub fn name(self, db: &dyn HirDatabase) -> Name {
3073         let params = db.generic_params(self.id.parent);
3074         params.lifetimes[self.id.local_id].name.clone()
3075     }
3076 
module(self, db: &dyn HirDatabase) -> Module3077     pub fn module(self, db: &dyn HirDatabase) -> Module {
3078         self.id.parent.module(db.upcast()).into()
3079     }
3080 
parent(self, _db: &dyn HirDatabase) -> GenericDef3081     pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef {
3082         self.id.parent.into()
3083     }
3084 }
3085 
3086 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3087 pub struct ConstParam {
3088     pub(crate) id: ConstParamId,
3089 }
3090 
3091 impl ConstParam {
merge(self) -> TypeOrConstParam3092     pub fn merge(self) -> TypeOrConstParam {
3093         TypeOrConstParam { id: self.id.into() }
3094     }
3095 
name(self, db: &dyn HirDatabase) -> Name3096     pub fn name(self, db: &dyn HirDatabase) -> Name {
3097         let params = db.generic_params(self.id.parent());
3098         match params.type_or_consts[self.id.local_id()].name() {
3099             Some(x) => x.clone(),
3100             None => {
3101                 never!();
3102                 Name::missing()
3103             }
3104         }
3105     }
3106 
module(self, db: &dyn HirDatabase) -> Module3107     pub fn module(self, db: &dyn HirDatabase) -> Module {
3108         self.id.parent().module(db.upcast()).into()
3109     }
3110 
parent(self, _db: &dyn HirDatabase) -> GenericDef3111     pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef {
3112         self.id.parent().into()
3113     }
3114 
ty(self, db: &dyn HirDatabase) -> Type3115     pub fn ty(self, db: &dyn HirDatabase) -> Type {
3116         Type::new(db, self.id.parent(), db.const_param_ty(self.id))
3117     }
3118 }
3119 
3120 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3121 pub struct TypeOrConstParam {
3122     pub(crate) id: TypeOrConstParamId,
3123 }
3124 
3125 impl TypeOrConstParam {
name(self, db: &dyn HirDatabase) -> Name3126     pub fn name(self, db: &dyn HirDatabase) -> Name {
3127         let params = db.generic_params(self.id.parent);
3128         match params.type_or_consts[self.id.local_id].name() {
3129             Some(n) => n.clone(),
3130             _ => Name::missing(),
3131         }
3132     }
3133 
module(self, db: &dyn HirDatabase) -> Module3134     pub fn module(self, db: &dyn HirDatabase) -> Module {
3135         self.id.parent.module(db.upcast()).into()
3136     }
3137 
parent(self, _db: &dyn HirDatabase) -> GenericDef3138     pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef {
3139         self.id.parent.into()
3140     }
3141 
split(self, db: &dyn HirDatabase) -> Either<ConstParam, TypeParam>3142     pub fn split(self, db: &dyn HirDatabase) -> Either<ConstParam, TypeParam> {
3143         let params = db.generic_params(self.id.parent);
3144         match &params.type_or_consts[self.id.local_id] {
3145             hir_def::generics::TypeOrConstParamData::TypeParamData(_) => {
3146                 Either::Right(TypeParam { id: TypeParamId::from_unchecked(self.id) })
3147             }
3148             hir_def::generics::TypeOrConstParamData::ConstParamData(_) => {
3149                 Either::Left(ConstParam { id: ConstParamId::from_unchecked(self.id) })
3150             }
3151         }
3152     }
3153 
ty(self, db: &dyn HirDatabase) -> Type3154     pub fn ty(self, db: &dyn HirDatabase) -> Type {
3155         match self.split(db) {
3156             Either::Left(x) => x.ty(db),
3157             Either::Right(x) => x.ty(db),
3158         }
3159     }
3160 }
3161 
3162 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3163 pub struct Impl {
3164     pub(crate) id: ImplId,
3165 }
3166 
3167 impl Impl {
all_in_crate(db: &dyn HirDatabase, krate: Crate) -> Vec<Impl>3168     pub fn all_in_crate(db: &dyn HirDatabase, krate: Crate) -> Vec<Impl> {
3169         let inherent = db.inherent_impls_in_crate(krate.id);
3170         let trait_ = db.trait_impls_in_crate(krate.id);
3171 
3172         inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect()
3173     }
3174 
3175     pub fn all_for_type(db: &dyn HirDatabase, Type { ty, env }: Type) -> Vec<Impl> {
3176         let def_crates = match method_resolution::def_crates(db, &ty, env.krate) {
3177             Some(def_crates) => def_crates,
3178             None => return Vec::new(),
3179         };
3180 
3181         let filter = |impl_def: &Impl| {
3182             let self_ty = impl_def.self_ty(db);
3183             let rref = self_ty.remove_ref();
3184             ty.equals_ctor(rref.as_ref().map_or(&self_ty.ty, |it| &it.ty))
3185         };
3186 
3187         let fp = TyFingerprint::for_inherent_impl(&ty);
3188         let fp = match fp {
3189             Some(fp) => fp,
3190             None => return Vec::new(),
3191         };
3192 
3193         let mut all = Vec::new();
3194         def_crates.iter().for_each(|&id| {
3195             all.extend(
3196                 db.inherent_impls_in_crate(id)
3197                     .for_self_ty(&ty)
3198                     .iter()
3199                     .cloned()
3200                     .map(Self::from)
3201                     .filter(filter),
3202             )
3203         });
3204         for id in def_crates
3205             .iter()
3206             .flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db))
3207             .map(|Crate { id }| id)
3208             .chain(def_crates.iter().copied())
3209             .unique()
3210         {
3211             all.extend(
3212                 db.trait_impls_in_crate(id)
3213                     .for_self_ty_without_blanket_impls(fp)
3214                     .map(Self::from)
3215                     .filter(filter),
3216             );
3217         }
3218         all
3219     }
3220 
all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl>3221     pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> {
3222         let krate = trait_.module(db).krate();
3223         let mut all = Vec::new();
3224         for Crate { id } in krate.transitive_reverse_dependencies(db) {
3225             let impls = db.trait_impls_in_crate(id);
3226             all.extend(impls.for_trait(trait_.id).map(Self::from))
3227         }
3228         all
3229     }
3230 
trait_(self, db: &dyn HirDatabase) -> Option<Trait>3231     pub fn trait_(self, db: &dyn HirDatabase) -> Option<Trait> {
3232         let trait_ref = db.impl_trait(self.id)?;
3233         let id = trait_ref.skip_binders().hir_trait_id();
3234         Some(Trait { id })
3235     }
3236 
trait_ref(self, db: &dyn HirDatabase) -> Option<TraitRef>3237     pub fn trait_ref(self, db: &dyn HirDatabase) -> Option<TraitRef> {
3238         let substs = TyBuilder::placeholder_subst(db, self.id);
3239         let trait_ref = db.impl_trait(self.id)?.substitute(Interner, &substs);
3240         let resolver = self.id.resolver(db.upcast());
3241         Some(TraitRef::new_with_resolver(db, &resolver, trait_ref))
3242     }
3243 
self_ty(self, db: &dyn HirDatabase) -> Type3244     pub fn self_ty(self, db: &dyn HirDatabase) -> Type {
3245         let resolver = self.id.resolver(db.upcast());
3246         let substs = TyBuilder::placeholder_subst(db, self.id);
3247         let ty = db.impl_self_ty(self.id).substitute(Interner, &substs);
3248         Type::new_with_resolver_inner(db, &resolver, ty)
3249     }
3250 
items(self, db: &dyn HirDatabase) -> Vec<AssocItem>3251     pub fn items(self, db: &dyn HirDatabase) -> Vec<AssocItem> {
3252         db.impl_data(self.id).items.iter().map(|it| (*it).into()).collect()
3253     }
3254 
is_negative(self, db: &dyn HirDatabase) -> bool3255     pub fn is_negative(self, db: &dyn HirDatabase) -> bool {
3256         db.impl_data(self.id).is_negative
3257     }
3258 
module(self, db: &dyn HirDatabase) -> Module3259     pub fn module(self, db: &dyn HirDatabase) -> Module {
3260         self.id.lookup(db.upcast()).container.into()
3261     }
3262 
is_builtin_derive(self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>>3263     pub fn is_builtin_derive(self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>> {
3264         let src = self.source(db)?;
3265         src.file_id.is_builtin_derive(db.upcast())
3266     }
3267 }
3268 
3269 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
3270 pub struct TraitRef {
3271     env: Arc<TraitEnvironment>,
3272     trait_ref: hir_ty::TraitRef,
3273 }
3274 
3275 impl TraitRef {
new_with_resolver( db: &dyn HirDatabase, resolver: &Resolver, trait_ref: hir_ty::TraitRef, ) -> TraitRef3276     pub(crate) fn new_with_resolver(
3277         db: &dyn HirDatabase,
3278         resolver: &Resolver,
3279         trait_ref: hir_ty::TraitRef,
3280     ) -> TraitRef {
3281         let env = resolver.generic_def().map_or_else(
3282             || Arc::new(TraitEnvironment::empty(resolver.krate())),
3283             |d| db.trait_environment(d),
3284         );
3285         TraitRef { env, trait_ref }
3286     }
3287 
trait_(&self) -> Trait3288     pub fn trait_(&self) -> Trait {
3289         let id = self.trait_ref.hir_trait_id();
3290         Trait { id }
3291     }
3292 
self_ty(&self) -> Type3293     pub fn self_ty(&self) -> Type {
3294         let ty = self.trait_ref.self_type_parameter(Interner);
3295         Type { env: self.env.clone(), ty }
3296     }
3297 
3298     /// Returns `idx`-th argument of this trait reference if it is a type argument. Note that the
3299     /// first argument is the `Self` type.
get_type_argument(&self, idx: usize) -> Option<Type>3300     pub fn get_type_argument(&self, idx: usize) -> Option<Type> {
3301         self.trait_ref
3302             .substitution
3303             .as_slice(Interner)
3304             .get(idx)
3305             .and_then(|arg| arg.ty(Interner))
3306             .cloned()
3307             .map(|ty| Type { env: self.env.clone(), ty })
3308     }
3309 }
3310 
3311 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
3312 pub struct Closure {
3313     id: ClosureId,
3314     subst: Substitution,
3315 }
3316 
3317 impl From<Closure> for ClosureId {
from(value: Closure) -> Self3318     fn from(value: Closure) -> Self {
3319         value.id
3320     }
3321 }
3322 
3323 impl Closure {
as_ty(self) -> Ty3324     fn as_ty(self) -> Ty {
3325         TyKind::Closure(self.id, self.subst).intern(Interner)
3326     }
3327 
display_with_id(&self, db: &dyn HirDatabase) -> String3328     pub fn display_with_id(&self, db: &dyn HirDatabase) -> String {
3329         self.clone().as_ty().display(db).with_closure_style(ClosureStyle::ClosureWithId).to_string()
3330     }
3331 
display_with_impl(&self, db: &dyn HirDatabase) -> String3332     pub fn display_with_impl(&self, db: &dyn HirDatabase) -> String {
3333         self.clone().as_ty().display(db).with_closure_style(ClosureStyle::ImplFn).to_string()
3334     }
3335 
captured_items(&self, db: &dyn HirDatabase) -> Vec<ClosureCapture>3336     pub fn captured_items(&self, db: &dyn HirDatabase) -> Vec<ClosureCapture> {
3337         let owner = db.lookup_intern_closure((self.id).into()).0;
3338         let infer = &db.infer(owner);
3339         let info = infer.closure_info(&self.id);
3340         info.0
3341             .iter()
3342             .cloned()
3343             .map(|capture| ClosureCapture { owner, closure: self.id, capture })
3344             .collect()
3345     }
3346 
capture_types(&self, db: &dyn HirDatabase) -> Vec<Type>3347     pub fn capture_types(&self, db: &dyn HirDatabase) -> Vec<Type> {
3348         let owner = db.lookup_intern_closure((self.id).into()).0;
3349         let infer = &db.infer(owner);
3350         let (captures, _) = infer.closure_info(&self.id);
3351         captures
3352             .iter()
3353             .cloned()
3354             .map(|capture| Type {
3355                 env: db.trait_environment_for_body(owner),
3356                 ty: capture.ty(&self.subst),
3357             })
3358             .collect()
3359     }
3360 
fn_trait(&self, db: &dyn HirDatabase) -> FnTrait3361     pub fn fn_trait(&self, db: &dyn HirDatabase) -> FnTrait {
3362         let owner = db.lookup_intern_closure((self.id).into()).0;
3363         let infer = &db.infer(owner);
3364         let info = infer.closure_info(&self.id);
3365         info.1
3366     }
3367 }
3368 
3369 #[derive(Clone, Debug, PartialEq, Eq)]
3370 pub struct ClosureCapture {
3371     owner: DefWithBodyId,
3372     closure: ClosureId,
3373     capture: hir_ty::CapturedItem,
3374 }
3375 
3376 impl ClosureCapture {
local(&self) -> Local3377     pub fn local(&self) -> Local {
3378         Local { parent: self.owner, binding_id: self.capture.local() }
3379     }
3380 
kind(&self) -> CaptureKind3381     pub fn kind(&self) -> CaptureKind {
3382         match self.capture.kind() {
3383             hir_ty::CaptureKind::ByRef(
3384                 hir_ty::mir::BorrowKind::Shallow | hir_ty::mir::BorrowKind::Shared,
3385             ) => CaptureKind::SharedRef,
3386             hir_ty::CaptureKind::ByRef(hir_ty::mir::BorrowKind::Unique) => {
3387                 CaptureKind::UniqueSharedRef
3388             }
3389             hir_ty::CaptureKind::ByRef(hir_ty::mir::BorrowKind::Mut { .. }) => {
3390                 CaptureKind::MutableRef
3391             }
3392             hir_ty::CaptureKind::ByValue => CaptureKind::Move,
3393         }
3394     }
3395 
display_place(&self, db: &dyn HirDatabase) -> String3396     pub fn display_place(&self, db: &dyn HirDatabase) -> String {
3397         self.capture.display_place(self.owner, db)
3398     }
3399 }
3400 
3401 pub enum CaptureKind {
3402     SharedRef,
3403     UniqueSharedRef,
3404     MutableRef,
3405     Move,
3406 }
3407 
3408 #[derive(Clone, PartialEq, Eq, Debug)]
3409 pub struct Type {
3410     env: Arc<TraitEnvironment>,
3411     ty: Ty,
3412 }
3413 
3414 impl Type {
new_with_resolver(db: &dyn HirDatabase, resolver: &Resolver, ty: Ty) -> Type3415     pub(crate) fn new_with_resolver(db: &dyn HirDatabase, resolver: &Resolver, ty: Ty) -> Type {
3416         Type::new_with_resolver_inner(db, resolver, ty)
3417     }
3418 
new_with_resolver_inner( db: &dyn HirDatabase, resolver: &Resolver, ty: Ty, ) -> Type3419     pub(crate) fn new_with_resolver_inner(
3420         db: &dyn HirDatabase,
3421         resolver: &Resolver,
3422         ty: Ty,
3423     ) -> Type {
3424         let environment = resolver.generic_def().map_or_else(
3425             || Arc::new(TraitEnvironment::empty(resolver.krate())),
3426             |d| db.trait_environment(d),
3427         );
3428         Type { env: environment, ty }
3429     }
3430 
new_for_crate(krate: CrateId, ty: Ty) -> Type3431     pub(crate) fn new_for_crate(krate: CrateId, ty: Ty) -> Type {
3432         Type { env: Arc::new(TraitEnvironment::empty(krate)), ty }
3433     }
3434 
reference(inner: &Type, m: Mutability) -> Type3435     pub fn reference(inner: &Type, m: Mutability) -> Type {
3436         inner.derived(
3437             TyKind::Ref(
3438                 if m.is_mut() { hir_ty::Mutability::Mut } else { hir_ty::Mutability::Not },
3439                 hir_ty::static_lifetime(),
3440                 inner.ty.clone(),
3441             )
3442             .intern(Interner),
3443         )
3444     }
3445 
new(db: &dyn HirDatabase, lexical_env: impl HasResolver, ty: Ty) -> Type3446     fn new(db: &dyn HirDatabase, lexical_env: impl HasResolver, ty: Ty) -> Type {
3447         let resolver = lexical_env.resolver(db.upcast());
3448         let environment = resolver.generic_def().map_or_else(
3449             || Arc::new(TraitEnvironment::empty(resolver.krate())),
3450             |d| db.trait_environment(d),
3451         );
3452         Type { env: environment, ty }
3453     }
3454 
from_def(db: &dyn HirDatabase, def: impl Into<TyDefId> + HasResolver) -> Type3455     fn from_def(db: &dyn HirDatabase, def: impl Into<TyDefId> + HasResolver) -> Type {
3456         let ty = db.ty(def.into());
3457         let substs = TyBuilder::unknown_subst(
3458             db,
3459             match def.into() {
3460                 TyDefId::AdtId(it) => GenericDefId::AdtId(it),
3461                 TyDefId::TypeAliasId(it) => GenericDefId::TypeAliasId(it),
3462                 TyDefId::BuiltinType(_) => return Type::new(db, def, ty.skip_binders().clone()),
3463             },
3464         );
3465         Type::new(db, def, ty.substitute(Interner, &substs))
3466     }
3467 
from_value_def(db: &dyn HirDatabase, def: impl Into<ValueTyDefId> + HasResolver) -> Type3468     fn from_value_def(db: &dyn HirDatabase, def: impl Into<ValueTyDefId> + HasResolver) -> Type {
3469         let ty = db.value_ty(def.into());
3470         let substs = TyBuilder::unknown_subst(
3471             db,
3472             match def.into() {
3473                 ValueTyDefId::ConstId(it) => GenericDefId::ConstId(it),
3474                 ValueTyDefId::FunctionId(it) => GenericDefId::FunctionId(it),
3475                 ValueTyDefId::StructId(it) => GenericDefId::AdtId(AdtId::StructId(it)),
3476                 ValueTyDefId::UnionId(it) => GenericDefId::AdtId(AdtId::UnionId(it)),
3477                 ValueTyDefId::EnumVariantId(it) => GenericDefId::EnumVariantId(it),
3478                 ValueTyDefId::StaticId(_) => return Type::new(db, def, ty.skip_binders().clone()),
3479             },
3480         );
3481         Type::new(db, def, ty.substitute(Interner, &substs))
3482     }
3483 
new_slice(ty: Type) -> Type3484     pub fn new_slice(ty: Type) -> Type {
3485         Type { env: ty.env, ty: TyBuilder::slice(ty.ty) }
3486     }
3487 
is_unit(&self) -> bool3488     pub fn is_unit(&self) -> bool {
3489         matches!(self.ty.kind(Interner), TyKind::Tuple(0, ..))
3490     }
3491 
is_bool(&self) -> bool3492     pub fn is_bool(&self) -> bool {
3493         matches!(self.ty.kind(Interner), TyKind::Scalar(Scalar::Bool))
3494     }
3495 
is_never(&self) -> bool3496     pub fn is_never(&self) -> bool {
3497         matches!(self.ty.kind(Interner), TyKind::Never)
3498     }
3499 
is_mutable_reference(&self) -> bool3500     pub fn is_mutable_reference(&self) -> bool {
3501         matches!(self.ty.kind(Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..))
3502     }
3503 
is_reference(&self) -> bool3504     pub fn is_reference(&self) -> bool {
3505         matches!(self.ty.kind(Interner), TyKind::Ref(..))
3506     }
3507 
as_reference(&self) -> Option<(Type, Mutability)>3508     pub fn as_reference(&self) -> Option<(Type, Mutability)> {
3509         let (ty, _lt, m) = self.ty.as_reference()?;
3510         let m = Mutability::from_mutable(matches!(m, hir_ty::Mutability::Mut));
3511         Some((self.derived(ty.clone()), m))
3512     }
3513 
is_slice(&self) -> bool3514     pub fn is_slice(&self) -> bool {
3515         matches!(self.ty.kind(Interner), TyKind::Slice(..))
3516     }
3517 
is_usize(&self) -> bool3518     pub fn is_usize(&self) -> bool {
3519         matches!(self.ty.kind(Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize)))
3520     }
3521 
is_float(&self) -> bool3522     pub fn is_float(&self) -> bool {
3523         matches!(self.ty.kind(Interner), TyKind::Scalar(Scalar::Float(_)))
3524     }
3525 
is_char(&self) -> bool3526     pub fn is_char(&self) -> bool {
3527         matches!(self.ty.kind(Interner), TyKind::Scalar(Scalar::Char))
3528     }
3529 
is_int_or_uint(&self) -> bool3530     pub fn is_int_or_uint(&self) -> bool {
3531         match self.ty.kind(Interner) {
3532             TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_)) => true,
3533             _ => false,
3534         }
3535     }
3536 
is_scalar(&self) -> bool3537     pub fn is_scalar(&self) -> bool {
3538         matches!(self.ty.kind(Interner), TyKind::Scalar(_))
3539     }
3540 
is_tuple(&self) -> bool3541     pub fn is_tuple(&self) -> bool {
3542         matches!(self.ty.kind(Interner), TyKind::Tuple(..))
3543     }
3544 
remove_ref(&self) -> Option<Type>3545     pub fn remove_ref(&self) -> Option<Type> {
3546         match &self.ty.kind(Interner) {
3547             TyKind::Ref(.., ty) => Some(self.derived(ty.clone())),
3548             _ => None,
3549         }
3550     }
3551 
as_slice(&self) -> Option<Type>3552     pub fn as_slice(&self) -> Option<Type> {
3553         match &self.ty.kind(Interner) {
3554             TyKind::Slice(ty) => Some(self.derived(ty.clone())),
3555             _ => None,
3556         }
3557     }
3558 
strip_references(&self) -> Type3559     pub fn strip_references(&self) -> Type {
3560         self.derived(self.ty.strip_references().clone())
3561     }
3562 
strip_reference(&self) -> Type3563     pub fn strip_reference(&self) -> Type {
3564         self.derived(self.ty.strip_reference().clone())
3565     }
3566 
is_unknown(&self) -> bool3567     pub fn is_unknown(&self) -> bool {
3568         self.ty.is_unknown()
3569     }
3570 
3571     /// Checks that particular type `ty` implements `std::future::IntoFuture` or
3572     /// `std::future::Future`.
3573     /// This function is used in `.await` syntax completion.
impls_into_future(&self, db: &dyn HirDatabase) -> bool3574     pub fn impls_into_future(&self, db: &dyn HirDatabase) -> bool {
3575         let trait_ = db
3576             .lang_item(self.env.krate, LangItem::IntoFutureIntoFuture)
3577             .and_then(|it| {
3578                 let into_future_fn = it.as_function()?;
3579                 let assoc_item = as_assoc_item(db, AssocItem::Function, into_future_fn)?;
3580                 let into_future_trait = assoc_item.containing_trait_or_trait_impl(db)?;
3581                 Some(into_future_trait.id)
3582             })
3583             .or_else(|| {
3584                 let future_trait = db.lang_item(self.env.krate, LangItem::Future)?;
3585                 future_trait.as_trait()
3586             });
3587 
3588         let trait_ = match trait_ {
3589             Some(it) => it,
3590             None => return false,
3591         };
3592 
3593         let canonical_ty =
3594             Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
3595         method_resolution::implements_trait(&canonical_ty, db, self.env.clone(), trait_)
3596     }
3597 
3598     /// Checks that particular type `ty` implements `std::ops::FnOnce`.
3599     ///
3600     /// This function can be used to check if a particular type is callable, since FnOnce is a
3601     /// supertrait of Fn and FnMut, so all callable types implements at least FnOnce.
impls_fnonce(&self, db: &dyn HirDatabase) -> bool3602     pub fn impls_fnonce(&self, db: &dyn HirDatabase) -> bool {
3603         let fnonce_trait = match FnTrait::FnOnce.get_id(db, self.env.krate) {
3604             Some(it) => it,
3605             None => return false,
3606         };
3607 
3608         let canonical_ty =
3609             Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
3610         method_resolution::implements_trait_unique(
3611             &canonical_ty,
3612             db,
3613             self.env.clone(),
3614             fnonce_trait,
3615         )
3616     }
3617 
impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool3618     pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool {
3619         let mut it = args.iter().map(|t| t.ty.clone());
3620         let trait_ref = TyBuilder::trait_ref(db, trait_.id)
3621             .push(self.ty.clone())
3622             .fill(|x| {
3623                 let r = it.next().unwrap();
3624                 match x {
3625                     ParamKind::Type => GenericArgData::Ty(r).intern(Interner),
3626                     ParamKind::Const(ty) => {
3627                         // FIXME: this code is not covered in tests.
3628                         unknown_const_as_generic(ty.clone())
3629                     }
3630                 }
3631             })
3632             .build();
3633 
3634         let goal = Canonical {
3635             value: hir_ty::InEnvironment::new(&self.env.env, trait_ref.cast(Interner)),
3636             binders: CanonicalVarKinds::empty(Interner),
3637         };
3638 
3639         db.trait_solve(self.env.krate, self.env.block, goal).is_some()
3640     }
3641 
normalize_trait_assoc_type( &self, db: &dyn HirDatabase, args: &[Type], alias: TypeAlias, ) -> Option<Type>3642     pub fn normalize_trait_assoc_type(
3643         &self,
3644         db: &dyn HirDatabase,
3645         args: &[Type],
3646         alias: TypeAlias,
3647     ) -> Option<Type> {
3648         let mut args = args.iter();
3649         let trait_id = match alias.id.lookup(db.upcast()).container {
3650             ItemContainerId::TraitId(id) => id,
3651             _ => unreachable!("non assoc type alias reached in normalize_trait_assoc_type()"),
3652         };
3653         let parent_subst = TyBuilder::subst_for_def(db, trait_id, None)
3654             .push(self.ty.clone())
3655             .fill(|x| {
3656                 // FIXME: this code is not covered in tests.
3657                 match x {
3658                     ParamKind::Type => {
3659                         GenericArgData::Ty(args.next().unwrap().ty.clone()).intern(Interner)
3660                     }
3661                     ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
3662                 }
3663             })
3664             .build();
3665         // FIXME: We don't handle GATs yet.
3666         let projection = TyBuilder::assoc_type_projection(db, alias.id, Some(parent_subst)).build();
3667 
3668         let ty = db.normalize_projection(projection, self.env.clone());
3669         if ty.is_unknown() {
3670             None
3671         } else {
3672             Some(self.derived(ty))
3673         }
3674     }
3675 
is_copy(&self, db: &dyn HirDatabase) -> bool3676     pub fn is_copy(&self, db: &dyn HirDatabase) -> bool {
3677         let lang_item = db.lang_item(self.env.krate, LangItem::Copy);
3678         let copy_trait = match lang_item {
3679             Some(LangItemTarget::Trait(it)) => it,
3680             _ => return false,
3681         };
3682         self.impls_trait(db, copy_trait.into(), &[])
3683     }
3684 
as_callable(&self, db: &dyn HirDatabase) -> Option<Callable>3685     pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> {
3686         let mut the_ty = &self.ty;
3687         let callee = match self.ty.kind(Interner) {
3688             TyKind::Ref(_, _, ty) if ty.as_closure().is_some() => {
3689                 the_ty = ty;
3690                 Callee::Closure(ty.as_closure().unwrap())
3691             }
3692             TyKind::Closure(id, _) => Callee::Closure(*id),
3693             TyKind::Function(_) => Callee::FnPtr,
3694             TyKind::FnDef(..) => Callee::Def(self.ty.callable_def(db)?),
3695             _ => {
3696                 let sig = hir_ty::callable_sig_from_fnonce(&self.ty, self.env.clone(), db)?;
3697                 return Some(Callable {
3698                     ty: self.clone(),
3699                     sig,
3700                     callee: Callee::Other,
3701                     is_bound_method: false,
3702                 });
3703             }
3704         };
3705 
3706         let sig = the_ty.callable_sig(db)?;
3707         Some(Callable { ty: self.clone(), sig, callee, is_bound_method: false })
3708     }
3709 
is_closure(&self) -> bool3710     pub fn is_closure(&self) -> bool {
3711         matches!(self.ty.kind(Interner), TyKind::Closure { .. })
3712     }
3713 
as_closure(&self) -> Option<Closure>3714     pub fn as_closure(&self) -> Option<Closure> {
3715         match self.ty.kind(Interner) {
3716             TyKind::Closure(id, subst) => Some(Closure { id: *id, subst: subst.clone() }),
3717             _ => None,
3718         }
3719     }
3720 
is_fn(&self) -> bool3721     pub fn is_fn(&self) -> bool {
3722         matches!(self.ty.kind(Interner), TyKind::FnDef(..) | TyKind::Function { .. })
3723     }
3724 
is_array(&self) -> bool3725     pub fn is_array(&self) -> bool {
3726         matches!(self.ty.kind(Interner), TyKind::Array(..))
3727     }
3728 
is_packed(&self, db: &dyn HirDatabase) -> bool3729     pub fn is_packed(&self, db: &dyn HirDatabase) -> bool {
3730         let adt_id = match *self.ty.kind(Interner) {
3731             TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id,
3732             _ => return false,
3733         };
3734 
3735         let adt = adt_id.into();
3736         match adt {
3737             Adt::Struct(s) => s.repr(db).unwrap_or_default().pack.is_some(),
3738             _ => false,
3739         }
3740     }
3741 
is_raw_ptr(&self) -> bool3742     pub fn is_raw_ptr(&self) -> bool {
3743         matches!(self.ty.kind(Interner), TyKind::Raw(..))
3744     }
3745 
remove_raw_ptr(&self) -> Option<Type>3746     pub fn remove_raw_ptr(&self) -> Option<Type> {
3747         if let TyKind::Raw(_, ty) = self.ty.kind(Interner) {
3748             Some(self.derived(ty.clone()))
3749         } else {
3750             None
3751         }
3752     }
3753 
contains_unknown(&self) -> bool3754     pub fn contains_unknown(&self) -> bool {
3755         // FIXME: When we get rid of `ConstScalar::Unknown`, we can just look at precomputed
3756         // `TypeFlags` in `TyData`.
3757         return go(&self.ty);
3758 
3759         fn go(ty: &Ty) -> bool {
3760             match ty.kind(Interner) {
3761                 TyKind::Error => true,
3762 
3763                 TyKind::Adt(_, substs)
3764                 | TyKind::AssociatedType(_, substs)
3765                 | TyKind::Tuple(_, substs)
3766                 | TyKind::OpaqueType(_, substs)
3767                 | TyKind::FnDef(_, substs)
3768                 | TyKind::Closure(_, substs) => {
3769                     substs.iter(Interner).filter_map(|a| a.ty(Interner)).any(go)
3770                 }
3771 
3772                 TyKind::Array(_ty, len) if len.is_unknown() => true,
3773                 TyKind::Array(ty, _)
3774                 | TyKind::Slice(ty)
3775                 | TyKind::Raw(_, ty)
3776                 | TyKind::Ref(_, _, ty) => go(ty),
3777 
3778                 TyKind::Scalar(_)
3779                 | TyKind::Str
3780                 | TyKind::Never
3781                 | TyKind::Placeholder(_)
3782                 | TyKind::BoundVar(_)
3783                 | TyKind::InferenceVar(_, _)
3784                 | TyKind::Dyn(_)
3785                 | TyKind::Function(_)
3786                 | TyKind::Alias(_)
3787                 | TyKind::Foreign(_)
3788                 | TyKind::Generator(..)
3789                 | TyKind::GeneratorWitness(..) => false,
3790             }
3791         }
3792     }
3793 
fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)>3794     pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
3795         let (variant_id, substs) = match self.ty.kind(Interner) {
3796             TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), substs) => ((*s).into(), substs),
3797             TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), substs) => ((*u).into(), substs),
3798             _ => return Vec::new(),
3799         };
3800 
3801         db.field_types(variant_id)
3802             .iter()
3803             .map(|(local_id, ty)| {
3804                 let def = Field { parent: variant_id.into(), id: local_id };
3805                 let ty = ty.clone().substitute(Interner, substs);
3806                 (def, self.derived(ty))
3807             })
3808             .collect()
3809     }
3810 
tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type>3811     pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> {
3812         if let TyKind::Tuple(_, substs) = &self.ty.kind(Interner) {
3813             substs
3814                 .iter(Interner)
3815                 .map(|ty| self.derived(ty.assert_ty_ref(Interner).clone()))
3816                 .collect()
3817         } else {
3818             Vec::new()
3819         }
3820     }
3821 
as_array(&self, db: &dyn HirDatabase) -> Option<(Type, usize)>3822     pub fn as_array(&self, db: &dyn HirDatabase) -> Option<(Type, usize)> {
3823         if let TyKind::Array(ty, len) = &self.ty.kind(Interner) {
3824             try_const_usize(db, len).map(|x| (self.derived(ty.clone()), x as usize))
3825         } else {
3826             None
3827         }
3828     }
3829 
3830     /// Returns types that this type dereferences to (including this type itself). The returned
3831     /// iterator won't yield the same type more than once even if the deref chain contains a cycle.
autoderef(&self, db: &dyn HirDatabase) -> impl Iterator<Item = Type> + '_3832     pub fn autoderef(&self, db: &dyn HirDatabase) -> impl Iterator<Item = Type> + '_ {
3833         self.autoderef_(db).map(move |ty| self.derived(ty))
3834     }
3835 
autoderef_(&self, db: &dyn HirDatabase) -> impl Iterator<Item = Ty>3836     fn autoderef_(&self, db: &dyn HirDatabase) -> impl Iterator<Item = Ty> {
3837         // There should be no inference vars in types passed here
3838         let canonical = hir_ty::replace_errors_with_variables(&self.ty);
3839         autoderef(db, self.env.clone(), canonical)
3840     }
3841 
3842     // This would be nicer if it just returned an iterator, but that runs into
3843     // lifetime problems, because we need to borrow temp `CrateImplDefs`.
iterate_assoc_items<T>( &self, db: &dyn HirDatabase, krate: Crate, mut callback: impl FnMut(AssocItem) -> Option<T>, ) -> Option<T>3844     pub fn iterate_assoc_items<T>(
3845         &self,
3846         db: &dyn HirDatabase,
3847         krate: Crate,
3848         mut callback: impl FnMut(AssocItem) -> Option<T>,
3849     ) -> Option<T> {
3850         let mut slot = None;
3851         self.iterate_assoc_items_dyn(db, krate, &mut |assoc_item_id| {
3852             slot = callback(assoc_item_id.into());
3853             slot.is_some()
3854         });
3855         slot
3856     }
3857 
iterate_assoc_items_dyn( &self, db: &dyn HirDatabase, krate: Crate, callback: &mut dyn FnMut(AssocItemId) -> bool, )3858     fn iterate_assoc_items_dyn(
3859         &self,
3860         db: &dyn HirDatabase,
3861         krate: Crate,
3862         callback: &mut dyn FnMut(AssocItemId) -> bool,
3863     ) {
3864         let def_crates = match method_resolution::def_crates(db, &self.ty, krate.id) {
3865             Some(it) => it,
3866             None => return,
3867         };
3868         for krate in def_crates {
3869             let impls = db.inherent_impls_in_crate(krate);
3870 
3871             for impl_def in impls.for_self_ty(&self.ty) {
3872                 for &item in db.impl_data(*impl_def).items.iter() {
3873                     if callback(item) {
3874                         return;
3875                     }
3876                 }
3877             }
3878         }
3879     }
3880 
3881     /// Iterates its type arguments
3882     ///
3883     /// It iterates the actual type arguments when concrete types are used
3884     /// and otherwise the generic names.
3885     /// It does not include `const` arguments.
3886     ///
3887     /// For code, such as:
3888     /// ```text
3889     /// struct Foo<T, U>
3890     ///
3891     /// impl<U> Foo<String, U>
3892     /// ```
3893     ///
3894     /// It iterates:
3895     /// ```text
3896     /// - "String"
3897     /// - "U"
3898     /// ```
type_arguments(&self) -> impl Iterator<Item = Type> + '_3899     pub fn type_arguments(&self) -> impl Iterator<Item = Type> + '_ {
3900         self.ty
3901             .strip_references()
3902             .as_adt()
3903             .into_iter()
3904             .flat_map(|(_, substs)| substs.iter(Interner))
3905             .filter_map(|arg| arg.ty(Interner).cloned())
3906             .map(move |ty| self.derived(ty))
3907     }
3908 
3909     /// Iterates its type and const arguments
3910     ///
3911     /// It iterates the actual type and const arguments when concrete types
3912     /// are used and otherwise the generic names.
3913     ///
3914     /// For code, such as:
3915     /// ```text
3916     /// struct Foo<T, const U: usize, const X: usize>
3917     ///
3918     /// impl<U> Foo<String, U, 12>
3919     /// ```
3920     ///
3921     /// It iterates:
3922     /// ```text
3923     /// - "String"
3924     /// - "U"
3925     /// - "12"
3926     /// ```
type_and_const_arguments<'a>( &'a self, db: &'a dyn HirDatabase, ) -> impl Iterator<Item = SmolStr> + 'a3927     pub fn type_and_const_arguments<'a>(
3928         &'a self,
3929         db: &'a dyn HirDatabase,
3930     ) -> impl Iterator<Item = SmolStr> + 'a {
3931         self.ty
3932             .strip_references()
3933             .as_adt()
3934             .into_iter()
3935             .flat_map(|(_, substs)| substs.iter(Interner))
3936             .filter_map(|arg| {
3937                 // arg can be either a `Ty` or `constant`
3938                 if let Some(ty) = arg.ty(Interner) {
3939                     Some(SmolStr::new(ty.display(db).to_string()))
3940                 } else if let Some(const_) = arg.constant(Interner) {
3941                     Some(SmolStr::new_inline(&const_.display(db).to_string()))
3942                 } else {
3943                     None
3944                 }
3945             })
3946     }
3947 
3948     /// Combines lifetime indicators, type and constant parameters into a single `Iterator`
generic_parameters<'a>( &'a self, db: &'a dyn HirDatabase, ) -> impl Iterator<Item = SmolStr> + 'a3949     pub fn generic_parameters<'a>(
3950         &'a self,
3951         db: &'a dyn HirDatabase,
3952     ) -> impl Iterator<Item = SmolStr> + 'a {
3953         // iterate the lifetime
3954         self.as_adt()
3955             .and_then(|a| a.lifetime(db).and_then(|lt| Some((&lt.name).to_smol_str())))
3956             .into_iter()
3957             // add the type and const parameters
3958             .chain(self.type_and_const_arguments(db))
3959     }
3960 
iterate_method_candidates_with_traits<T>( &self, db: &dyn HirDatabase, scope: &SemanticsScope<'_>, traits_in_scope: &FxHashSet<TraitId>, with_local_impls: Option<Module>, name: Option<&Name>, mut callback: impl FnMut(Function) -> Option<T>, ) -> Option<T>3961     pub fn iterate_method_candidates_with_traits<T>(
3962         &self,
3963         db: &dyn HirDatabase,
3964         scope: &SemanticsScope<'_>,
3965         traits_in_scope: &FxHashSet<TraitId>,
3966         with_local_impls: Option<Module>,
3967         name: Option<&Name>,
3968         mut callback: impl FnMut(Function) -> Option<T>,
3969     ) -> Option<T> {
3970         let _p = profile::span("iterate_method_candidates");
3971         let mut slot = None;
3972 
3973         self.iterate_method_candidates_dyn(
3974             db,
3975             scope,
3976             traits_in_scope,
3977             with_local_impls,
3978             name,
3979             &mut |assoc_item_id| {
3980                 if let AssocItemId::FunctionId(func) = assoc_item_id {
3981                     if let Some(res) = callback(func.into()) {
3982                         slot = Some(res);
3983                         return ControlFlow::Break(());
3984                     }
3985                 }
3986                 ControlFlow::Continue(())
3987             },
3988         );
3989         slot
3990     }
3991 
iterate_method_candidates<T>( &self, db: &dyn HirDatabase, scope: &SemanticsScope<'_>, with_local_impls: Option<Module>, name: Option<&Name>, callback: impl FnMut(Function) -> Option<T>, ) -> Option<T>3992     pub fn iterate_method_candidates<T>(
3993         &self,
3994         db: &dyn HirDatabase,
3995         scope: &SemanticsScope<'_>,
3996         with_local_impls: Option<Module>,
3997         name: Option<&Name>,
3998         callback: impl FnMut(Function) -> Option<T>,
3999     ) -> Option<T> {
4000         self.iterate_method_candidates_with_traits(
4001             db,
4002             scope,
4003             &scope.visible_traits().0,
4004             with_local_impls,
4005             name,
4006             callback,
4007         )
4008     }
4009 
iterate_method_candidates_dyn( &self, db: &dyn HirDatabase, scope: &SemanticsScope<'_>, traits_in_scope: &FxHashSet<TraitId>, with_local_impls: Option<Module>, name: Option<&Name>, callback: &mut dyn FnMut(AssocItemId) -> ControlFlow<()>, )4010     fn iterate_method_candidates_dyn(
4011         &self,
4012         db: &dyn HirDatabase,
4013         scope: &SemanticsScope<'_>,
4014         traits_in_scope: &FxHashSet<TraitId>,
4015         with_local_impls: Option<Module>,
4016         name: Option<&Name>,
4017         callback: &mut dyn FnMut(AssocItemId) -> ControlFlow<()>,
4018     ) {
4019         // There should be no inference vars in types passed here
4020         let canonical = hir_ty::replace_errors_with_variables(&self.ty);
4021 
4022         let krate = scope.krate();
4023         let environment = scope.resolver().generic_def().map_or_else(
4024             || Arc::new(TraitEnvironment::empty(krate.id)),
4025             |d| db.trait_environment(d),
4026         );
4027 
4028         method_resolution::iterate_method_candidates_dyn(
4029             &canonical,
4030             db,
4031             environment,
4032             traits_in_scope,
4033             with_local_impls.and_then(|b| b.id.containing_block()).into(),
4034             name,
4035             method_resolution::LookupMode::MethodCall,
4036             &mut |_adj, id, _| callback(id),
4037         );
4038     }
4039 
iterate_path_candidates<T>( &self, db: &dyn HirDatabase, scope: &SemanticsScope<'_>, traits_in_scope: &FxHashSet<TraitId>, with_local_impls: Option<Module>, name: Option<&Name>, mut callback: impl FnMut(AssocItem) -> Option<T>, ) -> Option<T>4040     pub fn iterate_path_candidates<T>(
4041         &self,
4042         db: &dyn HirDatabase,
4043         scope: &SemanticsScope<'_>,
4044         traits_in_scope: &FxHashSet<TraitId>,
4045         with_local_impls: Option<Module>,
4046         name: Option<&Name>,
4047         mut callback: impl FnMut(AssocItem) -> Option<T>,
4048     ) -> Option<T> {
4049         let _p = profile::span("iterate_path_candidates");
4050         let mut slot = None;
4051         self.iterate_path_candidates_dyn(
4052             db,
4053             scope,
4054             traits_in_scope,
4055             with_local_impls,
4056             name,
4057             &mut |assoc_item_id| {
4058                 if let Some(res) = callback(assoc_item_id.into()) {
4059                     slot = Some(res);
4060                     return ControlFlow::Break(());
4061                 }
4062                 ControlFlow::Continue(())
4063             },
4064         );
4065         slot
4066     }
4067 
iterate_path_candidates_dyn( &self, db: &dyn HirDatabase, scope: &SemanticsScope<'_>, traits_in_scope: &FxHashSet<TraitId>, with_local_impls: Option<Module>, name: Option<&Name>, callback: &mut dyn FnMut(AssocItemId) -> ControlFlow<()>, )4068     fn iterate_path_candidates_dyn(
4069         &self,
4070         db: &dyn HirDatabase,
4071         scope: &SemanticsScope<'_>,
4072         traits_in_scope: &FxHashSet<TraitId>,
4073         with_local_impls: Option<Module>,
4074         name: Option<&Name>,
4075         callback: &mut dyn FnMut(AssocItemId) -> ControlFlow<()>,
4076     ) {
4077         let canonical = hir_ty::replace_errors_with_variables(&self.ty);
4078 
4079         let krate = scope.krate();
4080         let environment = scope.resolver().generic_def().map_or_else(
4081             || Arc::new(TraitEnvironment::empty(krate.id)),
4082             |d| db.trait_environment(d),
4083         );
4084 
4085         method_resolution::iterate_path_candidates(
4086             &canonical,
4087             db,
4088             environment,
4089             traits_in_scope,
4090             with_local_impls.and_then(|b| b.id.containing_block()).into(),
4091             name,
4092             &mut |id| callback(id),
4093         );
4094     }
4095 
as_adt(&self) -> Option<Adt>4096     pub fn as_adt(&self) -> Option<Adt> {
4097         let (adt, _subst) = self.ty.as_adt()?;
4098         Some(adt.into())
4099     }
4100 
as_builtin(&self) -> Option<BuiltinType>4101     pub fn as_builtin(&self) -> Option<BuiltinType> {
4102         self.ty.as_builtin().map(|inner| BuiltinType { inner })
4103     }
4104 
as_dyn_trait(&self) -> Option<Trait>4105     pub fn as_dyn_trait(&self) -> Option<Trait> {
4106         self.ty.dyn_trait().map(Into::into)
4107     }
4108 
4109     /// If a type can be represented as `dyn Trait`, returns all traits accessible via this type,
4110     /// or an empty iterator otherwise.
applicable_inherent_traits<'a>( &'a self, db: &'a dyn HirDatabase, ) -> impl Iterator<Item = Trait> + 'a4111     pub fn applicable_inherent_traits<'a>(
4112         &'a self,
4113         db: &'a dyn HirDatabase,
4114     ) -> impl Iterator<Item = Trait> + 'a {
4115         let _p = profile::span("applicable_inherent_traits");
4116         self.autoderef_(db)
4117             .filter_map(|ty| ty.dyn_trait())
4118             .flat_map(move |dyn_trait_id| hir_ty::all_super_traits(db.upcast(), dyn_trait_id))
4119             .map(Trait::from)
4120     }
4121 
env_traits<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Trait> + 'a4122     pub fn env_traits<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Trait> + 'a {
4123         let _p = profile::span("env_traits");
4124         self.autoderef_(db)
4125             .filter(|ty| matches!(ty.kind(Interner), TyKind::Placeholder(_)))
4126             .flat_map(|ty| {
4127                 self.env
4128                     .traits_in_scope_from_clauses(ty)
4129                     .flat_map(|t| hir_ty::all_super_traits(db.upcast(), t))
4130             })
4131             .map(Trait::from)
4132     }
4133 
as_impl_traits(&self, db: &dyn HirDatabase) -> Option<impl Iterator<Item = Trait>>4134     pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<impl Iterator<Item = Trait>> {
4135         self.ty.impl_trait_bounds(db).map(|it| {
4136             it.into_iter().filter_map(|pred| match pred.skip_binders() {
4137                 hir_ty::WhereClause::Implemented(trait_ref) => {
4138                     Some(Trait::from(trait_ref.hir_trait_id()))
4139                 }
4140                 _ => None,
4141             })
4142         })
4143     }
4144 
as_associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<Trait>4145     pub fn as_associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<Trait> {
4146         self.ty.associated_type_parent_trait(db).map(Into::into)
4147     }
4148 
derived(&self, ty: Ty) -> Type4149     fn derived(&self, ty: Ty) -> Type {
4150         Type { env: self.env.clone(), ty }
4151     }
4152 
4153     /// Visits every type, including generic arguments, in this type. `cb` is called with type
4154     /// itself first, and then with its generic arguments.
walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type))4155     pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) {
4156         fn walk_substs(
4157             db: &dyn HirDatabase,
4158             type_: &Type,
4159             substs: &Substitution,
4160             cb: &mut impl FnMut(Type),
4161         ) {
4162             for ty in substs.iter(Interner).filter_map(|a| a.ty(Interner)) {
4163                 walk_type(db, &type_.derived(ty.clone()), cb);
4164             }
4165         }
4166 
4167         fn walk_bounds(
4168             db: &dyn HirDatabase,
4169             type_: &Type,
4170             bounds: &[QuantifiedWhereClause],
4171             cb: &mut impl FnMut(Type),
4172         ) {
4173             for pred in bounds {
4174                 if let WhereClause::Implemented(trait_ref) = pred.skip_binders() {
4175                     cb(type_.clone());
4176                     // skip the self type. it's likely the type we just got the bounds from
4177                     for ty in
4178                         trait_ref.substitution.iter(Interner).skip(1).filter_map(|a| a.ty(Interner))
4179                     {
4180                         walk_type(db, &type_.derived(ty.clone()), cb);
4181                     }
4182                 }
4183             }
4184         }
4185 
4186         fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
4187             let ty = type_.ty.strip_references();
4188             match ty.kind(Interner) {
4189                 TyKind::Adt(_, substs) => {
4190                     cb(type_.derived(ty.clone()));
4191                     walk_substs(db, type_, substs, cb);
4192                 }
4193                 TyKind::AssociatedType(_, substs) => {
4194                     if ty.associated_type_parent_trait(db).is_some() {
4195                         cb(type_.derived(ty.clone()));
4196                     }
4197                     walk_substs(db, type_, substs, cb);
4198                 }
4199                 TyKind::OpaqueType(_, subst) => {
4200                     if let Some(bounds) = ty.impl_trait_bounds(db) {
4201                         walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
4202                     }
4203 
4204                     walk_substs(db, type_, subst, cb);
4205                 }
4206                 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
4207                     if let Some(bounds) = ty.impl_trait_bounds(db) {
4208                         walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
4209                     }
4210 
4211                     walk_substs(db, type_, &opaque_ty.substitution, cb);
4212                 }
4213                 TyKind::Placeholder(_) => {
4214                     if let Some(bounds) = ty.impl_trait_bounds(db) {
4215                         walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
4216                     }
4217                 }
4218                 TyKind::Dyn(bounds) => {
4219                     walk_bounds(
4220                         db,
4221                         &type_.derived(ty.clone()),
4222                         bounds.bounds.skip_binders().interned(),
4223                         cb,
4224                     );
4225                 }
4226 
4227                 TyKind::Ref(_, _, ty)
4228                 | TyKind::Raw(_, ty)
4229                 | TyKind::Array(ty, _)
4230                 | TyKind::Slice(ty) => {
4231                     walk_type(db, &type_.derived(ty.clone()), cb);
4232                 }
4233 
4234                 TyKind::FnDef(_, substs)
4235                 | TyKind::Tuple(_, substs)
4236                 | TyKind::Closure(.., substs) => {
4237                     walk_substs(db, type_, substs, cb);
4238                 }
4239                 TyKind::Function(hir_ty::FnPointer { substitution, .. }) => {
4240                     walk_substs(db, type_, &substitution.0, cb);
4241                 }
4242 
4243                 _ => {}
4244             }
4245         }
4246 
4247         walk_type(db, self, &mut cb);
4248     }
4249 
could_unify_with(&self, db: &dyn HirDatabase, other: &Type) -> bool4250     pub fn could_unify_with(&self, db: &dyn HirDatabase, other: &Type) -> bool {
4251         let tys = hir_ty::replace_errors_with_variables(&(self.ty.clone(), other.ty.clone()));
4252         hir_ty::could_unify(db, self.env.clone(), &tys)
4253     }
4254 
could_coerce_to(&self, db: &dyn HirDatabase, to: &Type) -> bool4255     pub fn could_coerce_to(&self, db: &dyn HirDatabase, to: &Type) -> bool {
4256         let tys = hir_ty::replace_errors_with_variables(&(self.ty.clone(), to.ty.clone()));
4257         hir_ty::could_coerce(db, self.env.clone(), &tys)
4258     }
4259 
as_type_param(&self, db: &dyn HirDatabase) -> Option<TypeParam>4260     pub fn as_type_param(&self, db: &dyn HirDatabase) -> Option<TypeParam> {
4261         match self.ty.kind(Interner) {
4262             TyKind::Placeholder(p) => Some(TypeParam {
4263                 id: TypeParamId::from_unchecked(hir_ty::from_placeholder_idx(db, *p)),
4264             }),
4265             _ => None,
4266         }
4267     }
4268 
4269     /// Returns unique `GenericParam`s contained in this type.
generic_params(&self, db: &dyn HirDatabase) -> FxHashSet<GenericParam>4270     pub fn generic_params(&self, db: &dyn HirDatabase) -> FxHashSet<GenericParam> {
4271         hir_ty::collect_placeholders(&self.ty, db)
4272             .into_iter()
4273             .map(|id| TypeOrConstParam { id }.split(db).either_into())
4274             .collect()
4275     }
4276 
layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError>4277     pub fn layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
4278         db.layout_of_ty(self.ty.clone(), self.env.krate)
4279             .map(|layout| Layout(layout, db.target_data_layout(self.env.krate).unwrap()))
4280     }
4281 }
4282 
4283 // FIXME: Document this
4284 #[derive(Debug)]
4285 pub struct Callable {
4286     ty: Type,
4287     sig: CallableSig,
4288     callee: Callee,
4289     /// Whether this is a method that was called with method call syntax.
4290     pub(crate) is_bound_method: bool,
4291 }
4292 
4293 #[derive(Debug)]
4294 enum Callee {
4295     Def(CallableDefId),
4296     Closure(ClosureId),
4297     FnPtr,
4298     Other,
4299 }
4300 
4301 pub enum CallableKind {
4302     Function(Function),
4303     TupleStruct(Struct),
4304     TupleEnumVariant(Variant),
4305     Closure,
4306     FnPtr,
4307     /// Some other type that implements `FnOnce`.
4308     Other,
4309 }
4310 
4311 impl Callable {
kind(&self) -> CallableKind4312     pub fn kind(&self) -> CallableKind {
4313         use Callee::*;
4314         match self.callee {
4315             Def(CallableDefId::FunctionId(it)) => CallableKind::Function(it.into()),
4316             Def(CallableDefId::StructId(it)) => CallableKind::TupleStruct(it.into()),
4317             Def(CallableDefId::EnumVariantId(it)) => CallableKind::TupleEnumVariant(it.into()),
4318             Closure(_) => CallableKind::Closure,
4319             FnPtr => CallableKind::FnPtr,
4320             Other => CallableKind::Other,
4321         }
4322     }
receiver_param(&self, db: &dyn HirDatabase) -> Option<(ast::SelfParam, Type)>4323     pub fn receiver_param(&self, db: &dyn HirDatabase) -> Option<(ast::SelfParam, Type)> {
4324         let func = match self.callee {
4325             Callee::Def(CallableDefId::FunctionId(it)) if self.is_bound_method => it,
4326             _ => return None,
4327         };
4328         let src = func.lookup(db.upcast()).source(db.upcast());
4329         let param_list = src.value.param_list()?;
4330         Some((param_list.self_param()?, self.ty.derived(self.sig.params()[0].clone())))
4331     }
n_params(&self) -> usize4332     pub fn n_params(&self) -> usize {
4333         self.sig.params().len() - if self.is_bound_method { 1 } else { 0 }
4334     }
params( &self, db: &dyn HirDatabase, ) -> Vec<(Option<Either<ast::SelfParam, ast::Pat>>, Type)>4335     pub fn params(
4336         &self,
4337         db: &dyn HirDatabase,
4338     ) -> Vec<(Option<Either<ast::SelfParam, ast::Pat>>, Type)> {
4339         let types = self
4340             .sig
4341             .params()
4342             .iter()
4343             .skip(if self.is_bound_method { 1 } else { 0 })
4344             .map(|ty| self.ty.derived(ty.clone()));
4345         let map_param = |it: ast::Param| it.pat().map(Either::Right);
4346         let patterns = match self.callee {
4347             Callee::Def(CallableDefId::FunctionId(func)) => {
4348                 let src = func.lookup(db.upcast()).source(db.upcast());
4349                 src.value.param_list().map(|param_list| {
4350                     param_list
4351                         .self_param()
4352                         .map(|it| Some(Either::Left(it)))
4353                         .filter(|_| !self.is_bound_method)
4354                         .into_iter()
4355                         .chain(param_list.params().map(map_param))
4356                 })
4357             }
4358             Callee::Closure(closure_id) => match closure_source(db, closure_id) {
4359                 Some(src) => src.param_list().map(|param_list| {
4360                     param_list
4361                         .self_param()
4362                         .map(|it| Some(Either::Left(it)))
4363                         .filter(|_| !self.is_bound_method)
4364                         .into_iter()
4365                         .chain(param_list.params().map(map_param))
4366                 }),
4367                 None => None,
4368             },
4369             _ => None,
4370         };
4371         patterns.into_iter().flatten().chain(iter::repeat(None)).zip(types).collect()
4372     }
return_type(&self) -> Type4373     pub fn return_type(&self) -> Type {
4374         self.ty.derived(self.sig.ret().clone())
4375     }
4376 }
4377 
closure_source(db: &dyn HirDatabase, closure: ClosureId) -> Option<ast::ClosureExpr>4378 fn closure_source(db: &dyn HirDatabase, closure: ClosureId) -> Option<ast::ClosureExpr> {
4379     let (owner, expr_id) = db.lookup_intern_closure(closure.into());
4380     let (_, source_map) = db.body_with_source_map(owner);
4381     let ast = source_map.expr_syntax(expr_id).ok()?;
4382     let root = ast.file_syntax(db.upcast());
4383     let expr = ast.value.to_node(&root);
4384     match expr {
4385         ast::Expr::ClosureExpr(it) => Some(it),
4386         _ => None,
4387     }
4388 }
4389 
4390 #[derive(Clone, Debug, Eq, PartialEq)]
4391 pub struct Layout(Arc<TyLayout>, Arc<TargetDataLayout>);
4392 
4393 impl Layout {
size(&self) -> u644394     pub fn size(&self) -> u64 {
4395         self.0.size.bytes()
4396     }
4397 
align(&self) -> u644398     pub fn align(&self) -> u64 {
4399         self.0.align.abi.bytes()
4400     }
4401 
niches(&self) -> Option<u128>4402     pub fn niches(&self) -> Option<u128> {
4403         Some(self.0.largest_niche?.available(&*self.1))
4404     }
4405 
field_offset(&self, idx: usize) -> Option<u64>4406     pub fn field_offset(&self, idx: usize) -> Option<u64> {
4407         match self.0.fields {
4408             layout::FieldsShape::Primitive => None,
4409             layout::FieldsShape::Union(_) => Some(0),
4410             layout::FieldsShape::Array { stride, count } => {
4411                 let i = u64::try_from(idx).ok()?;
4412                 (i < count).then_some((stride * i).bytes())
4413             }
4414             layout::FieldsShape::Arbitrary { ref offsets, .. } => Some(offsets.get(idx)?.bytes()),
4415         }
4416     }
4417 
enum_tag_size(&self) -> Option<usize>4418     pub fn enum_tag_size(&self) -> Option<usize> {
4419         let tag_size =
4420             if let layout::Variants::Multiple { tag, tag_encoding, .. } = &self.0.variants {
4421                 match tag_encoding {
4422                     TagEncoding::Direct => tag.size(&*self.1).bytes_usize(),
4423                     TagEncoding::Niche { .. } => 0,
4424                 }
4425             } else {
4426                 return None;
4427             };
4428         Some(tag_size)
4429     }
4430 }
4431 
4432 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
4433 pub enum BindingMode {
4434     Move,
4435     Ref(Mutability),
4436 }
4437 
4438 /// For IDE only
4439 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
4440 pub enum ScopeDef {
4441     ModuleDef(ModuleDef),
4442     GenericParam(GenericParam),
4443     ImplSelfType(Impl),
4444     AdtSelfType(Adt),
4445     Local(Local),
4446     Label(Label),
4447     Unknown,
4448 }
4449 
4450 impl ScopeDef {
all_items(def: PerNs) -> ArrayVec<Self, 3>4451     pub fn all_items(def: PerNs) -> ArrayVec<Self, 3> {
4452         let mut items = ArrayVec::new();
4453 
4454         match (def.take_types(), def.take_values()) {
4455             (Some(m1), None) => items.push(ScopeDef::ModuleDef(m1.into())),
4456             (None, Some(m2)) => items.push(ScopeDef::ModuleDef(m2.into())),
4457             (Some(m1), Some(m2)) => {
4458                 // Some items, like unit structs and enum variants, are
4459                 // returned as both a type and a value. Here we want
4460                 // to de-duplicate them.
4461                 if m1 != m2 {
4462                     items.push(ScopeDef::ModuleDef(m1.into()));
4463                     items.push(ScopeDef::ModuleDef(m2.into()));
4464                 } else {
4465                     items.push(ScopeDef::ModuleDef(m1.into()));
4466                 }
4467             }
4468             (None, None) => {}
4469         };
4470 
4471         if let Some(macro_def_id) = def.take_macros() {
4472             items.push(ScopeDef::ModuleDef(ModuleDef::Macro(macro_def_id.into())));
4473         }
4474 
4475         if items.is_empty() {
4476             items.push(ScopeDef::Unknown);
4477         }
4478 
4479         items
4480     }
4481 
attrs(&self, db: &dyn HirDatabase) -> Option<AttrsWithOwner>4482     pub fn attrs(&self, db: &dyn HirDatabase) -> Option<AttrsWithOwner> {
4483         match self {
4484             ScopeDef::ModuleDef(it) => it.attrs(db),
4485             ScopeDef::GenericParam(it) => Some(it.attrs(db)),
4486             ScopeDef::ImplSelfType(_)
4487             | ScopeDef::AdtSelfType(_)
4488             | ScopeDef::Local(_)
4489             | ScopeDef::Label(_)
4490             | ScopeDef::Unknown => None,
4491         }
4492     }
4493 
krate(&self, db: &dyn HirDatabase) -> Option<Crate>4494     pub fn krate(&self, db: &dyn HirDatabase) -> Option<Crate> {
4495         match self {
4496             ScopeDef::ModuleDef(it) => it.module(db).map(|m| m.krate()),
4497             ScopeDef::GenericParam(it) => Some(it.module(db).krate()),
4498             ScopeDef::ImplSelfType(_) => None,
4499             ScopeDef::AdtSelfType(it) => Some(it.module(db).krate()),
4500             ScopeDef::Local(it) => Some(it.module(db).krate()),
4501             ScopeDef::Label(it) => Some(it.module(db).krate()),
4502             ScopeDef::Unknown => None,
4503         }
4504     }
4505 }
4506 
4507 impl From<ItemInNs> for ScopeDef {
from(item: ItemInNs) -> Self4508     fn from(item: ItemInNs) -> Self {
4509         match item {
4510             ItemInNs::Types(id) => ScopeDef::ModuleDef(id),
4511             ItemInNs::Values(id) => ScopeDef::ModuleDef(id),
4512             ItemInNs::Macros(id) => ScopeDef::ModuleDef(ModuleDef::Macro(id)),
4513         }
4514     }
4515 }
4516 
4517 #[derive(Clone, Debug, PartialEq, Eq)]
4518 pub struct Adjustment {
4519     pub source: Type,
4520     pub target: Type,
4521     pub kind: Adjust,
4522 }
4523 
4524 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4525 pub enum Adjust {
4526     /// Go from ! to any type.
4527     NeverToAny,
4528     /// Dereference once, producing a place.
4529     Deref(Option<OverloadedDeref>),
4530     /// Take the address and produce either a `&` or `*` pointer.
4531     Borrow(AutoBorrow),
4532     Pointer(PointerCast),
4533 }
4534 
4535 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4536 pub enum AutoBorrow {
4537     /// Converts from T to &T.
4538     Ref(Mutability),
4539     /// Converts from T to *T.
4540     RawPtr(Mutability),
4541 }
4542 
4543 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4544 pub struct OverloadedDeref(pub Mutability);
4545 
4546 pub trait HasVisibility {
visibility(&self, db: &dyn HirDatabase) -> Visibility4547     fn visibility(&self, db: &dyn HirDatabase) -> Visibility;
is_visible_from(&self, db: &dyn HirDatabase, module: Module) -> bool4548     fn is_visible_from(&self, db: &dyn HirDatabase, module: Module) -> bool {
4549         let vis = self.visibility(db);
4550         vis.is_visible_from(db.upcast(), module.id)
4551     }
4552 }
4553 
4554 /// Trait for obtaining the defining crate of an item.
4555 pub trait HasCrate {
krate(&self, db: &dyn HirDatabase) -> Crate4556     fn krate(&self, db: &dyn HirDatabase) -> Crate;
4557 }
4558 
4559 impl<T: hir_def::HasModule> HasCrate for T {
krate(&self, db: &dyn HirDatabase) -> Crate4560     fn krate(&self, db: &dyn HirDatabase) -> Crate {
4561         self.module(db.upcast()).krate().into()
4562     }
4563 }
4564 
4565 impl HasCrate for AssocItem {
krate(&self, db: &dyn HirDatabase) -> Crate4566     fn krate(&self, db: &dyn HirDatabase) -> Crate {
4567         self.module(db).krate()
4568     }
4569 }
4570 
4571 impl HasCrate for Struct {
krate(&self, db: &dyn HirDatabase) -> Crate4572     fn krate(&self, db: &dyn HirDatabase) -> Crate {
4573         self.module(db).krate()
4574     }
4575 }
4576 
4577 impl HasCrate for Union {
krate(&self, db: &dyn HirDatabase) -> Crate4578     fn krate(&self, db: &dyn HirDatabase) -> Crate {
4579         self.module(db).krate()
4580     }
4581 }
4582 
4583 impl HasCrate for Enum {
krate(&self, db: &dyn HirDatabase) -> Crate4584     fn krate(&self, db: &dyn HirDatabase) -> Crate {
4585         self.module(db).krate()
4586     }
4587 }
4588 
4589 impl HasCrate for Field {
krate(&self, db: &dyn HirDatabase) -> Crate4590     fn krate(&self, db: &dyn HirDatabase) -> Crate {
4591         self.parent_def(db).module(db).krate()
4592     }
4593 }
4594 
4595 impl HasCrate for Variant {
krate(&self, db: &dyn HirDatabase) -> Crate4596     fn krate(&self, db: &dyn HirDatabase) -> Crate {
4597         self.module(db).krate()
4598     }
4599 }
4600 
4601 impl HasCrate for Function {
krate(&self, db: &dyn HirDatabase) -> Crate4602     fn krate(&self, db: &dyn HirDatabase) -> Crate {
4603         self.module(db).krate()
4604     }
4605 }
4606 
4607 impl HasCrate for Const {
krate(&self, db: &dyn HirDatabase) -> Crate4608     fn krate(&self, db: &dyn HirDatabase) -> Crate {
4609         self.module(db).krate()
4610     }
4611 }
4612 
4613 impl HasCrate for TypeAlias {
krate(&self, db: &dyn HirDatabase) -> Crate4614     fn krate(&self, db: &dyn HirDatabase) -> Crate {
4615         self.module(db).krate()
4616     }
4617 }
4618 
4619 impl HasCrate for Type {
krate(&self, _db: &dyn HirDatabase) -> Crate4620     fn krate(&self, _db: &dyn HirDatabase) -> Crate {
4621         self.env.krate.into()
4622     }
4623 }
4624 
4625 impl HasCrate for Macro {
krate(&self, db: &dyn HirDatabase) -> Crate4626     fn krate(&self, db: &dyn HirDatabase) -> Crate {
4627         self.module(db).krate()
4628     }
4629 }
4630 
4631 impl HasCrate for Trait {
krate(&self, db: &dyn HirDatabase) -> Crate4632     fn krate(&self, db: &dyn HirDatabase) -> Crate {
4633         self.module(db).krate()
4634     }
4635 }
4636 
4637 impl HasCrate for TraitAlias {
krate(&self, db: &dyn HirDatabase) -> Crate4638     fn krate(&self, db: &dyn HirDatabase) -> Crate {
4639         self.module(db).krate()
4640     }
4641 }
4642 
4643 impl HasCrate for Static {
krate(&self, db: &dyn HirDatabase) -> Crate4644     fn krate(&self, db: &dyn HirDatabase) -> Crate {
4645         self.module(db).krate()
4646     }
4647 }
4648 
4649 impl HasCrate for Adt {
krate(&self, db: &dyn HirDatabase) -> Crate4650     fn krate(&self, db: &dyn HirDatabase) -> Crate {
4651         self.module(db).krate()
4652     }
4653 }
4654 
4655 impl HasCrate for Module {
krate(&self, _: &dyn HirDatabase) -> Crate4656     fn krate(&self, _: &dyn HirDatabase) -> Crate {
4657         Module::krate(*self)
4658     }
4659 }
4660 
4661 pub trait HasContainer {
container(&self, db: &dyn HirDatabase) -> ItemContainer4662     fn container(&self, db: &dyn HirDatabase) -> ItemContainer;
4663 }
4664 
4665 impl HasContainer for Module {
container(&self, db: &dyn HirDatabase) -> ItemContainer4666     fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
4667         // FIXME: handle block expressions as modules (their parent is in a different DefMap)
4668         let def_map = self.id.def_map(db.upcast());
4669         match def_map[self.id.local_id].parent {
4670             Some(parent_id) => ItemContainer::Module(Module { id: def_map.module_id(parent_id) }),
4671             None => ItemContainer::Crate(def_map.krate()),
4672         }
4673     }
4674 }
4675 
4676 impl HasContainer for Function {
container(&self, db: &dyn HirDatabase) -> ItemContainer4677     fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
4678         container_id_to_hir(self.id.lookup(db.upcast()).container)
4679     }
4680 }
4681 
4682 impl HasContainer for Struct {
container(&self, db: &dyn HirDatabase) -> ItemContainer4683     fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
4684         ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container })
4685     }
4686 }
4687 
4688 impl HasContainer for Union {
container(&self, db: &dyn HirDatabase) -> ItemContainer4689     fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
4690         ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container })
4691     }
4692 }
4693 
4694 impl HasContainer for Enum {
container(&self, db: &dyn HirDatabase) -> ItemContainer4695     fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
4696         ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container })
4697     }
4698 }
4699 
4700 impl HasContainer for TypeAlias {
container(&self, db: &dyn HirDatabase) -> ItemContainer4701     fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
4702         container_id_to_hir(self.id.lookup(db.upcast()).container)
4703     }
4704 }
4705 
4706 impl HasContainer for Const {
container(&self, db: &dyn HirDatabase) -> ItemContainer4707     fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
4708         container_id_to_hir(self.id.lookup(db.upcast()).container)
4709     }
4710 }
4711 
4712 impl HasContainer for Static {
container(&self, db: &dyn HirDatabase) -> ItemContainer4713     fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
4714         container_id_to_hir(self.id.lookup(db.upcast()).container)
4715     }
4716 }
4717 
4718 impl HasContainer for Trait {
container(&self, db: &dyn HirDatabase) -> ItemContainer4719     fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
4720         ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container })
4721     }
4722 }
4723 
4724 impl HasContainer for TraitAlias {
container(&self, db: &dyn HirDatabase) -> ItemContainer4725     fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
4726         ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container })
4727     }
4728 }
4729 
container_id_to_hir(c: ItemContainerId) -> ItemContainer4730 fn container_id_to_hir(c: ItemContainerId) -> ItemContainer {
4731     match c {
4732         ItemContainerId::ExternBlockId(_id) => ItemContainer::ExternBlock(),
4733         ItemContainerId::ModuleId(id) => ItemContainer::Module(Module { id }),
4734         ItemContainerId::ImplId(id) => ItemContainer::Impl(Impl { id }),
4735         ItemContainerId::TraitId(id) => ItemContainer::Trait(Trait { id }),
4736     }
4737 }
4738 
4739 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4740 pub enum ItemContainer {
4741     Trait(Trait),
4742     Impl(Impl),
4743     Module(Module),
4744     ExternBlock(),
4745     Crate(CrateId),
4746 }
4747