1 //! FIXME: write short doc here
2 use std::{iter, sync::Arc};
4 use arrayvec::ArrayVec;
5 use base_db::{CrateDisplayName, CrateId, Edition, FileId};
11 builtin_type::BuiltinType,
12 expr::{BindingAnnotation, Pat, PatId},
14 item_tree::ItemTreeNode,
15 lang_item::LangItemTarget,
18 resolver::{HasResolver, Resolver},
20 type_ref::{Mutability, TypeRef},
21 AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, DefWithBodyId, EnumId,
22 FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, LocalEnumVariantId, LocalFieldId,
23 LocalModuleId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId,
26 use hir_def::{find_path::PrefixKind, item_scope::ItemInNs, visibility::Visibility};
28 diagnostics::DiagnosticSink,
30 MacroDefId, MacroDefKind,
34 display::{HirDisplayError, HirFormatter},
36 traits::{FnTrait, Solution, SolutionVariables},
37 ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate,
38 InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, Ty,
39 TyDefId, TyKind, TypeCtor,
41 use rustc_hash::FxHashSet;
44 ast::{self, AttrsOwner, NameOwner},
47 use tt::{Ident, Leaf, Literal, TokenTree};
50 db::{DefDatabase, HirDatabase},
51 has_source::HasSource,
52 HirDisplay, InFile, Name,
55 /// hir::Crate describes a single crate. It's the main interface with which
56 /// a crate's dependencies interact. Mostly, it should be just a proxy for the
58 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
60 pub(crate) id: CrateId,
64 pub struct CrateDependency {
70 pub fn dependencies(self, db: &dyn HirDatabase) -> Vec<CrateDependency> {
71 db.crate_graph()[self.id]
75 let krate = Crate { id: dep.crate_id };
76 let name = dep.as_name();
77 CrateDependency { krate, name }
82 // FIXME: add `transitive_reverse_dependencies`.
83 pub fn reverse_dependencies(self, db: &dyn HirDatabase) -> Vec<Crate> {
84 let crate_graph = db.crate_graph();
88 crate_graph[krate].dependencies.iter().any(|it| it.crate_id == self.id)
90 .map(|id| Crate { id })
94 pub fn root_module(self, db: &dyn HirDatabase) -> Module {
95 let module_id = db.crate_def_map(self.id).root;
96 Module::new(self, module_id)
99 pub fn root_file(self, db: &dyn HirDatabase) -> FileId {
100 db.crate_graph()[self.id].root_file_id
103 pub fn edition(self, db: &dyn HirDatabase) -> Edition {
104 db.crate_graph()[self.id].edition
107 pub fn display_name(self, db: &dyn HirDatabase) -> Option<CrateDisplayName> {
108 db.crate_graph()[self.id].display_name.clone()
111 pub fn query_external_importables(
113 db: &dyn DefDatabase,
114 query: import_map::Query,
115 ) -> impl Iterator<Item = Either<ModuleDef, MacroDef>> {
116 import_map::search_dependencies(db, self.into(), query).into_iter().map(|item| match item {
117 ItemInNs::Types(mod_id) | ItemInNs::Values(mod_id) => Either::Left(mod_id.into()),
118 ItemInNs::Macros(mac_id) => Either::Right(mac_id.into()),
122 pub fn all(db: &dyn HirDatabase) -> Vec<Crate> {
123 db.crate_graph().iter().map(|id| Crate { id }).collect()
126 /// Try to get the root URL of the documentation of a crate.
127 pub fn get_html_root_url(self: &Crate, db: &dyn HirDatabase) -> Option<String> {
128 // Look for #![doc(html_root_url = "...")]
129 let attrs = db.attrs(AttrDefId::ModuleId(self.root_module(db).into()));
130 let doc_attr_q = attrs.by_key("doc");
132 if !doc_attr_q.exists() {
136 let doc_url = doc_attr_q.tt_values().map(|tt| {
137 let name = tt.token_trees.iter()
138 .skip_while(|tt| !matches!(tt, TokenTree::Leaf(Leaf::Ident(Ident{text: ref ident, ..})) if ident == "html_root_url"))
143 Some(TokenTree::Leaf(Leaf::Literal(Literal{ref text, ..}))) => Some(text),
146 }).flat_map(|t| t).next();
148 doc_url.map(|s| s.trim_matches('"').trim_end_matches('/').to_owned() + "/")
152 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
154 pub(crate) id: ModuleId,
157 /// The defs which can be visible in the module.
158 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
163 // Can't be directly declared, but can be imported.
164 EnumVariant(EnumVariant),
168 TypeAlias(TypeAlias),
169 BuiltinType(BuiltinType),
174 Adt(Struct, Enum, Union),
184 impl From<VariantDef> for ModuleDef {
185 fn from(var: VariantDef) -> Self {
187 VariantDef::Struct(t) => Adt::from(t).into(),
188 VariantDef::Union(t) => Adt::from(t).into(),
189 VariantDef::EnumVariant(t) => t.into(),
195 pub fn module(self, db: &dyn HirDatabase) -> Option<Module> {
197 ModuleDef::Module(it) => it.parent(db),
198 ModuleDef::Function(it) => Some(it.module(db)),
199 ModuleDef::Adt(it) => Some(it.module(db)),
200 ModuleDef::EnumVariant(it) => Some(it.module(db)),
201 ModuleDef::Const(it) => Some(it.module(db)),
202 ModuleDef::Static(it) => Some(it.module(db)),
203 ModuleDef::Trait(it) => Some(it.module(db)),
204 ModuleDef::TypeAlias(it) => Some(it.module(db)),
205 ModuleDef::BuiltinType(_) => None,
209 pub fn canonical_path(&self, db: &dyn HirDatabase) -> Option<String> {
210 let mut segments = Vec::new();
211 segments.push(self.name(db)?.to_string());
212 for m in self.module(db)?.path_to_root(db) {
213 segments.extend(m.name(db).map(|it| it.to_string()))
216 Some(segments.join("::"))
219 pub fn definition_visibility(&self, db: &dyn HirDatabase) -> Option<Visibility> {
220 let module = match self {
221 ModuleDef::Module(it) => it.parent(db)?,
222 ModuleDef::Function(it) => return Some(it.visibility(db)),
223 ModuleDef::Adt(it) => it.module(db),
224 ModuleDef::EnumVariant(it) => {
225 let parent = it.parent_enum(db);
226 let module = it.module(db);
227 return module.visibility_of(db, &ModuleDef::Adt(Adt::Enum(parent)));
229 ModuleDef::Const(it) => return Some(it.visibility(db)),
230 ModuleDef::Static(it) => it.module(db),
231 ModuleDef::Trait(it) => it.module(db),
232 ModuleDef::TypeAlias(it) => return Some(it.visibility(db)),
233 ModuleDef::BuiltinType(_) => return None,
236 module.visibility_of(db, self)
239 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
241 ModuleDef::Adt(it) => Some(it.name(db)),
242 ModuleDef::Trait(it) => Some(it.name(db)),
243 ModuleDef::Function(it) => Some(it.name(db)),
244 ModuleDef::EnumVariant(it) => Some(it.name(db)),
245 ModuleDef::TypeAlias(it) => Some(it.name(db)),
246 ModuleDef::Module(it) => it.name(db),
247 ModuleDef::Const(it) => it.name(db),
248 ModuleDef::Static(it) => it.name(db),
250 ModuleDef::BuiltinType(it) => Some(it.as_name()),
254 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
255 let id = match self {
256 ModuleDef::Adt(it) => match it {
257 Adt::Struct(it) => it.id.into(),
258 Adt::Enum(it) => it.id.into(),
259 Adt::Union(it) => it.id.into(),
261 ModuleDef::Trait(it) => it.id.into(),
262 ModuleDef::Function(it) => it.id.into(),
263 ModuleDef::TypeAlias(it) => it.id.into(),
264 ModuleDef::Module(it) => it.id.into(),
265 ModuleDef::Const(it) => it.id.into(),
266 ModuleDef::Static(it) => it.id.into(),
270 let module = match self.module(db) {
275 hir_ty::diagnostics::validate_module_item(db, module.id.krate, id, sink)
280 pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module {
281 Module { id: ModuleId { krate: krate.id, local_id: crate_module_id } }
284 /// Name of this module.
285 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
286 let def_map = db.crate_def_map(self.id.krate);
287 let parent = def_map[self.id.local_id].parent?;
288 def_map[parent].children.iter().find_map(|(name, module_id)| {
289 if *module_id == self.id.local_id {
297 /// Returns the crate this module is part of.
298 pub fn krate(self) -> Crate {
299 Crate { id: self.id.krate }
302 /// Topmost parent of this module. Every module has a `crate_root`, but some
303 /// might be missing `krate`. This can happen if a module's file is not included
304 /// in the module tree of any target in `Cargo.toml`.
305 pub fn crate_root(self, db: &dyn HirDatabase) -> Module {
306 let def_map = db.crate_def_map(self.id.krate);
307 self.with_module_id(def_map.root)
310 /// Iterates over all child modules.
311 pub fn children(self, db: &dyn HirDatabase) -> impl Iterator<Item = Module> {
312 let def_map = db.crate_def_map(self.id.krate);
313 let children = def_map[self.id.local_id]
316 .map(|(_, module_id)| self.with_module_id(*module_id))
317 .collect::<Vec<_>>();
321 /// Finds a parent module.
322 pub fn parent(self, db: &dyn HirDatabase) -> Option<Module> {
323 let def_map = db.crate_def_map(self.id.krate);
324 let parent_id = def_map[self.id.local_id].parent?;
325 Some(self.with_module_id(parent_id))
328 pub fn path_to_root(self, db: &dyn HirDatabase) -> Vec<Module> {
329 let mut res = vec![self];
331 while let Some(next) = curr.parent(db) {
338 /// Returns a `ModuleScope`: a set of items, visible in this module.
341 db: &dyn HirDatabase,
342 visible_from: Option<Module>,
343 ) -> Vec<(Name, ScopeDef)> {
344 db.crate_def_map(self.id.krate)[self.id.local_id]
347 .filter_map(|(name, def)| {
348 if let Some(m) = visible_from {
350 def.filter_visibility(|vis| vis.is_visible_from(db.upcast(), m.id));
351 if filtered.is_none() && !def.is_none() {
354 Some((name, filtered))
360 .flat_map(|(name, def)| {
361 ScopeDef::all_items(def).into_iter().map(move |item| (name.clone(), item))
366 pub fn visibility_of(self, db: &dyn HirDatabase, def: &ModuleDef) -> Option<Visibility> {
367 db.crate_def_map(self.id.krate)[self.id.local_id].scope.visibility_of(def.clone().into())
370 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
371 let _p = profile::span("Module::diagnostics").detail(|| {
372 format!("{:?}", self.name(db).map_or("<unknown>".into(), |name| name.to_string()))
374 let crate_def_map = db.crate_def_map(self.id.krate);
375 crate_def_map.add_diagnostics(db.upcast(), self.id.local_id, sink);
376 for decl in self.declarations(db) {
377 decl.diagnostics(db, sink);
380 crate::ModuleDef::Function(f) => f.diagnostics(db, sink),
381 crate::ModuleDef::Module(m) => {
382 // Only add diagnostics from inline modules
383 if crate_def_map[m.id.local_id].origin.is_inline() {
384 m.diagnostics(db, sink)
391 for impl_def in self.impl_defs(db) {
392 for item in impl_def.items(db) {
393 if let AssocItem::Function(f) = item {
394 f.diagnostics(db, sink);
400 pub fn declarations(self, db: &dyn HirDatabase) -> Vec<ModuleDef> {
401 let def_map = db.crate_def_map(self.id.krate);
402 def_map[self.id.local_id].scope.declarations().map(ModuleDef::from).collect()
405 pub fn impl_defs(self, db: &dyn HirDatabase) -> Vec<Impl> {
406 let def_map = db.crate_def_map(self.id.krate);
407 def_map[self.id.local_id].scope.impls().map(Impl::from).collect()
410 pub(crate) fn with_module_id(self, module_id: LocalModuleId) -> Module {
411 Module::new(self.krate(), module_id)
414 /// Finds a path that can be used to refer to the given item from within
415 /// this module, if possible.
416 pub fn find_use_path(self, db: &dyn DefDatabase, item: impl Into<ItemInNs>) -> Option<ModPath> {
417 hir_def::find_path::find_path(db, item.into(), self.into())
420 /// Finds a path that can be used to refer to the given item from within
421 /// this module, if possible. This is used for returning import paths for use-statements.
422 pub fn find_use_path_prefixed(
424 db: &dyn DefDatabase,
425 item: impl Into<ItemInNs>,
426 prefix_kind: PrefixKind,
427 ) -> Option<ModPath> {
428 hir_def::find_path::find_path_prefixed(db, item.into(), self.into(), prefix_kind)
432 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
434 pub(crate) parent: VariantDef,
435 pub(crate) id: LocalFieldId,
438 #[derive(Debug, PartialEq, Eq)]
439 pub enum FieldSource {
440 Named(ast::RecordField),
441 Pos(ast::TupleField),
445 pub fn name(&self, db: &dyn HirDatabase) -> Name {
446 self.parent.variant_data(db).fields()[self.id].name.clone()
449 /// Returns the type as in the signature of the struct (i.e., with
450 /// placeholder types for type parameters). This is good for showing
451 /// signature help, but not so good to actually get the type of the field
452 /// when you actually have a variable of the struct.
453 pub fn signature_ty(&self, db: &dyn HirDatabase) -> Type {
454 let var_id = self.parent.into();
455 let generic_def_id: GenericDefId = match self.parent {
456 VariantDef::Struct(it) => it.id.into(),
457 VariantDef::Union(it) => it.id.into(),
458 VariantDef::EnumVariant(it) => it.parent.id.into(),
460 let substs = Substs::type_params(db, generic_def_id);
461 let ty = db.field_types(var_id)[self.id].clone().subst(&substs);
462 Type::new(db, self.parent.module(db).id.krate, var_id, ty)
465 pub fn parent_def(&self, _db: &dyn HirDatabase) -> VariantDef {
470 impl HasVisibility for Field {
471 fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
472 let variant_data = self.parent.variant_data(db);
473 let visibility = &variant_data.fields()[self.id].visibility;
474 let parent_id: hir_def::VariantId = self.parent.into();
475 visibility.resolve(db.upcast(), &parent_id.resolver(db.upcast()))
479 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
481 pub(crate) id: StructId,
485 pub fn module(self, db: &dyn HirDatabase) -> Module {
486 Module { id: self.id.lookup(db.upcast()).container.module(db.upcast()) }
489 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
490 Some(self.module(db).krate())
493 pub fn name(self, db: &dyn HirDatabase) -> Name {
494 db.struct_data(self.id).name.clone()
497 pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
498 db.struct_data(self.id)
502 .map(|(id, _)| Field { parent: self.into(), id })
506 pub fn ty(self, db: &dyn HirDatabase) -> Type {
507 Type::from_def(db, self.id.lookup(db.upcast()).container.module(db.upcast()).krate, self.id)
510 pub fn repr(self, db: &dyn HirDatabase) -> Option<ReprKind> {
511 db.struct_data(self.id).repr.clone()
514 fn variant_data(self, db: &dyn HirDatabase) -> Arc<VariantData> {
515 db.struct_data(self.id).variant_data.clone()
519 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
521 pub(crate) id: UnionId,
525 pub fn name(self, db: &dyn HirDatabase) -> Name {
526 db.union_data(self.id).name.clone()
529 pub fn module(self, db: &dyn HirDatabase) -> Module {
530 Module { id: self.id.lookup(db.upcast()).container.module(db.upcast()) }
533 pub fn ty(self, db: &dyn HirDatabase) -> Type {
534 Type::from_def(db, self.id.lookup(db.upcast()).container.module(db.upcast()).krate, self.id)
537 pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
538 db.union_data(self.id)
542 .map(|(id, _)| Field { parent: self.into(), id })
546 fn variant_data(self, db: &dyn HirDatabase) -> Arc<VariantData> {
547 db.union_data(self.id).variant_data.clone()
551 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
553 pub(crate) id: EnumId,
557 pub fn module(self, db: &dyn HirDatabase) -> Module {
558 Module { id: self.id.lookup(db.upcast()).container.module(db.upcast()) }
561 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
562 Some(self.module(db).krate())
565 pub fn name(self, db: &dyn HirDatabase) -> Name {
566 db.enum_data(self.id).name.clone()
569 pub fn variants(self, db: &dyn HirDatabase) -> Vec<EnumVariant> {
570 db.enum_data(self.id)
573 .map(|(id, _)| EnumVariant { parent: self, id })
577 pub fn ty(self, db: &dyn HirDatabase) -> Type {
578 Type::from_def(db, self.id.lookup(db.upcast()).container.module(db.upcast()).krate, self.id)
582 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
583 pub struct EnumVariant {
584 pub(crate) parent: Enum,
585 pub(crate) id: LocalEnumVariantId,
589 pub fn module(self, db: &dyn HirDatabase) -> Module {
590 self.parent.module(db)
592 pub fn parent_enum(self, _db: &dyn HirDatabase) -> Enum {
596 pub fn name(self, db: &dyn HirDatabase) -> Name {
597 db.enum_data(self.parent.id).variants[self.id].name.clone()
600 pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
601 self.variant_data(db)
604 .map(|(id, _)| Field { parent: self.into(), id })
608 pub fn kind(self, db: &dyn HirDatabase) -> StructKind {
609 self.variant_data(db).kind()
612 pub(crate) fn variant_data(self, db: &dyn HirDatabase) -> Arc<VariantData> {
613 db.enum_data(self.parent.id).variants[self.id].variant_data.clone()
618 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
624 impl_from!(Struct, Union, Enum for Adt);
627 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
628 let subst = db.generic_defaults(self.into());
629 subst.iter().any(|ty| &ty.value == &Ty::Unknown)
632 /// Turns this ADT into a type. Any type parameters of the ADT will be
633 /// turned into unknown types, which is good for e.g. finding the most
634 /// general set of completions, but will not look very nice when printed.
635 pub fn ty(self, db: &dyn HirDatabase) -> Type {
636 let id = AdtId::from(self);
637 Type::from_def(db, id.module(db.upcast()).krate, id)
640 pub fn module(self, db: &dyn HirDatabase) -> Module {
642 Adt::Struct(s) => s.module(db),
643 Adt::Union(s) => s.module(db),
644 Adt::Enum(e) => e.module(db),
648 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
649 Some(self.module(db).krate())
652 pub fn name(self, db: &dyn HirDatabase) -> Name {
654 Adt::Struct(s) => s.name(db),
655 Adt::Union(u) => u.name(db),
656 Adt::Enum(e) => e.name(db),
661 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
662 pub enum VariantDef {
665 EnumVariant(EnumVariant),
667 impl_from!(Struct, Union, EnumVariant for VariantDef);
670 pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
672 VariantDef::Struct(it) => it.fields(db),
673 VariantDef::Union(it) => it.fields(db),
674 VariantDef::EnumVariant(it) => it.fields(db),
678 pub fn module(self, db: &dyn HirDatabase) -> Module {
680 VariantDef::Struct(it) => it.module(db),
681 VariantDef::Union(it) => it.module(db),
682 VariantDef::EnumVariant(it) => it.module(db),
686 pub fn name(&self, db: &dyn HirDatabase) -> Name {
688 VariantDef::Struct(s) => s.name(db),
689 VariantDef::Union(u) => u.name(db),
690 VariantDef::EnumVariant(e) => e.name(db),
694 pub(crate) fn variant_data(self, db: &dyn HirDatabase) -> Arc<VariantData> {
696 VariantDef::Struct(it) => it.variant_data(db),
697 VariantDef::Union(it) => it.variant_data(db),
698 VariantDef::EnumVariant(it) => it.variant_data(db),
703 /// The defs which have a body.
704 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
705 pub enum DefWithBody {
710 impl_from!(Function, Const, Static for DefWithBody);
713 pub fn module(self, db: &dyn HirDatabase) -> Module {
715 DefWithBody::Const(c) => c.module(db),
716 DefWithBody::Function(f) => f.module(db),
717 DefWithBody::Static(s) => s.module(db),
721 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
723 DefWithBody::Function(f) => Some(f.name(db)),
724 DefWithBody::Static(s) => s.name(db),
725 DefWithBody::Const(c) => c.name(db),
730 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
731 pub struct Function {
732 pub(crate) id: FunctionId,
736 pub fn module(self, db: &dyn HirDatabase) -> Module {
737 self.id.lookup(db.upcast()).module(db.upcast()).into()
740 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
741 Some(self.module(db).krate())
744 pub fn name(self, db: &dyn HirDatabase) -> Name {
745 db.function_data(self.id).name.clone()
748 pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> {
749 if !db.function_data(self.id).has_self_param {
752 Some(SelfParam { func: self.id })
755 pub fn assoc_fn_params(self, db: &dyn HirDatabase) -> Vec<Param> {
756 let resolver = self.id.resolver(db.upcast());
757 let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
758 let environment = TraitEnvironment::lower(db, &resolver);
759 db.function_data(self.id)
764 krate: self.id.lookup(db.upcast()).container.module(db.upcast()).krate,
766 value: Ty::from_hir_ext(&ctx, type_ref).0,
767 environment: environment.clone(),
774 pub fn method_params(self, db: &dyn HirDatabase) -> Option<Vec<Param>> {
775 if self.self_param(db).is_none() {
778 let mut res = self.assoc_fn_params(db);
783 pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool {
784 db.function_data(self.id).is_unsafe
787 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
788 let krate = self.module(db).id.krate;
789 hir_def::diagnostics::validate_body(db.upcast(), self.id.into(), sink);
790 hir_ty::diagnostics::validate_module_item(db, krate, self.id.into(), sink);
791 hir_ty::diagnostics::validate_body(db, self.id.into(), sink);
794 /// Whether this function declaration has a definition.
796 /// This is false in the case of required (not provided) trait methods.
797 pub fn has_body(self, db: &dyn HirDatabase) -> bool {
798 db.function_data(self.id).has_body
802 // Note: logically, this belongs to `hir_ty`, but we are not using it there yet.
809 impl From<Mutability> for Access {
810 fn from(mutability: Mutability) -> Access {
812 Mutability::Shared => Access::Shared,
813 Mutability::Mut => Access::Exclusive,
824 pub fn ty(&self) -> &Type {
829 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
830 pub struct SelfParam {
835 pub fn access(self, db: &dyn HirDatabase) -> Access {
836 let func_data = db.function_data(self.func);
840 .map(|param| match *param {
841 TypeRef::Reference(.., mutability) => mutability.into(),
844 .unwrap_or(Access::Owned)
848 impl HasVisibility for Function {
849 fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
850 let function_data = db.function_data(self.id);
851 let visibility = &function_data.visibility;
852 visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
856 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
858 pub(crate) id: ConstId,
862 pub fn module(self, db: &dyn HirDatabase) -> Module {
863 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) }
866 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
867 Some(self.module(db).krate())
870 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
871 db.const_data(self.id).name.clone()
875 impl HasVisibility for Const {
876 fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
877 let function_data = db.const_data(self.id);
878 let visibility = &function_data.visibility;
879 visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
883 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
885 pub(crate) id: StaticId,
889 pub fn module(self, db: &dyn HirDatabase) -> Module {
890 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) }
893 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
894 Some(self.module(db).krate())
897 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
898 db.static_data(self.id).name.clone()
901 pub fn is_mut(self, db: &dyn HirDatabase) -> bool {
902 db.static_data(self.id).mutable
906 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
908 pub(crate) id: TraitId,
912 pub fn module(self, db: &dyn HirDatabase) -> Module {
913 Module { id: self.id.lookup(db.upcast()).container.module(db.upcast()) }
916 pub fn name(self, db: &dyn HirDatabase) -> Name {
917 db.trait_data(self.id).name.clone()
920 pub fn items(self, db: &dyn HirDatabase) -> Vec<AssocItem> {
921 db.trait_data(self.id).items.iter().map(|(_name, it)| (*it).into()).collect()
924 pub fn is_auto(self, db: &dyn HirDatabase) -> bool {
925 db.trait_data(self.id).auto
929 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
930 pub struct TypeAlias {
931 pub(crate) id: TypeAliasId,
935 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
936 let subst = db.generic_defaults(self.id.into());
937 subst.iter().any(|ty| &ty.value == &Ty::Unknown)
940 pub fn module(self, db: &dyn HirDatabase) -> Module {
941 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) }
944 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
945 Some(self.module(db).krate())
948 pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> {
949 db.type_alias_data(self.id).type_ref.clone()
952 pub fn ty(self, db: &dyn HirDatabase) -> Type {
953 Type::from_def(db, self.id.lookup(db.upcast()).module(db.upcast()).krate, self.id)
956 pub fn name(self, db: &dyn HirDatabase) -> Name {
957 db.type_alias_data(self.id).name.clone()
961 impl HasVisibility for TypeAlias {
962 fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
963 let function_data = db.type_alias_data(self.id);
964 let visibility = &function_data.visibility;
965 visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
969 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
970 pub struct MacroDef {
971 pub(crate) id: MacroDefId,
975 /// FIXME: right now, this just returns the root module of the crate that
976 /// defines this macro. The reasons for this is that macros are expanded
977 /// early, in `hir_expand`, where modules simply do not exist yet.
978 pub fn module(self, db: &dyn HirDatabase) -> Option<Module> {
979 let krate = self.id.krate;
980 let module_id = db.crate_def_map(krate).root;
981 Some(Module::new(Crate { id: krate }, module_id))
984 /// XXX: this parses the file
985 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
986 self.source(db).value.name().map(|it| it.as_name())
989 /// Indicate it is a proc-macro
990 pub fn is_proc_macro(&self) -> bool {
991 matches!(self.id.kind, MacroDefKind::ProcMacro(_))
994 /// Indicate it is a derive macro
995 pub fn is_derive_macro(&self) -> bool {
996 matches!(self.id.kind, MacroDefKind::ProcMacro(_) | MacroDefKind::BuiltInDerive(_))
1000 /// Invariant: `inner.as_assoc_item(db).is_some()`
1001 /// We do not actively enforce this invariant.
1002 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1003 pub enum AssocItem {
1006 TypeAlias(TypeAlias),
1008 pub enum AssocItemContainer {
1012 pub trait AsAssocItem {
1013 fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem>;
1016 impl AsAssocItem for Function {
1017 fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem> {
1018 as_assoc_item(db, AssocItem::Function, self.id)
1021 impl AsAssocItem for Const {
1022 fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem> {
1023 as_assoc_item(db, AssocItem::Const, self.id)
1026 impl AsAssocItem for TypeAlias {
1027 fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem> {
1028 as_assoc_item(db, AssocItem::TypeAlias, self.id)
1031 fn as_assoc_item<ID, DEF, CTOR, AST>(db: &dyn HirDatabase, ctor: CTOR, id: ID) -> Option<AssocItem>
1033 ID: Lookup<Data = AssocItemLoc<AST>>,
1035 CTOR: FnOnce(DEF) -> AssocItem,
1038 match id.lookup(db.upcast()).container {
1039 AssocContainerId::TraitId(_) | AssocContainerId::ImplId(_) => Some(ctor(DEF::from(id))),
1040 AssocContainerId::ContainerId(_) => None,
1045 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
1047 AssocItem::Function(it) => Some(it.name(db)),
1048 AssocItem::Const(it) => it.name(db),
1049 AssocItem::TypeAlias(it) => Some(it.name(db)),
1052 pub fn module(self, db: &dyn HirDatabase) -> Module {
1054 AssocItem::Function(f) => f.module(db),
1055 AssocItem::Const(c) => c.module(db),
1056 AssocItem::TypeAlias(t) => t.module(db),
1059 pub fn container(self, db: &dyn HirDatabase) -> AssocItemContainer {
1060 let container = match self {
1061 AssocItem::Function(it) => it.id.lookup(db.upcast()).container,
1062 AssocItem::Const(it) => it.id.lookup(db.upcast()).container,
1063 AssocItem::TypeAlias(it) => it.id.lookup(db.upcast()).container,
1066 AssocContainerId::TraitId(id) => AssocItemContainer::Trait(id.into()),
1067 AssocContainerId::ImplId(id) => AssocItemContainer::Impl(id.into()),
1068 AssocContainerId::ContainerId(_) => panic!("invalid AssocItem"),
1073 impl HasVisibility for AssocItem {
1074 fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
1076 AssocItem::Function(f) => f.visibility(db),
1077 AssocItem::Const(c) => c.visibility(db),
1078 AssocItem::TypeAlias(t) => t.visibility(db),
1083 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
1084 pub enum GenericDef {
1088 TypeAlias(TypeAlias),
1090 // enum variants cannot have generics themselves, but their parent enums
1091 // can, and this makes some code easier to write
1092 EnumVariant(EnumVariant),
1093 // consts can have type parameters from their parents (i.e. associated consts of traits)
1098 Adt(Struct, Enum, Union),
1108 pub fn params(self, db: &dyn HirDatabase) -> Vec<GenericParam> {
1109 let generics = db.generic_params(self.into());
1110 let ty_params = generics
1113 .map(|(local_id, _)| TypeParam { id: TypeParamId { parent: self.into(), local_id } })
1114 .map(GenericParam::TypeParam);
1115 let lt_params = generics
1118 .map(|(local_id, _)| LifetimeParam {
1119 id: LifetimeParamId { parent: self.into(), local_id },
1121 .map(GenericParam::LifetimeParam);
1122 ty_params.chain(lt_params).collect()
1125 pub fn type_params(self, db: &dyn HirDatabase) -> Vec<TypeParam> {
1126 let generics = db.generic_params(self.into());
1130 .map(|(local_id, _)| TypeParam { id: TypeParamId { parent: self.into(), local_id } })
1135 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1137 pub(crate) parent: DefWithBodyId,
1138 pub(crate) pat_id: PatId,
1142 pub fn is_param(self, db: &dyn HirDatabase) -> bool {
1143 let src = self.source(db);
1145 Either::Left(bind_pat) => {
1146 bind_pat.syntax().ancestors().any(|it| ast::Param::can_cast(it.kind()))
1148 Either::Right(_self_param) => true,
1152 // FIXME: why is this an option? It shouldn't be?
1153 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
1154 let body = db.body(self.parent.into());
1155 match &body[self.pat_id] {
1156 Pat::Bind { name, .. } => Some(name.clone()),
1161 pub fn is_self(self, db: &dyn HirDatabase) -> bool {
1162 self.name(db) == Some(name![self])
1165 pub fn is_mut(self, db: &dyn HirDatabase) -> bool {
1166 let body = db.body(self.parent.into());
1167 match &body[self.pat_id] {
1168 Pat::Bind { mode, .. } => match mode {
1169 BindingAnnotation::Mutable | BindingAnnotation::RefMut => true,
1176 pub fn parent(self, _db: &dyn HirDatabase) -> DefWithBody {
1180 pub fn module(self, db: &dyn HirDatabase) -> Module {
1181 self.parent(db).module(db)
1184 pub fn ty(self, db: &dyn HirDatabase) -> Type {
1185 let def = DefWithBodyId::from(self.parent);
1186 let infer = db.infer(def);
1187 let ty = infer[self.pat_id].clone();
1188 let krate = def.module(db.upcast()).krate;
1189 Type::new(db, krate, def, ty)
1192 pub fn source(self, db: &dyn HirDatabase) -> InFile<Either<ast::IdentPat, ast::SelfParam>> {
1193 let (_body, source_map) = db.body_with_source_map(self.parent.into());
1194 let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm...
1195 let root = src.file_syntax(db.upcast());
1197 ast.map_left(|it| it.cast().unwrap().to_node(&root)).map_right(|it| it.to_node(&root))
1202 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1203 pub enum GenericParam {
1204 TypeParam(TypeParam),
1205 LifetimeParam(LifetimeParam),
1207 impl_from!(TypeParam, LifetimeParam for GenericParam);
1209 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1210 pub struct TypeParam {
1211 pub(crate) id: TypeParamId,
1215 pub fn name(self, db: &dyn HirDatabase) -> Name {
1216 let params = db.generic_params(self.id.parent);
1217 params.types[self.id.local_id].name.clone().unwrap_or_else(Name::missing)
1220 pub fn module(self, db: &dyn HirDatabase) -> Module {
1221 self.id.parent.module(db.upcast()).into()
1224 pub fn ty(self, db: &dyn HirDatabase) -> Type {
1225 let resolver = self.id.parent.resolver(db.upcast());
1226 let environment = TraitEnvironment::lower(db, &resolver);
1227 let ty = Ty::Placeholder(self.id);
1229 krate: self.id.parent.module(db.upcast()).krate,
1230 ty: InEnvironment { value: ty, environment },
1234 pub fn default(self, db: &dyn HirDatabase) -> Option<Type> {
1235 let params = db.generic_defaults(self.id.parent);
1236 let local_idx = hir_ty::param_idx(db, self.id)?;
1237 let resolver = self.id.parent.resolver(db.upcast());
1238 let environment = TraitEnvironment::lower(db, &resolver);
1239 let ty = params.get(local_idx)?.clone();
1240 let subst = Substs::type_params(db, self.id.parent);
1241 let ty = ty.subst(&subst.prefix(local_idx));
1243 krate: self.id.parent.module(db.upcast()).krate,
1244 ty: InEnvironment { value: ty, environment },
1249 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1250 pub struct LifetimeParam {
1251 pub(crate) id: LifetimeParamId,
1254 impl LifetimeParam {
1255 pub fn name(self, db: &dyn HirDatabase) -> Name {
1256 let params = db.generic_params(self.id.parent);
1257 params.lifetimes[self.id.local_id].name.clone()
1260 pub fn module(self, db: &dyn HirDatabase) -> Module {
1261 self.id.parent.module(db.upcast()).into()
1264 pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef {
1265 self.id.parent.into()
1269 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1271 pub(crate) id: ImplId,
1275 pub fn all_in_crate(db: &dyn HirDatabase, krate: Crate) -> Vec<Impl> {
1276 let inherent = db.inherent_impls_in_crate(krate.id);
1277 let trait_ = db.trait_impls_in_crate(krate.id);
1279 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect()
1281 pub fn for_trait(db: &dyn HirDatabase, krate: Crate, trait_: Trait) -> Vec<Impl> {
1282 let impls = db.trait_impls_in_crate(krate.id);
1283 impls.for_trait(trait_.id).map(Self::from).collect()
1286 pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> {
1287 db.impl_data(self.id).target_trait.clone()
1290 pub fn target_type(self, db: &dyn HirDatabase) -> TypeRef {
1291 db.impl_data(self.id).target_type.clone()
1294 pub fn target_ty(self, db: &dyn HirDatabase) -> Type {
1295 let impl_data = db.impl_data(self.id);
1296 let resolver = self.id.resolver(db.upcast());
1297 let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
1298 let environment = TraitEnvironment::lower(db, &resolver);
1299 let ty = Ty::from_hir(&ctx, &impl_data.target_type);
1301 krate: self.id.lookup(db.upcast()).container.module(db.upcast()).krate,
1302 ty: InEnvironment { value: ty, environment },
1306 pub fn items(self, db: &dyn HirDatabase) -> Vec<AssocItem> {
1307 db.impl_data(self.id).items.iter().map(|it| (*it).into()).collect()
1310 pub fn is_negative(self, db: &dyn HirDatabase) -> bool {
1311 db.impl_data(self.id).is_negative
1314 pub fn module(self, db: &dyn HirDatabase) -> Module {
1315 self.id.lookup(db.upcast()).container.module(db.upcast()).into()
1318 pub fn krate(self, db: &dyn HirDatabase) -> Crate {
1319 Crate { id: self.module(db).id.krate }
1322 pub fn is_builtin_derive(self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>> {
1323 let src = self.source(db);
1324 let item = src.file_id.is_builtin_derive(db.upcast())?;
1325 let hygenic = hir_expand::hygiene::Hygiene::new(db.upcast(), item.file_id);
1331 let path = ModPath::from_src(it.path()?, &hygenic)?;
1332 if path.as_ident()?.to_string() == "derive" {
1340 Some(item.with_value(attr))
1344 #[derive(Clone, PartialEq, Eq, Debug)]
1347 ty: InEnvironment<Ty>,
1351 pub(crate) fn new_with_resolver(
1352 db: &dyn HirDatabase,
1353 resolver: &Resolver,
1356 let krate = resolver.krate()?;
1357 Some(Type::new_with_resolver_inner(db, krate, resolver, ty))
1359 pub(crate) fn new_with_resolver_inner(
1360 db: &dyn HirDatabase,
1362 resolver: &Resolver,
1365 let environment = TraitEnvironment::lower(db, &resolver);
1366 Type { krate, ty: InEnvironment { value: ty, environment } }
1369 fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type {
1370 let resolver = lexical_env.resolver(db.upcast());
1371 let environment = TraitEnvironment::lower(db, &resolver);
1372 Type { krate, ty: InEnvironment { value: ty, environment } }
1376 db: &dyn HirDatabase,
1378 def: impl HasResolver + Into<TyDefId> + Into<GenericDefId>,
1380 let substs = Substs::build_for_def(db, def).fill_with_unknown().build();
1381 let ty = db.ty(def.into()).subst(&substs);
1382 Type::new(db, krate, def, ty)
1385 pub fn is_unit(&self) -> bool {
1388 Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { cardinality: 0 }, .. })
1391 pub fn is_bool(&self) -> bool {
1392 matches!(self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }))
1395 pub fn is_mutable_reference(&self) -> bool {
1398 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(Mutability::Mut), .. })
1402 pub fn remove_ref(&self) -> Option<Type> {
1403 if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_), .. }) = self.ty.value {
1404 self.ty.value.substs().map(|substs| self.derived(substs[0].clone()))
1410 pub fn is_unknown(&self) -> bool {
1411 matches!(self.ty.value, Ty::Unknown)
1414 /// Checks that particular type `ty` implements `std::future::Future`.
1415 /// This function is used in `.await` syntax completion.
1416 pub fn impls_future(&self, db: &dyn HirDatabase) -> bool {
1417 // No special case for the type of async block, since Chalk can figure it out.
1419 let krate = self.krate;
1421 let std_future_trait =
1422 db.lang_item(krate, "future_trait".into()).and_then(|it| it.as_trait());
1423 let std_future_trait = match std_future_trait {
1425 None => return false,
1428 let canonical_ty = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) };
1429 method_resolution::implements_trait(
1432 self.ty.environment.clone(),
1438 /// Checks that particular type `ty` implements `std::ops::FnOnce`.
1440 /// This function can be used to check if a particular type is callable, since FnOnce is a
1441 /// supertrait of Fn and FnMut, so all callable types implements at least FnOnce.
1442 pub fn impls_fnonce(&self, db: &dyn HirDatabase) -> bool {
1443 let krate = self.krate;
1445 let fnonce_trait = match FnTrait::FnOnce.get_id(db, krate) {
1447 None => return false,
1450 let canonical_ty = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) };
1451 method_resolution::implements_trait_unique(
1454 self.ty.environment.clone(),
1460 pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool {
1461 let trait_ref = hir_ty::TraitRef {
1463 substs: Substs::build_for_def(db, trait_.id)
1464 .push(self.ty.value.clone())
1465 .fill(args.iter().map(|t| t.ty.value.clone()))
1469 let goal = Canonical {
1470 value: hir_ty::InEnvironment::new(
1471 self.ty.environment.clone(),
1472 hir_ty::Obligation::Trait(trait_ref),
1474 kinds: Arc::new([]),
1477 db.trait_solve(self.krate, goal).is_some()
1480 pub fn normalize_trait_assoc_type(
1482 db: &dyn HirDatabase,
1487 let subst = Substs::build_for_def(db, trait_.id)
1488 .push(self.ty.value.clone())
1489 .fill(args.iter().map(|t| t.ty.value.clone()))
1491 let predicate = ProjectionPredicate {
1492 projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst },
1493 ty: Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)),
1495 let goal = Canonical {
1496 value: InEnvironment::new(
1497 self.ty.environment.clone(),
1498 Obligation::Projection(predicate),
1500 kinds: Arc::new([TyKind::General]),
1503 match db.trait_solve(self.krate, goal)? {
1504 Solution::Unique(SolutionVariables(subst)) => subst.value.first().cloned(),
1505 Solution::Ambig(_) => None,
1509 ty: InEnvironment { value: ty, environment: Arc::clone(&self.ty.environment) },
1513 pub fn is_copy(&self, db: &dyn HirDatabase) -> bool {
1514 let lang_item = db.lang_item(self.krate, SmolStr::new("copy"));
1515 let copy_trait = match lang_item {
1516 Some(LangItemTarget::TraitId(it)) => it,
1519 self.impls_trait(db, copy_trait.into(), &[])
1522 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> {
1523 let def = match self.ty.value {
1524 Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(def), parameters: _ }) => Some(def),
1528 let sig = self.ty.value.callable_sig(db)?;
1529 Some(Callable { ty: self.clone(), sig, def, is_bound_method: false })
1532 pub fn is_closure(&self) -> bool {
1533 matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { .. }, .. }))
1536 pub fn is_fn(&self) -> bool {
1537 matches!(&self.ty.value,
1538 Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(..), .. }) |
1539 Ty::Apply(ApplicationTy { ctor: TypeCtor::FnPtr { .. }, .. })
1543 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool {
1544 let adt_id = match self.ty.value {
1545 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_id), .. }) => adt_id,
1549 let adt = adt_id.into();
1551 Adt::Struct(s) => matches!(s.repr(db), Some(ReprKind::Packed)),
1556 pub fn is_raw_ptr(&self) -> bool {
1557 matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(..), .. }))
1560 pub fn contains_unknown(&self) -> bool {
1561 return go(&self.ty.value);
1563 fn go(ty: &Ty) -> bool {
1565 Ty::Unknown => true,
1566 Ty::Apply(a_ty) => a_ty.parameters.iter().any(go),
1572 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
1573 if let Ty::Apply(a_ty) = &self.ty.value {
1574 let variant_id = match a_ty.ctor {
1575 TypeCtor::Adt(AdtId::StructId(s)) => s.into(),
1576 TypeCtor::Adt(AdtId::UnionId(u)) => u.into(),
1577 _ => return Vec::new(),
1581 .field_types(variant_id)
1583 .map(|(local_id, ty)| {
1584 let def = Field { parent: variant_id.into(), id: local_id };
1585 let ty = ty.clone().subst(&a_ty.parameters);
1586 (def, self.derived(ty))
1593 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> {
1594 let mut res = Vec::new();
1595 if let Ty::Apply(a_ty) = &self.ty.value {
1596 if let TypeCtor::Tuple { .. } = a_ty.ctor {
1597 for ty in a_ty.parameters.iter() {
1598 let ty = ty.clone();
1599 res.push(self.derived(ty));
1606 pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a {
1607 // There should be no inference vars in types passed here
1608 // FIXME check that?
1609 let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) };
1610 let environment = self.ty.environment.clone();
1611 let ty = InEnvironment { value: canonical, environment };
1612 autoderef(db, Some(self.krate), ty)
1613 .map(|canonical| canonical.value)
1614 .map(move |ty| self.derived(ty))
1617 // This would be nicer if it just returned an iterator, but that runs into
1618 // lifetime problems, because we need to borrow temp `CrateImplDefs`.
1619 pub fn iterate_assoc_items<T>(
1621 db: &dyn HirDatabase,
1623 mut callback: impl FnMut(AssocItem) -> Option<T>,
1625 for krate in self.ty.value.def_crates(db, krate.id)? {
1626 let impls = db.inherent_impls_in_crate(krate);
1628 for impl_def in impls.for_self_ty(&self.ty.value) {
1629 for &item in db.impl_data(*impl_def).items.iter() {
1630 if let Some(result) = callback(item.into()) {
1631 return Some(result);
1639 pub fn iterate_method_candidates<T>(
1641 db: &dyn HirDatabase,
1643 traits_in_scope: &FxHashSet<TraitId>,
1644 name: Option<&Name>,
1645 mut callback: impl FnMut(&Ty, Function) -> Option<T>,
1647 // There should be no inference vars in types passed here
1648 // FIXME check that?
1649 // FIXME replace Unknown by bound vars here
1650 let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) };
1652 let env = self.ty.environment.clone();
1653 let krate = krate.id;
1655 method_resolution::iterate_method_candidates(
1662 method_resolution::LookupMode::MethodCall,
1664 AssocItemId::FunctionId(f) => callback(ty, f.into()),
1670 pub fn iterate_path_candidates<T>(
1672 db: &dyn HirDatabase,
1674 traits_in_scope: &FxHashSet<TraitId>,
1675 name: Option<&Name>,
1676 mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>,
1678 // There should be no inference vars in types passed here
1679 // FIXME check that?
1680 // FIXME replace Unknown by bound vars here
1681 let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) };
1683 let env = self.ty.environment.clone();
1684 let krate = krate.id;
1686 method_resolution::iterate_method_candidates(
1693 method_resolution::LookupMode::Path,
1694 |ty, it| callback(ty, it.into()),
1698 pub fn as_adt(&self) -> Option<Adt> {
1699 let (adt, _subst) = self.ty.value.as_adt()?;
1703 pub fn as_dyn_trait(&self) -> Option<Trait> {
1704 self.ty.value.dyn_trait().map(Into::into)
1707 pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> {
1708 self.ty.value.impl_trait_bounds(db).map(|it| {
1710 .filter_map(|pred| match pred {
1711 hir_ty::GenericPredicate::Implemented(trait_ref) => {
1712 Some(Trait::from(trait_ref.trait_))
1720 pub fn as_associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<Trait> {
1721 self.ty.value.associated_type_parent_trait(db).map(Into::into)
1724 // FIXME: provide required accessors such that it becomes implementable from outside.
1725 pub fn is_equal_for_find_impls(&self, other: &Type) -> bool {
1726 match (&self.ty.value, &other.ty.value) {
1727 (Ty::Apply(a_original_ty), Ty::Apply(ApplicationTy { ctor, parameters })) => match ctor
1729 TypeCtor::Ref(..) => match parameters.as_single() {
1730 Ty::Apply(a_ty) => a_original_ty.ctor == a_ty.ctor,
1733 _ => a_original_ty.ctor == *ctor,
1739 fn derived(&self, ty: Ty) -> Type {
1742 ty: InEnvironment { value: ty, environment: self.ty.environment.clone() },
1746 pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) {
1747 // TypeWalk::walk for a Ty at first visits parameters and only after that the Ty itself.
1748 // We need a different order here.
1751 db: &dyn HirDatabase,
1754 cb: &mut impl FnMut(Type),
1756 for ty in substs.iter() {
1757 walk_type(db, &type_.derived(ty.clone()), cb);
1762 db: &dyn HirDatabase,
1764 bounds: &[GenericPredicate],
1765 cb: &mut impl FnMut(Type),
1767 for pred in bounds {
1769 GenericPredicate::Implemented(trait_ref) => {
1771 walk_substs(db, type_, &trait_ref.substs, cb);
1778 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
1779 let ty = type_.ty.value.strip_references();
1781 Ty::Apply(ApplicationTy { ctor, parameters }) => {
1783 TypeCtor::Adt(_) => {
1784 cb(type_.derived(ty.clone()));
1786 TypeCtor::AssociatedType(_) => {
1787 if let Some(_) = ty.associated_type_parent_trait(db) {
1788 cb(type_.derived(ty.clone()));
1791 TypeCtor::OpaqueType(..) => {
1792 if let Some(bounds) = ty.impl_trait_bounds(db) {
1793 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1799 // adt params, tuples, etc...
1800 walk_substs(db, type_, parameters, cb);
1802 Ty::Opaque(opaque_ty) => {
1803 if let Some(bounds) = ty.impl_trait_bounds(db) {
1804 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1807 walk_substs(db, type_, &opaque_ty.parameters, cb);
1809 Ty::Placeholder(_) => {
1810 if let Some(bounds) = ty.impl_trait_bounds(db) {
1811 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1814 Ty::Dyn(bounds) => {
1815 walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb);
1822 walk_type(db, self, &mut cb);
1826 impl HirDisplay for Type {
1827 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
1828 self.ty.value.hir_fmt(f)
1834 pub struct Callable {
1837 def: Option<CallableDefId>,
1838 pub(crate) is_bound_method: bool,
1841 pub enum CallableKind {
1843 TupleStruct(Struct),
1844 TupleEnumVariant(EnumVariant),
1849 pub fn kind(&self) -> CallableKind {
1851 Some(CallableDefId::FunctionId(it)) => CallableKind::Function(it.into()),
1852 Some(CallableDefId::StructId(it)) => CallableKind::TupleStruct(it.into()),
1853 Some(CallableDefId::EnumVariantId(it)) => CallableKind::TupleEnumVariant(it.into()),
1854 None => CallableKind::Closure,
1857 pub fn receiver_param(&self, db: &dyn HirDatabase) -> Option<ast::SelfParam> {
1858 let func = match self.def {
1859 Some(CallableDefId::FunctionId(it)) if self.is_bound_method => it,
1862 let src = func.lookup(db.upcast()).source(db.upcast());
1863 let param_list = src.value.param_list()?;
1864 param_list.self_param()
1866 pub fn n_params(&self) -> usize {
1867 self.sig.params().len() - if self.is_bound_method { 1 } else { 0 }
1871 db: &dyn HirDatabase,
1872 ) -> Vec<(Option<Either<ast::SelfParam, ast::Pat>>, Type)> {
1877 .skip(if self.is_bound_method { 1 } else { 0 })
1878 .map(|ty| self.ty.derived(ty.clone()));
1879 let patterns = match self.def {
1880 Some(CallableDefId::FunctionId(func)) => {
1881 let src = func.lookup(db.upcast()).source(db.upcast());
1882 src.value.param_list().map(|param_list| {
1885 .map(|it| Some(Either::Left(it)))
1886 .filter(|_| !self.is_bound_method)
1888 .chain(param_list.params().map(|it| it.pat().map(Either::Right)))
1893 patterns.into_iter().flatten().chain(iter::repeat(None)).zip(types).collect()
1895 pub fn return_type(&self) -> Type {
1896 self.ty.derived(self.sig.ret().clone())
1903 ModuleDef(ModuleDef),
1905 GenericParam(TypeParam),
1913 pub fn all_items(def: PerNs) -> ArrayVec<[Self; 3]> {
1914 let mut items = ArrayVec::new();
1916 match (def.take_types(), def.take_values()) {
1917 (Some(m1), None) => items.push(ScopeDef::ModuleDef(m1.into())),
1918 (None, Some(m2)) => items.push(ScopeDef::ModuleDef(m2.into())),
1919 (Some(m1), Some(m2)) => {
1920 // Some items, like unit structs and enum variants, are
1921 // returned as both a type and a value. Here we want
1922 // to de-duplicate them.
1924 items.push(ScopeDef::ModuleDef(m1.into()));
1925 items.push(ScopeDef::ModuleDef(m2.into()));
1927 items.push(ScopeDef::ModuleDef(m1.into()));
1933 if let Some(macro_def_id) = def.take_macros() {
1934 items.push(ScopeDef::MacroDef(macro_def_id.into()));
1937 if items.is_empty() {
1938 items.push(ScopeDef::Unknown);
1945 pub trait HasVisibility {
1946 fn visibility(&self, db: &dyn HirDatabase) -> Visibility;
1947 fn is_visible_from(&self, db: &dyn HirDatabase, module: Module) -> bool {
1948 let vis = self.visibility(db);
1949 vis.is_visible_from(db.upcast(), module.id)