diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 89 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/impl_block.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir_def/src/data.rs | 192 | ||||
-rw-r--r-- | crates/ra_hir_def/src/db.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir_def/src/impls.rs | 86 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_def/src/traits.rs | 66 | ||||
-rw-r--r-- | crates/ra_hir_def/src/type_alias.rs | 27 | ||||
-rw-r--r-- | crates/ra_ide_api/src/call_info.rs | 4 | ||||
-rw-r--r-- | crates/ra_ide_api/src/change.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_dot.rs | 3 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_path.rs | 6 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/presentation.rs | 20 |
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)] | ||
565 | pub 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 | |||
574 | impl 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 | |||
635 | impl Function { | 564 | impl 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 | ||
23 | pub use hir_def::db::{ | 23 | pub 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 | }; |
29 | pub use hir_expand::db::{ | 29 | pub 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)] |
37 | pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { | 37 | pub 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 | ||
19 | impl ImplBlock { | 19 | impl 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}; | |||
22 | use rustc_hash::FxHashMap; | 22 | use rustc_hash::FxHashMap; |
23 | 23 | ||
24 | use hir_def::{ | 24 | use 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 | ||
50 | macro_rules! ty_app { | 51 | macro_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 | ||
624 | fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { | 624 | fn 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 | |||
3 | use std::sync::Arc; | ||
4 | |||
5 | use hir_expand::{ | ||
6 | name::{self, AsName, Name}, | ||
7 | AstId, | ||
8 | }; | ||
9 | use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; | ||
10 | |||
11 | use 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)] | ||
19 | pub 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 | |||
28 | impl 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)] | ||
70 | pub struct TypeAliasData { | ||
71 | pub name: Name, | ||
72 | pub type_ref: Option<TypeRef>, | ||
73 | } | ||
74 | |||
75 | impl 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)] | ||
88 | pub struct TraitData { | ||
89 | pub name: Option<Name>, | ||
90 | pub items: Vec<AssocItemId>, | ||
91 | pub auto: bool, | ||
92 | } | ||
93 | |||
94 | impl 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)] | ||
139 | pub 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 | |||
146 | impl 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; | |||
8 | use crate::{ | 8 | use 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 | |||
6 | use std::sync::Arc; | ||
7 | |||
8 | use hir_expand::AstId; | ||
9 | use ra_syntax::ast; | ||
10 | |||
11 | use crate::{ | ||
12 | db::DefDatabase2, type_ref::TypeRef, AssocItemId, AstItemDef, ConstLoc, ContainerId, | ||
13 | FunctionLoc, ImplId, Intern, TypeAliasLoc, | ||
14 | }; | ||
15 | |||
16 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
17 | pub struct ImplData { | ||
18 | target_trait: Option<TypeRef>, | ||
19 | target_type: TypeRef, | ||
20 | items: Vec<AssocItemId>, | ||
21 | negative: bool, | ||
22 | } | ||
23 | |||
24 | impl 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; | |||
13 | pub mod type_ref; | 13 | pub mod type_ref; |
14 | pub mod builtin_type; | 14 | pub mod builtin_type; |
15 | pub mod adt; | 15 | pub mod adt; |
16 | pub mod impls; | ||
17 | pub mod diagnostics; | 16 | pub mod diagnostics; |
18 | pub mod expr; | 17 | pub mod expr; |
19 | pub mod body; | 18 | pub mod body; |
20 | pub mod generics; | 19 | pub mod generics; |
21 | pub mod traits; | ||
22 | pub mod resolver; | 20 | pub mod resolver; |
23 | pub mod type_alias; | 21 | pub mod data; |
24 | 22 | ||
25 | #[cfg(test)] | 23 | #[cfg(test)] |
26 | mod test_db; | 24 | mod 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 | |||
3 | use std::sync::Arc; | ||
4 | |||
5 | use hir_expand::{ | ||
6 | name::{AsName, Name}, | ||
7 | AstId, | ||
8 | }; | ||
9 | |||
10 | use ra_syntax::ast::{self, NameOwner}; | ||
11 | |||
12 | use crate::{ | ||
13 | db::DefDatabase2, AssocItemId, AstItemDef, ConstLoc, ContainerId, FunctionLoc, Intern, TraitId, | ||
14 | TypeAliasId, TypeAliasLoc, | ||
15 | }; | ||
16 | |||
17 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
18 | pub struct TraitData { | ||
19 | pub name: Option<Name>, | ||
20 | pub items: Vec<AssocItemId>, | ||
21 | pub auto: bool, | ||
22 | } | ||
23 | |||
24 | impl 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 | |||
3 | use std::sync::Arc; | ||
4 | |||
5 | use hir_expand::name::{AsName, Name}; | ||
6 | |||
7 | use ra_syntax::ast::NameOwner; | ||
8 | |||
9 | use crate::{db::DefDatabase2, type_ref::TypeRef, HasSource, Lookup, TypeAliasId}; | ||
10 | |||
11 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
12 | pub struct TypeAliasData { | ||
13 | pub name: Name, | ||
14 | pub type_ref: Option<TypeRef>, | ||
15 | } | ||
16 | |||
17 | impl 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) | |||
59 | fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) { | 59 | fn 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 | ||