1 //! FIXME: write short doc here
10 body::{Body, BodySourceMap},
11 builtin_type::BuiltinType,
13 expr::{BindingAnnotation, Pat, PatId},
15 resolver::HasResolver,
16 type_ref::{Mutability, TypeRef},
17 AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId,
18 HasModule, ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId,
19 Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId,
22 diagnostics::DiagnosticSink,
26 use hir_ty::expr::ExprValidator;
27 use ra_db::{CrateId, Edition, FileId, FilePosition};
28 use ra_syntax::{ast, AstNode, SyntaxNode};
31 db::{DefDatabase, HirDatabase},
32 ty::display::HirFormatter,
33 ty::{self, InEnvironment, InferenceResult, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk},
34 CallableDef, HirDisplay, InFile, Name,
37 /// hir::Crate describes a single crate. It's the main interface with which
38 /// a crate's dependencies interact. Mostly, it should be just a proxy for the
40 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
42 pub(crate) crate_id: CrateId,
46 pub struct CrateDependency {
52 pub fn crate_id(self) -> CrateId {
56 pub fn dependencies(self, db: &impl DefDatabase) -> Vec<CrateDependency> {
58 .dependencies(self.crate_id)
60 let krate = Crate { crate_id: dep.crate_id() };
61 let name = dep.as_name();
62 CrateDependency { krate, name }
67 pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> {
68 let module_id = db.crate_def_map(self.crate_id).root;
69 Some(Module::new(self, module_id))
72 pub fn edition(self, db: &impl DefDatabase) -> Edition {
73 let crate_graph = db.crate_graph();
74 crate_graph.edition(self.crate_id)
77 pub fn all(db: &impl DefDatabase) -> Vec<Crate> {
78 db.crate_graph().iter().map(|crate_id| Crate { crate_id }).collect()
82 pub enum ModuleSource {
83 SourceFile(ast::SourceFile),
89 db: &impl DefDatabase,
90 file_id: Option<FileId>,
91 decl_id: Option<AstId<ast::Module>>,
93 match (file_id, decl_id) {
94 (Some(file_id), _) => {
95 let source_file = db.parse(file_id).tree();
96 ModuleSource::SourceFile(source_file)
98 (None, Some(item_id)) => {
99 let module = item_id.to_node(db);
100 assert!(module.item_list().is_some(), "expected inline module");
101 ModuleSource::Module(module)
103 (None, None) => panic!(),
107 // FIXME: this methods do not belong here
108 pub fn from_position(db: &impl DefDatabase, position: FilePosition) -> ModuleSource {
109 let parse = db.parse(position.file_id);
110 match &ra_syntax::algo::find_node_at_offset::<ast::Module>(
111 parse.tree().syntax(),
114 Some(m) if !m.has_semi() => ModuleSource::Module(m.clone()),
116 let source_file = parse.tree();
117 ModuleSource::SourceFile(source_file)
122 pub fn from_child_node(db: &impl DefDatabase, child: InFile<&SyntaxNode>) -> ModuleSource {
124 child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi())
126 ModuleSource::Module(m)
128 let file_id = child.file_id.original_file(db);
129 let source_file = db.parse(file_id).tree();
130 ModuleSource::SourceFile(source_file)
134 pub fn from_file_id(db: &impl DefDatabase, file_id: FileId) -> ModuleSource {
135 let source_file = db.parse(file_id).tree();
136 ModuleSource::SourceFile(source_file)
140 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
142 pub(crate) id: ModuleId,
145 /// The defs which can be visible in the module.
146 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
151 // Can't be directly declared, but can be imported.
152 EnumVariant(EnumVariant),
156 TypeAlias(TypeAlias),
157 BuiltinType(BuiltinType),
162 Adt(Struct, Enum, Union),
171 pub use hir_def::attr::Attrs;
174 pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module {
175 Module { id: ModuleId { krate: krate.crate_id, local_id: crate_module_id } }
178 /// Name of this module.
179 pub fn name(self, db: &impl DefDatabase) -> Option<Name> {
180 let def_map = db.crate_def_map(self.id.krate);
181 let parent = def_map[self.id.local_id].parent?;
182 def_map[parent].children.iter().find_map(|(name, module_id)| {
183 if *module_id == self.id.local_id {
191 /// Returns the crate this module is part of.
192 pub fn krate(self) -> Crate {
193 Crate { crate_id: self.id.krate }
196 /// Topmost parent of this module. Every module has a `crate_root`, but some
197 /// might be missing `krate`. This can happen if a module's file is not included
198 /// in the module tree of any target in `Cargo.toml`.
199 pub fn crate_root(self, db: &impl DefDatabase) -> Module {
200 let def_map = db.crate_def_map(self.id.krate);
201 self.with_module_id(def_map.root)
204 /// Finds a child module with the specified name.
205 pub fn child(self, db: &impl DefDatabase, name: &Name) -> Option<Module> {
206 let def_map = db.crate_def_map(self.id.krate);
207 let child_id = def_map[self.id.local_id].children.get(name)?;
208 Some(self.with_module_id(*child_id))
211 /// Iterates over all child modules.
212 pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> {
213 let def_map = db.crate_def_map(self.id.krate);
214 let children = def_map[self.id.local_id]
217 .map(|(_, module_id)| self.with_module_id(*module_id))
218 .collect::<Vec<_>>();
222 /// Finds a parent module.
223 pub fn parent(self, db: &impl DefDatabase) -> Option<Module> {
224 let def_map = db.crate_def_map(self.id.krate);
225 let parent_id = def_map[self.id.local_id].parent?;
226 Some(self.with_module_id(parent_id))
229 pub fn path_to_root(self, db: &impl HirDatabase) -> Vec<Module> {
230 let mut res = vec![self];
232 while let Some(next) = curr.parent(db) {
239 /// Returns a `ModuleScope`: a set of items, visible in this module.
240 pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<Import>)> {
241 db.crate_def_map(self.id.krate)[self.id.local_id]
245 (name.clone(), res.def.into(), res.import.map(|id| Import { parent: self, id }))
250 pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) {
251 db.crate_def_map(self.id.krate).add_diagnostics(db, self.id.local_id, sink);
252 for decl in self.declarations(db) {
254 crate::ModuleDef::Function(f) => f.diagnostics(db, sink),
255 crate::ModuleDef::Module(m) => {
256 // Only add diagnostics from inline modules
257 if let ModuleSource::Module(_) = m.definition_source(db).value {
258 m.diagnostics(db, sink)
265 for impl_block in self.impl_blocks(db) {
266 for item in impl_block.items(db) {
267 if let AssocItem::Function(f) = item {
268 f.diagnostics(db, sink);
274 pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> {
275 let def_map = db.crate_def_map(self.id.krate);
276 def_map[self.id.local_id].scope.declarations().map(ModuleDef::from).collect()
279 pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> {
280 let def_map = db.crate_def_map(self.id.krate);
281 def_map[self.id.local_id].impls.iter().copied().map(ImplBlock::from).collect()
284 fn with_module_id(self, module_id: LocalModuleId) -> Module {
285 Module::new(self.krate(), module_id)
290 pub(crate) parent: Module,
291 pub(crate) id: LocalImportId,
294 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
295 pub struct StructField {
296 pub(crate) parent: VariantDef,
297 pub(crate) id: LocalStructFieldId,
300 #[derive(Debug, PartialEq, Eq)]
301 pub enum FieldSource {
302 Named(ast::RecordFieldDef),
303 Pos(ast::TupleFieldDef),
307 pub fn name(&self, db: &impl HirDatabase) -> Name {
308 self.parent.variant_data(db).fields()[self.id].name.clone()
311 pub fn ty(&self, db: &impl HirDatabase) -> Ty {
312 db.field_types(self.parent.into())[self.id].clone()
315 pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef {
320 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
322 pub(crate) id: StructId,
326 pub fn module(self, db: &impl DefDatabase) -> Module {
327 Module { id: self.id.module(db) }
330 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
331 Some(self.module(db).krate())
334 pub fn name(self, db: &impl DefDatabase) -> Name {
335 db.struct_data(self.id.into()).name.clone()
338 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
339 db.struct_data(self.id.into())
343 .map(|(id, _)| StructField { parent: self.into(), id })
347 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
348 db.struct_data(self.id.into())
352 .find(|(_id, data)| data.name == *name)
353 .map(|(id, _)| StructField { parent: self.into(), id })
356 pub fn ty(self, db: &impl HirDatabase) -> Type {
357 Type::from_def(db, self.id.module(db).krate, self.id)
360 pub fn constructor_ty(self, db: &impl HirDatabase) -> Ty {
361 db.value_ty(self.id.into())
364 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
365 db.struct_data(self.id.into()).variant_data.clone()
369 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
371 pub(crate) id: UnionId,
375 pub fn name(self, db: &impl DefDatabase) -> Name {
376 db.union_data(self.id).name.clone()
379 pub fn module(self, db: &impl DefDatabase) -> Module {
380 Module { id: self.id.module(db) }
383 pub fn ty(self, db: &impl HirDatabase) -> Type {
384 Type::from_def(db, self.id.module(db).krate, self.id)
387 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
388 db.union_data(self.id)
392 .map(|(id, _)| StructField { parent: self.into(), id })
396 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
397 db.union_data(self.id)
401 .find(|(_id, data)| data.name == *name)
402 .map(|(id, _)| StructField { parent: self.into(), id })
405 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
406 db.union_data(self.id).variant_data.clone()
410 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
412 pub(crate) id: EnumId,
416 pub fn module(self, db: &impl DefDatabase) -> Module {
417 Module { id: self.id.module(db) }
420 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
421 Some(self.module(db).krate())
424 pub fn name(self, db: &impl DefDatabase) -> Name {
425 db.enum_data(self.id).name.clone()
428 pub fn variants(self, db: &impl DefDatabase) -> Vec<EnumVariant> {
429 db.enum_data(self.id)
432 .map(|(id, _)| EnumVariant { parent: self, id })
436 pub fn variant(self, db: &impl DefDatabase, name: &Name) -> Option<EnumVariant> {
437 let id = db.enum_data(self.id).variant(name)?;
438 Some(EnumVariant { parent: self, id })
441 pub fn ty(self, db: &impl HirDatabase) -> Type {
442 Type::from_def(db, self.id.module(db).krate, self.id)
446 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
447 pub struct EnumVariant {
448 pub(crate) parent: Enum,
449 pub(crate) id: LocalEnumVariantId,
453 pub fn module(self, db: &impl HirDatabase) -> Module {
454 self.parent.module(db)
456 pub fn parent_enum(self, _db: &impl DefDatabase) -> Enum {
460 pub fn name(self, db: &impl DefDatabase) -> Name {
461 db.enum_data(self.parent.id).variants[self.id].name.clone()
464 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
465 self.variant_data(db)
468 .map(|(id, _)| StructField { parent: self.into(), id })
472 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
473 self.variant_data(db)
476 .find(|(_id, data)| data.name == *name)
477 .map(|(id, _)| StructField { parent: self.into(), id })
480 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
481 db.enum_data(self.parent.id).variants[self.id].variant_data.clone()
486 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
492 impl_froms!(Adt: Struct, Union, Enum);
495 pub fn has_non_default_type_params(self, db: &impl HirDatabase) -> bool {
496 let subst = db.generic_defaults(self.into());
497 subst.iter().any(|ty| ty == &Ty::Unknown)
499 pub fn ty(self, db: &impl HirDatabase) -> Type {
500 let id = AdtId::from(self);
501 Type::from_def(db, id.module(db).krate, id)
504 pub fn module(self, db: &impl DefDatabase) -> Module {
506 Adt::Struct(s) => s.module(db),
507 Adt::Union(s) => s.module(db),
508 Adt::Enum(e) => e.module(db),
512 pub fn krate(self, db: &impl HirDatabase) -> Option<Crate> {
513 Some(self.module(db).krate())
517 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
518 pub enum VariantDef {
521 EnumVariant(EnumVariant),
523 impl_froms!(VariantDef: Struct, Union, EnumVariant);
526 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
528 VariantDef::Struct(it) => it.fields(db),
529 VariantDef::Union(it) => it.fields(db),
530 VariantDef::EnumVariant(it) => it.fields(db),
534 pub fn module(self, db: &impl HirDatabase) -> Module {
536 VariantDef::Struct(it) => it.module(db),
537 VariantDef::Union(it) => it.module(db),
538 VariantDef::EnumVariant(it) => it.module(db),
542 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
544 VariantDef::Struct(it) => it.variant_data(db),
545 VariantDef::Union(it) => it.variant_data(db),
546 VariantDef::EnumVariant(it) => it.variant_data(db),
551 /// The defs which have a body.
552 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
553 pub enum DefWithBody {
559 impl_froms!(DefWithBody: Function, Const, Static);
562 pub fn module(self, db: &impl HirDatabase) -> Module {
564 DefWithBody::Const(c) => c.module(db),
565 DefWithBody::Function(f) => f.module(db),
566 DefWithBody::Static(s) => s.module(db),
571 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
572 pub struct Function {
573 pub(crate) id: FunctionId,
577 pub fn module(self, db: &impl DefDatabase) -> Module {
578 self.id.lookup(db).module(db).into()
581 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
582 Some(self.module(db).krate())
585 pub fn name(self, db: &impl HirDatabase) -> Name {
586 db.function_data(self.id).name.clone()
589 pub fn has_self_param(self, db: &impl HirDatabase) -> bool {
590 db.function_data(self.id).has_self_param
593 pub fn params(self, db: &impl HirDatabase) -> Vec<TypeRef> {
594 db.function_data(self.id).params.clone()
597 pub fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
598 db.body_with_source_map(self.id.into()).1
601 pub fn body(self, db: &impl HirDatabase) -> Arc<Body> {
602 db.body(self.id.into())
605 pub fn ty(self, db: &impl HirDatabase) -> Ty {
606 db.value_ty(self.id.into())
609 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
610 db.infer(self.id.into())
613 /// The containing impl block, if this is a method.
614 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
615 match self.container(db) {
616 Some(Container::ImplBlock(it)) => Some(it),
621 /// The containing trait, if this is a trait method definition.
622 pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
623 match self.container(db) {
624 Some(Container::Trait(it)) => Some(it),
629 pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
630 match self.id.lookup(db).container {
631 ContainerId::TraitId(it) => Some(Container::Trait(it.into())),
632 ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())),
633 ContainerId::ModuleId(_) => None,
637 pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) {
638 let infer = self.infer(db);
639 infer.add_diagnostics(db, self.id, sink);
640 let mut validator = ExprValidator::new(self.id, infer, sink);
641 validator.validate_body(db);
645 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
647 pub(crate) id: ConstId,
651 pub fn module(self, db: &impl DefDatabase) -> Module {
652 Module { id: self.id.lookup(db).module(db) }
655 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
656 Some(self.module(db).krate())
659 pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
660 db.const_data(self.id).name.clone()
663 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
664 db.infer(self.id.into())
667 /// The containing impl block, if this is a type alias.
668 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
669 match self.container(db) {
670 Some(Container::ImplBlock(it)) => Some(it),
675 /// The containing trait, if this is a trait type alias definition.
676 pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
677 match self.container(db) {
678 Some(Container::Trait(it)) => Some(it),
683 pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
684 match self.id.lookup(db).container {
685 ContainerId::TraitId(it) => Some(Container::Trait(it.into())),
686 ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())),
687 ContainerId::ModuleId(_) => None,
692 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
694 pub(crate) id: StaticId,
698 pub fn module(self, db: &impl DefDatabase) -> Module {
699 Module { id: self.id.lookup(db).module(db) }
702 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
703 Some(self.module(db).krate())
706 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
707 db.infer(self.id.into())
711 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
713 pub(crate) id: TraitId,
717 pub fn module(self, db: &impl DefDatabase) -> Module {
718 Module { id: self.id.module(db) }
721 pub fn name(self, db: &impl DefDatabase) -> Name {
722 db.trait_data(self.id).name.clone()
725 pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> {
726 db.trait_data(self.id).items.iter().map(|(_name, it)| (*it).into()).collect()
729 pub fn is_auto(self, db: &impl DefDatabase) -> bool {
730 db.trait_data(self.id).auto
734 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
735 pub struct TypeAlias {
736 pub(crate) id: TypeAliasId,
740 pub fn has_non_default_type_params(self, db: &impl HirDatabase) -> bool {
741 let subst = db.generic_defaults(self.id.into());
742 subst.iter().any(|ty| ty == &Ty::Unknown)
745 pub fn module(self, db: &impl DefDatabase) -> Module {
746 Module { id: self.id.lookup(db).module(db) }
749 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
750 Some(self.module(db).krate())
753 /// The containing impl block, if this is a type alias.
754 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
755 match self.container(db) {
756 Some(Container::ImplBlock(it)) => Some(it),
761 /// The containing trait, if this is a trait type alias definition.
762 pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
763 match self.container(db) {
764 Some(Container::Trait(it)) => Some(it),
769 pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
770 match self.id.lookup(db).container {
771 ContainerId::TraitId(it) => Some(Container::Trait(it.into())),
772 ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())),
773 ContainerId::ModuleId(_) => None,
777 pub fn type_ref(self, db: &impl DefDatabase) -> Option<TypeRef> {
778 db.type_alias_data(self.id).type_ref.clone()
781 pub fn ty(self, db: &impl HirDatabase) -> Type {
782 Type::from_def(db, self.id.lookup(db).module(db).krate, self.id)
785 pub fn name(self, db: &impl DefDatabase) -> Name {
786 db.type_alias_data(self.id).name.clone()
790 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
791 pub struct MacroDef {
792 pub(crate) id: MacroDefId,
799 ImplBlock(ImplBlock),
801 impl_froms!(Container: Trait, ImplBlock);
803 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
807 TypeAlias(TypeAlias),
809 // FIXME: not every function, ... is actually an assoc item. maybe we should make
810 // sure that you can only turn actual assoc items into AssocItems. This would
811 // require not implementing From, and instead having some checked way of
812 // casting them, and somehow making the constructors private, which would be annoying.
813 impl_froms!(AssocItem: Function, Const, TypeAlias);
816 pub fn module(self, db: &impl DefDatabase) -> Module {
818 AssocItem::Function(f) => f.module(db),
819 AssocItem::Const(c) => c.module(db),
820 AssocItem::TypeAlias(t) => t.module(db),
824 pub fn container(self, db: &impl DefDatabase) -> Container {
826 AssocItem::Function(f) => f.container(db),
827 AssocItem::Const(c) => c.container(db),
828 AssocItem::TypeAlias(t) => t.container(db),
830 .expect("AssocItem without container")
834 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
835 pub enum GenericDef {
839 TypeAlias(TypeAlias),
840 ImplBlock(ImplBlock),
841 // enum variants cannot have generics themselves, but their parent enums
842 // can, and this makes some code easier to write
843 EnumVariant(EnumVariant),
844 // consts can have type parameters from their parents (i.e. associated consts of traits)
848 GenericDef: Function,
849 Adt(Struct, Enum, Union),
857 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
859 pub(crate) parent: DefWithBody,
860 pub(crate) pat_id: PatId,
864 pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
865 let body = db.body(self.parent.into());
866 match &body[self.pat_id] {
867 Pat::Bind { name, .. } => Some(name.clone()),
872 pub fn is_self(self, db: &impl HirDatabase) -> bool {
873 self.name(db) == Some(name::SELF_PARAM)
876 pub fn is_mut(self, db: &impl HirDatabase) -> bool {
877 let body = db.body(self.parent.into());
878 match &body[self.pat_id] {
879 Pat::Bind { mode, .. } => match mode {
880 BindingAnnotation::Mutable | BindingAnnotation::RefMut => true,
887 pub fn parent(self, _db: &impl HirDatabase) -> DefWithBody {
891 pub fn module(self, db: &impl HirDatabase) -> Module {
892 self.parent.module(db)
895 pub fn ty(self, db: &impl HirDatabase) -> Type {
896 let def = DefWithBodyId::from(self.parent);
897 let infer = db.infer(def);
898 let ty = infer[self.pat_id].clone();
899 let resolver = def.resolver(db);
900 let krate = def.module(db).krate;
901 let environment = TraitEnvironment::lower(db, &resolver);
902 Type { krate, ty: InEnvironment { value: ty, environment } }
905 pub fn source(self, db: &impl HirDatabase) -> InFile<Either<ast::BindPat, ast::SelfParam>> {
906 let (_body, source_map) = db.body_with_source_map(self.parent.into());
907 let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm...
908 let root = src.file_syntax(db);
910 ast.map_left(|it| it.cast().unwrap().to_node(&root)).map_right(|it| it.to_node(&root))
915 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
916 pub struct GenericParam {
917 pub(crate) parent: GenericDefId,
921 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
922 pub struct ImplBlock {
923 pub(crate) id: ImplId,
927 pub fn all_in_crate(db: &impl HirDatabase, krate: Crate) -> Vec<ImplBlock> {
928 let impls = db.impls_in_crate(krate.crate_id);
929 impls.all_impls().map(Self::from).collect()
931 pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplBlock> {
932 let impls = db.impls_in_crate(krate.crate_id);
933 impls.lookup_impl_blocks_for_trait(trait_.id).map(Self::from).collect()
936 pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> {
937 db.impl_data(self.id).target_trait.clone()
940 pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef {
941 db.impl_data(self.id).target_type.clone()
944 pub fn target_ty(&self, db: &impl HirDatabase) -> Type {
945 let impl_data = db.impl_data(self.id);
946 let resolver = self.id.resolver(db);
947 let environment = TraitEnvironment::lower(db, &resolver);
948 let ty = Ty::from_hir(db, &resolver, &impl_data.target_type);
949 Type { krate: self.id.module(db).krate, ty: InEnvironment { value: ty, environment } }
952 pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> {
953 db.impl_data(self.id).items.iter().map(|it| (*it).into()).collect()
956 pub fn is_negative(&self, db: &impl DefDatabase) -> bool {
957 db.impl_data(self.id).is_negative
960 pub fn module(&self, db: &impl DefDatabase) -> Module {
961 self.id.module(db).into()
964 pub fn krate(&self, db: &impl DefDatabase) -> Crate {
965 Crate { crate_id: self.module(db).id.krate }
969 #[derive(Clone, PartialEq, Eq, Debug)]
971 pub(crate) krate: CrateId,
972 pub(crate) ty: InEnvironment<Ty>,
977 db: &impl HirDatabase,
979 def: impl HasResolver + Into<TyDefId>,
981 let resolver = def.resolver(db);
982 let environment = TraitEnvironment::lower(db, &resolver);
983 let ty = db.ty(def.into());
984 Type { krate, ty: InEnvironment { value: ty, environment } }
987 pub fn is_bool(&self) -> bool {
988 match &self.ty.value {
989 Ty::Apply(a_ty) => match a_ty.ctor {
990 TypeCtor::Bool => true,
997 pub fn is_mutable_reference(&self) -> bool {
998 match &self.ty.value {
999 Ty::Apply(a_ty) => match a_ty.ctor {
1000 TypeCtor::Ref(Mutability::Mut) => true,
1007 pub fn is_unknown(&self) -> bool {
1008 match &self.ty.value {
1009 Ty::Unknown => true,
1014 // FIXME: this method is broken, as it doesn't take closures into account.
1015 pub fn as_callable(&self) -> Option<CallableDef> {
1016 Some(self.ty.value.as_callable()?.0)
1019 pub fn contains_unknown(&self) -> bool {
1020 return go(&self.ty.value);
1022 fn go(ty: &Ty) -> bool {
1024 Ty::Unknown => true,
1025 Ty::Apply(a_ty) => a_ty.parameters.iter().any(go),
1031 pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> {
1032 if let Ty::Apply(a_ty) = &self.ty.value {
1034 ty::TypeCtor::Adt(AdtId::StructId(s)) => {
1035 let var_def = s.into();
1037 .field_types(var_def)
1039 .map(|(local_id, ty)| {
1040 let def = StructField { parent: var_def.into(), id: local_id };
1041 let ty = ty.clone().subst(&a_ty.parameters);
1042 (def, self.derived(ty))
1052 pub fn tuple_fields(&self, _db: &impl HirDatabase) -> Vec<Type> {
1053 let mut res = Vec::new();
1054 if let Ty::Apply(a_ty) = &self.ty.value {
1056 ty::TypeCtor::Tuple { .. } => {
1057 for ty in a_ty.parameters.iter() {
1058 let ty = ty.clone().subst(&a_ty.parameters);
1059 res.push(self.derived(ty));
1068 pub fn variant_fields(
1070 db: &impl HirDatabase,
1072 ) -> Vec<(StructField, Type)> {
1073 // FIXME: check that ty and def match
1074 match &self.ty.value {
1075 Ty::Apply(a_ty) => def
1078 .map(|it| (it, self.derived(it.ty(db).subst(&a_ty.parameters))))
1084 pub fn autoderef<'a>(&'a self, db: &'a impl HirDatabase) -> impl Iterator<Item = Type> + 'a {
1085 // There should be no inference vars in types passed here
1086 // FIXME check that?
1087 let canonical = crate::ty::Canonical { value: self.ty.value.clone(), num_vars: 0 };
1088 let environment = self.ty.environment.clone();
1089 let ty = InEnvironment { value: canonical, environment: environment.clone() };
1090 ty::autoderef(db, Some(self.krate), ty)
1091 .map(|canonical| canonical.value)
1092 .map(move |ty| self.derived(ty))
1095 // This would be nicer if it just returned an iterator, but that runs into
1096 // lifetime problems, because we need to borrow temp `CrateImplBlocks`.
1097 pub fn iterate_impl_items<T>(
1099 db: &impl HirDatabase,
1101 mut callback: impl FnMut(AssocItem) -> Option<T>,
1103 for krate in self.ty.value.def_crates(db, krate.crate_id)? {
1104 let impls = db.impls_in_crate(krate);
1106 for impl_block in impls.lookup_impl_blocks(&self.ty.value) {
1107 for &item in db.impl_data(impl_block).items.iter() {
1108 if let Some(result) = callback(item.into()) {
1109 return Some(result);
1118 pub fn into_ty(self) -> Ty {
1122 pub fn as_adt(&self) -> Option<Adt> {
1123 let (adt, _subst) = self.ty.value.as_adt()?;
1127 // FIXME: provide required accessors such that it becomes implementable from outside.
1128 pub fn is_equal_for_find_impls(&self, other: &Type) -> bool {
1129 match (&self.ty.value, &other.ty.value) {
1130 (Ty::Apply(a_original_ty), Ty::Apply(ty::ApplicationTy { ctor, parameters })) => {
1132 TypeCtor::Ref(..) => match parameters.as_single() {
1133 Ty::Apply(a_ty) => a_original_ty.ctor == a_ty.ctor,
1136 _ => a_original_ty.ctor == *ctor,
1143 fn derived(&self, ty: Ty) -> Type {
1146 ty: InEnvironment { value: ty, environment: self.ty.environment.clone() },
1151 impl HirDisplay for Type {
1152 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> std::fmt::Result {
1153 self.ty.value.hir_fmt(f)
1159 ModuleDef(ModuleDef),
1161 GenericParam(GenericParam),
1162 ImplSelfType(ImplBlock),
1168 impl From<PerNs> for ScopeDef {
1169 fn from(def: PerNs) -> Self {
1171 .or_else(|| def.take_values())
1172 .map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into()))
1174 def.take_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into()))
1176 .unwrap_or(ScopeDef::Unknown)
1180 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1183 StructField(StructField),
1186 EnumVariant(EnumVariant),
1190 TypeAlias(TypeAlias),
1197 Adt(Struct, Enum, Union),
1207 pub trait HasAttrs {
1208 fn attrs(self, db: &impl DefDatabase) -> Attrs;
1211 impl<T: Into<AttrDef>> HasAttrs for T {
1212 fn attrs(self, db: &impl DefDatabase) -> Attrs {
1213 let def: AttrDef = self.into();
1214 db.attrs(def.into())
1219 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation>;
1221 impl<T: Into<AttrDef> + Copy> Docs for T {
1222 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
1223 let def: AttrDef = (*self).into();
1224 db.documentation(def.into())