aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/code_model.rs89
-rw-r--r--crates/ra_hir/src/db.rs13
-rw-r--r--crates/ra_hir/src/impl_block.rs8
-rw-r--r--crates/ra_hir/src/lib.rs6
-rw-r--r--crates/ra_hir/src/ty/infer.rs13
-rw-r--r--crates/ra_hir/src/ty/lower.rs6
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs6
-rw-r--r--crates/ra_hir_def/src/data.rs192
-rw-r--r--crates/ra_hir_def/src/db.rs10
-rw-r--r--crates/ra_hir_def/src/impls.rs86
-rw-r--r--crates/ra_hir_def/src/lib.rs4
-rw-r--r--crates/ra_hir_def/src/traits.rs66
-rw-r--r--crates/ra_hir_def/src/type_alias.rs27
-rw-r--r--crates/ra_ide_api/src/call_info.rs4
-rw-r--r--crates/ra_ide_api/src/change.rs2
-rw-r--r--crates/ra_ide_api/src/completion/complete_dot.rs3
-rw-r--r--crates/ra_ide_api/src/completion/complete_path.rs6
-rw-r--r--crates/ra_ide_api/src/completion/presentation.rs20
18 files changed, 252 insertions, 309 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 72c9b466f..3daf7488e 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -10,10 +10,10 @@ use hir_def::{
10 adt::VariantData, 10 adt::VariantData,
11 body::scope::ExprScopes, 11 body::scope::ExprScopes,
12 builtin_type::BuiltinType, 12 builtin_type::BuiltinType,
13 data::TraitData,
13 nameres::per_ns::PerNs, 14 nameres::per_ns::PerNs,
14 resolver::{HasResolver, TypeNs}, 15 resolver::{HasResolver, TypeNs},
15 traits::TraitData, 16 type_ref::TypeRef,
16 type_ref::{Mutability, TypeRef},
17 ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup, 17 ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup,
18 ModuleId, UnionId, 18 ModuleId, UnionId,
19}; 19};
@@ -561,77 +561,6 @@ pub struct Function {
561 pub(crate) id: FunctionId, 561 pub(crate) id: FunctionId,
562} 562}
563 563
564#[derive(Debug, Clone, PartialEq, Eq)]
565pub struct FnData {
566 pub(crate) name: Name,
567 pub(crate) params: Vec<TypeRef>,
568 pub(crate) ret_type: TypeRef,
569 /// True if the first param is `self`. This is relevant to decide whether this
570 /// can be called as a method.
571 pub(crate) has_self_param: bool,
572}
573
574impl FnData {
575 pub(crate) fn fn_data_query(
576 db: &(impl DefDatabase + AstDatabase),
577 func: Function,
578 ) -> Arc<FnData> {
579 let src = func.source(db);
580 let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing);
581 let mut params = Vec::new();
582 let mut has_self_param = false;
583 if let Some(param_list) = src.value.param_list() {
584 if let Some(self_param) = param_list.self_param() {
585 let self_type = if let Some(type_ref) = self_param.ascribed_type() {
586 TypeRef::from_ast(type_ref)
587 } else {
588 let self_type = TypeRef::Path(name::SELF_TYPE.into());
589 match self_param.kind() {
590 ast::SelfParamKind::Owned => self_type,
591 ast::SelfParamKind::Ref => {
592 TypeRef::Reference(Box::new(self_type), Mutability::Shared)
593 }
594 ast::SelfParamKind::MutRef => {
595 TypeRef::Reference(Box::new(self_type), Mutability::Mut)
596 }
597 }
598 };
599 params.push(self_type);
600 has_self_param = true;
601 }
602 for param in param_list.params() {
603 let type_ref = TypeRef::from_ast_opt(param.ascribed_type());
604 params.push(type_ref);
605 }
606 }
607 let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) {
608 TypeRef::from_ast(type_ref)
609 } else {
610 TypeRef::unit()
611 };
612
613 let sig = FnData { name, params, ret_type, has_self_param };
614 Arc::new(sig)
615 }
616 pub fn name(&self) -> &Name {
617 &self.name
618 }
619
620 pub fn params(&self) -> &[TypeRef] {
621 &self.params
622 }
623
624 pub fn ret_type(&self) -> &TypeRef {
625 &self.ret_type
626 }
627
628 /// True if the first arg is `self`. This is relevant to decide whether this
629 /// can be called as a method.
630 pub fn has_self_param(&self) -> bool {
631 self.has_self_param
632 }
633}
634
635impl Function { 564impl Function {
636 pub fn module(self, db: &impl DefDatabase) -> Module { 565 pub fn module(self, db: &impl DefDatabase) -> Module {
637 self.id.lookup(db).module(db).into() 566 self.id.lookup(db).module(db).into()
@@ -642,7 +571,15 @@ impl Function {
642 } 571 }
643 572
644 pub fn name(self, db: &impl HirDatabase) -> Name { 573 pub fn name(self, db: &impl HirDatabase) -> Name {
645 self.data(db).name.clone() 574 db.function_data(self.id).name.clone()
575 }
576
577 pub fn has_self_param(self, db: &impl HirDatabase) -> bool {
578 db.function_data(self.id).has_self_param
579 }
580
581 pub fn params(self, db: &impl HirDatabase) -> Vec<TypeRef> {
582 db.function_data(self.id).params.clone()
646 } 583 }
647 584
648 pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { 585 pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
@@ -657,10 +594,6 @@ impl Function {
657 db.type_for_def(self.into(), Namespace::Values) 594 db.type_for_def(self.into(), Namespace::Values)
658 } 595 }
659 596
660 pub fn data(self, db: &impl HirDatabase) -> Arc<FnData> {
661 db.fn_data(self)
662 }
663
664 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { 597 pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
665 db.infer(self.into()) 598 db.infer(self.into())
666 } 599 }
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 1cfcb2fd2..8b9af0565 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -16,15 +16,15 @@ use crate::{
16 CallableDef, FnSig, GenericPredicate, InferenceResult, Namespace, Substs, Ty, TypableDef, 16 CallableDef, FnSig, GenericPredicate, InferenceResult, Namespace, Substs, Ty, TypableDef,
17 TypeCtor, 17 TypeCtor,
18 }, 18 },
19 Const, ConstData, Crate, DefWithBody, FnData, Function, GenericDef, ImplBlock, Module, Static, 19 Const, ConstData, Crate, DefWithBody, GenericDef, ImplBlock, Module, Static, StructField,
20 StructField, Trait, 20 Trait,
21}; 21};
22 22
23pub use hir_def::db::{ 23pub use hir_def::db::{
24 BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage, 24 BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage,
25 EnumDataQuery, ExprScopesQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, 25 EnumDataQuery, ExprScopesQuery, FunctionDataQuery, GenericParamsQuery, ImplDataQuery,
26 InternDatabaseStorage, RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, 26 InternDatabase, InternDatabaseStorage, RawItemsQuery, RawItemsWithSourceMapQuery,
27 TraitDataQuery, TypeAliasDataQuery, 27 StructDataQuery, TraitDataQuery, TypeAliasDataQuery,
28}; 28};
29pub use hir_expand::db::{ 29pub use hir_expand::db::{
30 AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, 30 AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
@@ -35,9 +35,6 @@ pub use hir_expand::db::{
35#[salsa::query_group(DefDatabaseStorage)] 35#[salsa::query_group(DefDatabaseStorage)]
36#[salsa::requires(AstDatabase)] 36#[salsa::requires(AstDatabase)]
37pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { 37pub trait DefDatabase: HirDebugDatabase + DefDatabase2 {
38 #[salsa::invoke(FnData::fn_data_query)]
39 fn fn_data(&self, func: Function) -> Arc<FnData>;
40
41 #[salsa::invoke(ConstData::const_data_query)] 38 #[salsa::invoke(ConstData::const_data_query)]
42 fn const_data(&self, konst: Const) -> Arc<ConstData>; 39 fn const_data(&self, konst: Const) -> Arc<ConstData>;
43 40
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index 774fa1d96..334eeebac 100644
--- a/crates/ra_hir/src/impl_block.rs
+++ b/crates/ra_hir/src/impl_block.rs
@@ -18,11 +18,11 @@ impl HasSource for ImplBlock {
18 18
19impl ImplBlock { 19impl ImplBlock {
20 pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { 20 pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> {
21 db.impl_data(self.id).target_trait().cloned() 21 db.impl_data(self.id).target_trait.clone()
22 } 22 }
23 23
24 pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef { 24 pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef {
25 db.impl_data(self.id).target_type().clone() 25 db.impl_data(self.id).target_type.clone()
26 } 26 }
27 27
28 pub fn target_ty(&self, db: &impl HirDatabase) -> Ty { 28 pub fn target_ty(&self, db: &impl HirDatabase) -> Ty {
@@ -35,11 +35,11 @@ impl ImplBlock {
35 } 35 }
36 36
37 pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { 37 pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> {
38 db.impl_data(self.id).items().iter().map(|it| (*it).into()).collect() 38 db.impl_data(self.id).items.iter().map(|it| (*it).into()).collect()
39 } 39 }
40 40
41 pub fn is_negative(&self, db: &impl DefDatabase) -> bool { 41 pub fn is_negative(&self, db: &impl DefDatabase) -> bool {
42 db.impl_data(self.id).is_negative() 42 db.impl_data(self.id).is_negative
43 } 43 }
44 44
45 pub fn module(&self, db: &impl DefDatabase) -> Module { 45 pub fn module(&self, db: &impl DefDatabase) -> Module {
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 8535629ca..d29cc9258 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -55,9 +55,9 @@ pub use crate::{
55 docs::{DocDef, Docs, Documentation}, 55 docs::{DocDef, Docs, Documentation},
56 src::{HasBodySource, HasSource}, 56 src::{HasBodySource, HasSource},
57 Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, 57 Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum,
58 EnumVariant, FieldSource, FnData, Function, GenericDef, GenericParam, HasBody, ImplBlock, 58 EnumVariant, FieldSource, Function, GenericDef, GenericParam, HasBody, ImplBlock, Local,
59 Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField, 59 MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField, Trait,
60 Trait, TypeAlias, Union, VariantDef, 60 TypeAlias, Union, VariantDef,
61 }, 61 },
62 expr::ExprScopes, 62 expr::ExprScopes,
63 from_source::FromSource, 63 from_source::FromSource,
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 69b13baef..6e07ab86e 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -22,6 +22,7 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
22use rustc_hash::FxHashMap; 22use rustc_hash::FxHashMap;
23 23
24use hir_def::{ 24use hir_def::{
25 data::FunctionData,
25 path::known, 26 path::known,
26 resolver::{HasResolver, Resolver, TypeNs}, 27 resolver::{HasResolver, Resolver, TypeNs},
27 type_ref::{Mutability, TypeRef}, 28 type_ref::{Mutability, TypeRef},
@@ -43,8 +44,8 @@ use crate::{
43 db::HirDatabase, 44 db::HirDatabase,
44 expr::{BindingAnnotation, Body, ExprId, PatId}, 45 expr::{BindingAnnotation, Body, ExprId, PatId},
45 ty::infer::diagnostics::InferenceDiagnostic, 46 ty::infer::diagnostics::InferenceDiagnostic,
46 Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, 47 Adt, AssocItem, ConstData, DefWithBody, FloatTy, Function, HasBody, IntTy, Path, StructField,
47 StructField, Trait, VariantDef, 48 Trait, VariantDef,
48}; 49};
49 50
50macro_rules! ty_app { 51macro_rules! ty_app {
@@ -70,7 +71,7 @@ pub fn infer_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResu
70 71
71 match def { 72 match def {
72 DefWithBody::Const(ref c) => ctx.collect_const(&c.data(db)), 73 DefWithBody::Const(ref c) => ctx.collect_const(&c.data(db)),
73 DefWithBody::Function(ref f) => ctx.collect_fn(&f.data(db)), 74 DefWithBody::Function(ref f) => ctx.collect_fn(&db.function_data(f.id)),
74 DefWithBody::Static(ref s) => ctx.collect_const(&s.data(db)), 75 DefWithBody::Static(ref s) => ctx.collect_const(&s.data(db)),
75 } 76 }
76 77
@@ -562,14 +563,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
562 self.return_ty = self.make_ty(data.type_ref()); 563 self.return_ty = self.make_ty(data.type_ref());
563 } 564 }
564 565
565 fn collect_fn(&mut self, data: &FnData) { 566 fn collect_fn(&mut self, data: &FunctionData) {
566 let body = Arc::clone(&self.body); // avoid borrow checker problem 567 let body = Arc::clone(&self.body); // avoid borrow checker problem
567 for (type_ref, pat) in data.params().iter().zip(body.params()) { 568 for (type_ref, pat) in data.params.iter().zip(body.params()) {
568 let ty = self.make_ty(type_ref); 569 let ty = self.make_ty(type_ref);
569 570
570 self.infer_pat(*pat, &ty, BindingMode::default()); 571 self.infer_pat(*pat, &ty, BindingMode::default());
571 } 572 }
572 self.return_ty = self.make_ty(data.ret_type()); 573 self.return_ty = self.make_ty(&data.ret_type);
573 } 574 }
574 575
575 fn infer_body(&mut self) { 576 fn infer_body(&mut self) {
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index 75c552569..42daa9cb9 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -622,10 +622,10 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) ->
622} 622}
623 623
624fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { 624fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig {
625 let data = def.data(db); 625 let data = db.function_data(def.id);
626 let resolver = def.id.resolver(db); 626 let resolver = def.id.resolver(db);
627 let params = data.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); 627 let params = data.params.iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>();
628 let ret = Ty::from_hir(db, &resolver, data.ret_type()); 628 let ret = Ty::from_hir(db, &resolver, &data.ret_type);
629 FnSig::from_params_and_return(params, ret) 629 FnSig::from_params_and_return(params, ret)
630} 630}
631 631
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index 64adb814d..f84aae26e 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -291,9 +291,9 @@ fn is_valid_candidate(
291) -> bool { 291) -> bool {
292 match item { 292 match item {
293 AssocItem::Function(m) => { 293 AssocItem::Function(m) => {
294 let data = m.data(db); 294 let data = db.function_data(m.id);
295 name.map_or(true, |name| data.name() == name) 295 name.map_or(true, |name| data.name == *name)
296 && (data.has_self_param() || mode == LookupMode::Path) 296 && (data.has_self_param || mode == LookupMode::Path)
297 } 297 }
298 AssocItem::Const(c) => { 298 AssocItem::Const(c) => {
299 name.map_or(true, |name| Some(name) == c.name(db).as_ref()) 299 name.map_or(true, |name| Some(name) == c.name(db).as_ref())
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs
new file mode 100644
index 000000000..ba47629db
--- /dev/null
+++ b/crates/ra_hir_def/src/data.rs
@@ -0,0 +1,192 @@
1//! Contains basic data about various HIR declarations.
2
3use std::sync::Arc;
4
5use hir_expand::{
6 name::{self, AsName, Name},
7 AstId,
8};
9use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
10
11use crate::{
12 db::DefDatabase2,
13 type_ref::{Mutability, TypeRef},
14 AssocItemId, AstItemDef, ConstLoc, ContainerId, FunctionId, FunctionLoc, HasSource, ImplId,
15 Intern, Lookup, TraitId, TypeAliasId, TypeAliasLoc,
16};
17
18#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct FunctionData {
20 pub name: Name,
21 pub params: Vec<TypeRef>,
22 pub ret_type: TypeRef,
23 /// True if the first param is `self`. This is relevant to decide whether this
24 /// can be called as a method.
25 pub has_self_param: bool,
26}
27
28impl FunctionData {
29 pub(crate) fn fn_data_query(db: &impl DefDatabase2, func: FunctionId) -> Arc<FunctionData> {
30 let src = func.lookup(db).source(db);
31 let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing);
32 let mut params = Vec::new();
33 let mut has_self_param = false;
34 if let Some(param_list) = src.value.param_list() {
35 if let Some(self_param) = param_list.self_param() {
36 let self_type = if let Some(type_ref) = self_param.ascribed_type() {
37 TypeRef::from_ast(type_ref)
38 } else {
39 let self_type = TypeRef::Path(name::SELF_TYPE.into());
40 match self_param.kind() {
41 ast::SelfParamKind::Owned => self_type,
42 ast::SelfParamKind::Ref => {
43 TypeRef::Reference(Box::new(self_type), Mutability::Shared)
44 }
45 ast::SelfParamKind::MutRef => {
46 TypeRef::Reference(Box::new(self_type), Mutability::Mut)
47 }
48 }
49 };
50 params.push(self_type);
51 has_self_param = true;
52 }
53 for param in param_list.params() {
54 let type_ref = TypeRef::from_ast_opt(param.ascribed_type());
55 params.push(type_ref);
56 }
57 }
58 let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) {
59 TypeRef::from_ast(type_ref)
60 } else {
61 TypeRef::unit()
62 };
63
64 let sig = FunctionData { name, params, ret_type, has_self_param };
65 Arc::new(sig)
66 }
67}
68
69#[derive(Debug, Clone, PartialEq, Eq)]
70pub struct TypeAliasData {
71 pub name: Name,
72 pub type_ref: Option<TypeRef>,
73}
74
75impl TypeAliasData {
76 pub(crate) fn type_alias_data_query(
77 db: &impl DefDatabase2,
78 typ: TypeAliasId,
79 ) -> Arc<TypeAliasData> {
80 let node = typ.lookup(db).source(db).value;
81 let name = node.name().map_or_else(Name::missing, |n| n.as_name());
82 let type_ref = node.type_ref().map(TypeRef::from_ast);
83 Arc::new(TypeAliasData { name, type_ref })
84 }
85}
86
87#[derive(Debug, Clone, PartialEq, Eq)]
88pub struct TraitData {
89 pub name: Option<Name>,
90 pub items: Vec<AssocItemId>,
91 pub auto: bool,
92}
93
94impl TraitData {
95 pub(crate) fn trait_data_query(db: &impl DefDatabase2, tr: TraitId) -> Arc<TraitData> {
96 let src = tr.source(db);
97 let name = src.value.name().map(|n| n.as_name());
98 let auto = src.value.is_auto();
99 let ast_id_map = db.ast_id_map(src.file_id);
100 let items = if let Some(item_list) = src.value.item_list() {
101 item_list
102 .impl_items()
103 .map(|item_node| match item_node {
104 ast::ImplItem::FnDef(it) => FunctionLoc {
105 container: ContainerId::TraitId(tr),
106 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
107 }
108 .intern(db)
109 .into(),
110 ast::ImplItem::ConstDef(it) => ConstLoc {
111 container: ContainerId::TraitId(tr),
112 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
113 }
114 .intern(db)
115 .into(),
116 ast::ImplItem::TypeAliasDef(it) => TypeAliasLoc {
117 container: ContainerId::TraitId(tr),
118 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
119 }
120 .intern(db)
121 .into(),
122 })
123 .collect()
124 } else {
125 Vec::new()
126 };
127 Arc::new(TraitData { name, items, auto })
128 }
129
130 pub fn associated_types(&self) -> impl Iterator<Item = TypeAliasId> + '_ {
131 self.items.iter().filter_map(|item| match item {
132 AssocItemId::TypeAliasId(t) => Some(*t),
133 _ => None,
134 })
135 }
136}
137
138#[derive(Debug, Clone, PartialEq, Eq)]
139pub struct ImplData {
140 pub target_trait: Option<TypeRef>,
141 pub target_type: TypeRef,
142 pub items: Vec<AssocItemId>,
143 pub is_negative: bool,
144}
145
146impl ImplData {
147 pub(crate) fn impl_data_query(db: &impl DefDatabase2, id: ImplId) -> Arc<ImplData> {
148 let src = id.source(db);
149 let items = db.ast_id_map(src.file_id);
150
151 let target_trait = src.value.target_trait().map(TypeRef::from_ast);
152 let target_type = TypeRef::from_ast_opt(src.value.target_type());
153 let is_negative = src.value.is_negative();
154
155 let items = if let Some(item_list) = src.value.item_list() {
156 item_list
157 .impl_items()
158 .map(|item_node| match item_node {
159 ast::ImplItem::FnDef(it) => {
160 let def = FunctionLoc {
161 container: ContainerId::ImplId(id),
162 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
163 }
164 .intern(db);
165 def.into()
166 }
167 ast::ImplItem::ConstDef(it) => {
168 let def = ConstLoc {
169 container: ContainerId::ImplId(id),
170 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
171 }
172 .intern(db);
173 def.into()
174 }
175 ast::ImplItem::TypeAliasDef(it) => {
176 let def = TypeAliasLoc {
177 container: ContainerId::ImplId(id),
178 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
179 }
180 .intern(db);
181 def.into()
182 }
183 })
184 .collect()
185 } else {
186 Vec::new()
187 };
188
189 let res = ImplData { target_trait, target_type, items, is_negative };
190 Arc::new(res)
191 }
192}
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs
index 5bbdaa4b2..8c1784ec9 100644
--- a/crates/ra_hir_def/src/db.rs
+++ b/crates/ra_hir_def/src/db.rs
@@ -8,15 +8,14 @@ use ra_syntax::ast;
8use crate::{ 8use crate::{
9 adt::{EnumData, StructData}, 9 adt::{EnumData, StructData},
10 body::{scope::ExprScopes, Body, BodySourceMap}, 10 body::{scope::ExprScopes, Body, BodySourceMap},
11 data::{FunctionData, ImplData, TraitData, TypeAliasData},
11 generics::GenericParams, 12 generics::GenericParams,
12 impls::ImplData,
13 nameres::{ 13 nameres::{
14 raw::{ImportSourceMap, RawItems}, 14 raw::{ImportSourceMap, RawItems},
15 CrateDefMap, 15 CrateDefMap,
16 }, 16 },
17 traits::TraitData, 17 DefWithBodyId, EnumId, FunctionId, GenericDefId, ImplId, ItemLoc, StructOrUnionId, TraitId,
18 type_alias::TypeAliasData, 18 TypeAliasId,
19 DefWithBodyId, EnumId, GenericDefId, ImplId, ItemLoc, StructOrUnionId, TraitId, TypeAliasId,
20}; 19};
21 20
22#[salsa::query_group(InternDatabaseStorage)] 21#[salsa::query_group(InternDatabaseStorage)]
@@ -68,6 +67,9 @@ pub trait DefDatabase2: InternDatabase + AstDatabase {
68 #[salsa::invoke(TypeAliasData::type_alias_data_query)] 67 #[salsa::invoke(TypeAliasData::type_alias_data_query)]
69 fn type_alias_data(&self, e: TypeAliasId) -> Arc<TypeAliasData>; 68 fn type_alias_data(&self, e: TypeAliasId) -> Arc<TypeAliasData>;
70 69
70 #[salsa::invoke(FunctionData::fn_data_query)]
71 fn function_data(&self, func: FunctionId) -> Arc<FunctionData>;
72
71 #[salsa::invoke(Body::body_with_source_map_query)] 73 #[salsa::invoke(Body::body_with_source_map_query)]
72 fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>); 74 fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>);
73 75
diff --git a/crates/ra_hir_def/src/impls.rs b/crates/ra_hir_def/src/impls.rs
deleted file mode 100644
index 750a869f2..000000000
--- a/crates/ra_hir_def/src/impls.rs
+++ /dev/null
@@ -1,86 +0,0 @@
1//! Defines hir-level representation of impls.
2//!
3//! The handling is similar, but is not quite the same as for other items,
4//! because `impl`s don't have names.
5
6use std::sync::Arc;
7
8use hir_expand::AstId;
9use ra_syntax::ast;
10
11use crate::{
12 db::DefDatabase2, type_ref::TypeRef, AssocItemId, AstItemDef, ConstLoc, ContainerId,
13 FunctionLoc, ImplId, Intern, TypeAliasLoc,
14};
15
16#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct ImplData {
18 target_trait: Option<TypeRef>,
19 target_type: TypeRef,
20 items: Vec<AssocItemId>,
21 negative: bool,
22}
23
24impl ImplData {
25 pub(crate) fn impl_data_query(db: &impl DefDatabase2, id: ImplId) -> Arc<ImplData> {
26 let src = id.source(db);
27 let items = db.ast_id_map(src.file_id);
28
29 let target_trait = src.value.target_trait().map(TypeRef::from_ast);
30 let target_type = TypeRef::from_ast_opt(src.value.target_type());
31 let negative = src.value.is_negative();
32
33 let items = if let Some(item_list) = src.value.item_list() {
34 item_list
35 .impl_items()
36 .map(|item_node| match item_node {
37 ast::ImplItem::FnDef(it) => {
38 let def = FunctionLoc {
39 container: ContainerId::ImplId(id),
40 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
41 }
42 .intern(db);
43 def.into()
44 }
45 ast::ImplItem::ConstDef(it) => {
46 let def = ConstLoc {
47 container: ContainerId::ImplId(id),
48 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
49 }
50 .intern(db);
51 def.into()
52 }
53 ast::ImplItem::TypeAliasDef(it) => {
54 let def = TypeAliasLoc {
55 container: ContainerId::ImplId(id),
56 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
57 }
58 .intern(db);
59 def.into()
60 }
61 })
62 .collect()
63 } else {
64 Vec::new()
65 };
66
67 let res = ImplData { target_trait, target_type, items, negative };
68 Arc::new(res)
69 }
70
71 pub fn target_trait(&self) -> Option<&TypeRef> {
72 self.target_trait.as_ref()
73 }
74
75 pub fn target_type(&self) -> &TypeRef {
76 &self.target_type
77 }
78
79 pub fn items(&self) -> &[AssocItemId] {
80 &self.items
81 }
82
83 pub fn is_negative(&self) -> bool {
84 self.negative
85 }
86}
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index 268144462..3a0420da0 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -13,14 +13,12 @@ pub mod path;
13pub mod type_ref; 13pub mod type_ref;
14pub mod builtin_type; 14pub mod builtin_type;
15pub mod adt; 15pub mod adt;
16pub mod impls;
17pub mod diagnostics; 16pub mod diagnostics;
18pub mod expr; 17pub mod expr;
19pub mod body; 18pub mod body;
20pub mod generics; 19pub mod generics;
21pub mod traits;
22pub mod resolver; 20pub mod resolver;
23pub mod type_alias; 21pub mod data;
24 22
25#[cfg(test)] 23#[cfg(test)]
26mod test_db; 24mod test_db;
diff --git a/crates/ra_hir_def/src/traits.rs b/crates/ra_hir_def/src/traits.rs
deleted file mode 100644
index 6c2d5b2a9..000000000
--- a/crates/ra_hir_def/src/traits.rs
+++ /dev/null
@@ -1,66 +0,0 @@
1//! HIR for trait definitions.
2
3use std::sync::Arc;
4
5use hir_expand::{
6 name::{AsName, Name},
7 AstId,
8};
9
10use ra_syntax::ast::{self, NameOwner};
11
12use crate::{
13 db::DefDatabase2, AssocItemId, AstItemDef, ConstLoc, ContainerId, FunctionLoc, Intern, TraitId,
14 TypeAliasId, TypeAliasLoc,
15};
16
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct TraitData {
19 pub name: Option<Name>,
20 pub items: Vec<AssocItemId>,
21 pub auto: bool,
22}
23
24impl TraitData {
25 pub(crate) fn trait_data_query(db: &impl DefDatabase2, tr: TraitId) -> Arc<TraitData> {
26 let src = tr.source(db);
27 let name = src.value.name().map(|n| n.as_name());
28 let auto = src.value.is_auto();
29 let ast_id_map = db.ast_id_map(src.file_id);
30 let items = if let Some(item_list) = src.value.item_list() {
31 item_list
32 .impl_items()
33 .map(|item_node| match item_node {
34 ast::ImplItem::FnDef(it) => FunctionLoc {
35 container: ContainerId::TraitId(tr),
36 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
37 }
38 .intern(db)
39 .into(),
40 ast::ImplItem::ConstDef(it) => ConstLoc {
41 container: ContainerId::TraitId(tr),
42 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
43 }
44 .intern(db)
45 .into(),
46 ast::ImplItem::TypeAliasDef(it) => TypeAliasLoc {
47 container: ContainerId::TraitId(tr),
48 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
49 }
50 .intern(db)
51 .into(),
52 })
53 .collect()
54 } else {
55 Vec::new()
56 };
57 Arc::new(TraitData { name, items, auto })
58 }
59
60 pub fn associated_types(&self) -> impl Iterator<Item = TypeAliasId> + '_ {
61 self.items.iter().filter_map(|item| match item {
62 AssocItemId::TypeAliasId(t) => Some(*t),
63 _ => None,
64 })
65 }
66}
diff --git a/crates/ra_hir_def/src/type_alias.rs b/crates/ra_hir_def/src/type_alias.rs
deleted file mode 100644
index c0b49aa7c..000000000
--- a/crates/ra_hir_def/src/type_alias.rs
+++ /dev/null
@@ -1,27 +0,0 @@
1//! HIR for type aliases (i.e. the `type` keyword).
2
3use std::sync::Arc;
4
5use hir_expand::name::{AsName, Name};
6
7use ra_syntax::ast::NameOwner;
8
9use crate::{db::DefDatabase2, type_ref::TypeRef, HasSource, Lookup, TypeAliasId};
10
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct TypeAliasData {
13 pub name: Name,
14 pub type_ref: Option<TypeRef>,
15}
16
17impl TypeAliasData {
18 pub(crate) fn type_alias_data_query(
19 db: &impl DefDatabase2,
20 typ: TypeAliasId,
21 ) -> Arc<TypeAliasData> {
22 let node = typ.lookup(db).source(db).value;
23 let name = node.name().map_or_else(Name::missing, |n| n.as_name());
24 let type_ref = node.type_ref().map(TypeRef::from_ast);
25 Arc::new(TypeAliasData { name, type_ref })
26 }
27}
diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs
index 41ee81511..7c367230e 100644
--- a/crates/ra_ide_api/src/call_info.rs
+++ b/crates/ra_ide_api/src/call_info.rs
@@ -30,7 +30,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
30 let (callable_def, _subst) = analyzer.type_of(db, &expr.expr()?)?.as_callable()?; 30 let (callable_def, _subst) = analyzer.type_of(db, &expr.expr()?)?.as_callable()?;
31 match callable_def { 31 match callable_def {
32 hir::CallableDef::Function(it) => { 32 hir::CallableDef::Function(it) => {
33 (CallInfo::with_fn(db, it), it.data(db).has_self_param()) 33 (CallInfo::with_fn(db, it), it.has_self_param(db))
34 } 34 }
35 hir::CallableDef::Struct(it) => (CallInfo::with_struct(db, it)?, false), 35 hir::CallableDef::Struct(it) => (CallInfo::with_struct(db, it)?, false),
36 hir::CallableDef::EnumVariant(it) => (CallInfo::with_enum_variant(db, it)?, false), 36 hir::CallableDef::EnumVariant(it) => (CallInfo::with_enum_variant(db, it)?, false),
@@ -38,7 +38,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
38 } 38 }
39 FnCallNode::MethodCallExpr(expr) => { 39 FnCallNode::MethodCallExpr(expr) => {
40 let function = analyzer.resolve_method_call(&expr)?; 40 let function = analyzer.resolve_method_call(&expr)?;
41 (CallInfo::with_fn(db, function), function.data(db).has_self_param()) 41 (CallInfo::with_fn(db, function), function.has_self_param(db))
42 } 42 }
43 FnCallNode::MacroCallExpr(expr) => { 43 FnCallNode::MacroCallExpr(expr) => {
44 let macro_def = analyzer.resolve_macro_call(db, &expr)?; 44 let macro_def = analyzer.resolve_macro_call(db, &expr)?;
diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide_api/src/change.rs
index 3c607d5b5..8a05b287f 100644
--- a/crates/ra_ide_api/src/change.rs
+++ b/crates/ra_ide_api/src/change.rs
@@ -313,7 +313,7 @@ impl RootDatabase {
313 hir::db::RawItemsQuery 313 hir::db::RawItemsQuery
314 hir::db::CrateDefMapQuery 314 hir::db::CrateDefMapQuery
315 hir::db::GenericParamsQuery 315 hir::db::GenericParamsQuery
316 hir::db::FnDataQuery 316 hir::db::FunctionDataQuery
317 hir::db::TypeAliasDataQuery 317 hir::db::TypeAliasDataQuery
318 hir::db::ConstDataQuery 318 hir::db::ConstDataQuery
319 hir::db::StaticDataQuery 319 hir::db::StaticDataQuery
diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs
index 4e2c497e1..5a3f9b5f6 100644
--- a/crates/ra_ide_api/src/completion/complete_dot.rs
+++ b/crates/ra_ide_api/src/completion/complete_dot.rs
@@ -59,8 +59,7 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty)
59fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) { 59fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) {
60 let mut seen_methods = FxHashSet::default(); 60 let mut seen_methods = FxHashSet::default();
61 ctx.analyzer.iterate_method_candidates(ctx.db, receiver, None, |_ty, func| { 61 ctx.analyzer.iterate_method_candidates(ctx.db, receiver, None, |_ty, func| {
62 let data = func.data(ctx.db); 62 if func.has_self_param(ctx.db) && seen_methods.insert(func.name(ctx.db)) {
63 if data.has_self_param() && seen_methods.insert(data.name().clone()) {
64 acc.add_function(ctx, func); 63 acc.add_function(ctx, func);
65 } 64 }
66 None::<()> 65 None::<()>
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs
index 5d974cf6d..802c7701a 100644
--- a/crates/ra_ide_api/src/completion/complete_path.rs
+++ b/crates/ra_ide_api/src/completion/complete_path.rs
@@ -53,8 +53,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
53 ctx.analyzer.iterate_path_candidates(ctx.db, ty.clone(), None, |_ty, item| { 53 ctx.analyzer.iterate_path_candidates(ctx.db, ty.clone(), None, |_ty, item| {
54 match item { 54 match item {
55 hir::AssocItem::Function(func) => { 55 hir::AssocItem::Function(func) => {
56 let data = func.data(ctx.db); 56 if !func.has_self_param(ctx.db) {
57 if !data.has_self_param() {
58 acc.add_function(ctx, func); 57 acc.add_function(ctx, func);
59 } 58 }
60 } 59 }
@@ -80,8 +79,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
80 for item in t.items(ctx.db) { 79 for item in t.items(ctx.db) {
81 match item { 80 match item {
82 hir::AssocItem::Function(func) => { 81 hir::AssocItem::Function(func) => {
83 let data = func.data(ctx.db); 82 if !func.has_self_param(ctx.db) {
84 if !data.has_self_param() {
85 acc.add_function(ctx, func); 83 acc.add_function(ctx, func);
86 } 84 }
87 } 85 }
diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs
index bd464d193..896ad1517 100644
--- a/crates/ra_ide_api/src/completion/presentation.rs
+++ b/crates/ra_ide_api/src/completion/presentation.rs
@@ -199,14 +199,17 @@ impl Completions {
199 name: Option<String>, 199 name: Option<String>,
200 func: hir::Function, 200 func: hir::Function,
201 ) { 201 ) {
202 let data = func.data(ctx.db); 202 let func_name = func.name(ctx.db);
203 let name = name.unwrap_or_else(|| data.name().to_string()); 203 let has_self_param = func.has_self_param(ctx.db);
204 let params = func.params(ctx.db);
205
206 let name = name.unwrap_or_else(|| func_name.to_string());
204 let ast_node = func.source(ctx.db).value; 207 let ast_node = func.source(ctx.db).value;
205 let detail = function_label(&ast_node); 208 let detail = function_label(&ast_node);
206 209
207 let mut builder = 210 let mut builder =
208 CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.clone()) 211 CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.clone())
209 .kind(if data.has_self_param() { 212 .kind(if has_self_param {
210 CompletionItemKind::Method 213 CompletionItemKind::Method
211 } else { 214 } else {
212 CompletionItemKind::Function 215 CompletionItemKind::Function
@@ -221,12 +224,11 @@ impl Completions {
221 && ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis") 224 && ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis")
222 { 225 {
223 tested_by!(inserts_parens_for_function_calls); 226 tested_by!(inserts_parens_for_function_calls);
224 let (snippet, label) = 227 let (snippet, label) = if params.is_empty() || has_self_param && params.len() == 1 {
225 if data.params().is_empty() || data.has_self_param() && data.params().len() == 1 { 228 (format!("{}()$0", func_name), format!("{}()", name))
226 (format!("{}()$0", data.name()), format!("{}()", name)) 229 } else {
227 } else { 230 (format!("{}($0)", func_name), format!("{}(…)", name))
228 (format!("{}($0)", data.name()), format!("{}(…)", name)) 231 };
229 };
230 builder = builder.lookup_by(name).label(label).insert_snippet(snippet); 232 builder = builder.lookup_by(name).label(label).insert_snippet(snippet);
231 } 233 }
232 234