aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2020-04-27 23:40:32 +0100
committerJonas Schievink <[email protected]>2020-04-29 23:10:30 +0100
commit8c2670026a4c864a67a06bab654e203ed068f021 (patch)
tree95ed082f04067bcacfb40b1b871b64df3eb4be61 /crates/ra_hir
parent4ff3573e18114e044ed74e785f099a023ebfbf5d (diff)
Complete assoc. items on type parameters
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/code_model.rs10
-rw-r--r--crates/ra_hir/src/semantics.rs47
2 files changed, 56 insertions, 1 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 3fb419571..af59aa1b6 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -953,6 +953,16 @@ impl TypeParam {
953 pub fn module(self, db: &dyn HirDatabase) -> Module { 953 pub fn module(self, db: &dyn HirDatabase) -> Module {
954 self.id.parent.module(db.upcast()).into() 954 self.id.parent.module(db.upcast()).into()
955 } 955 }
956
957 pub fn ty(self, db: &dyn HirDatabase) -> Type {
958 let resolver = self.id.parent.resolver(db.upcast());
959 let environment = TraitEnvironment::lower(db, &resolver);
960 let ty = Ty::Placeholder(self.id);
961 Type {
962 krate: self.id.parent.module(db.upcast()).krate,
963 ty: InEnvironment { value: ty, environment },
964 }
965 }
956} 966}
957 967
958// FIXME: rename from `ImplDef` to `Impl` 968// FIXME: rename from `ImplDef` to `Impl`
diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs
index 86bfb416c..687f83f60 100644
--- a/crates/ra_hir/src/semantics.rs
+++ b/crates/ra_hir/src/semantics.rs
@@ -9,6 +9,7 @@ use hir_def::{
9 AsMacroCall, TraitId, 9 AsMacroCall, TraitId,
10}; 10};
11use hir_expand::ExpansionInfo; 11use hir_expand::ExpansionInfo;
12use hir_ty::associated_types;
12use itertools::Itertools; 13use itertools::Itertools;
13use ra_db::{FileId, FileRange}; 14use ra_db::{FileId, FileRange};
14use ra_prof::profile; 15use ra_prof::profile;
@@ -24,8 +25,9 @@ use crate::{
24 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, 25 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
25 source_analyzer::{resolve_hir_path, SourceAnalyzer}, 26 source_analyzer::{resolve_hir_path, SourceAnalyzer},
26 AssocItem, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, Module, ModuleDef, 27 AssocItem, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, Module, ModuleDef,
27 Name, Origin, Path, ScopeDef, Trait, Type, TypeParam, 28 Name, Origin, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam,
28}; 29};
30use resolver::TypeNs;
29 31
30#[derive(Debug, Clone, PartialEq, Eq)] 32#[derive(Debug, Clone, PartialEq, Eq)]
31pub enum PathResolution { 33pub enum PathResolution {
@@ -40,6 +42,49 @@ pub enum PathResolution {
40 AssocItem(AssocItem), 42 AssocItem(AssocItem),
41} 43}
42 44
45impl PathResolution {
46 fn in_type_ns(self) -> Option<TypeNs> {
47 match self {
48 PathResolution::Def(ModuleDef::Adt(adt)) => Some(TypeNs::AdtId(adt.into())),
49 PathResolution::Def(ModuleDef::BuiltinType(builtin)) => {
50 Some(TypeNs::BuiltinType(builtin))
51 }
52 PathResolution::Def(ModuleDef::Const(_)) => None,
53 PathResolution::Def(ModuleDef::EnumVariant(_)) => None,
54 PathResolution::Def(ModuleDef::Function(_)) => None,
55 PathResolution::Def(ModuleDef::Module(_)) => None,
56 PathResolution::Def(ModuleDef::Static(_)) => None,
57 PathResolution::Def(ModuleDef::Trait(_)) => None,
58 PathResolution::Def(ModuleDef::TypeAlias(alias)) => {
59 Some(TypeNs::TypeAliasId(alias.into()))
60 }
61 PathResolution::Local(_) => None,
62 PathResolution::TypeParam(param) => Some(TypeNs::GenericParam(param.into())),
63 PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType(impl_def.into())),
64 PathResolution::Macro(_) => None,
65 PathResolution::AssocItem(AssocItem::Const(_)) => None,
66 PathResolution::AssocItem(AssocItem::Function(_)) => None,
67 PathResolution::AssocItem(AssocItem::TypeAlias(alias)) => {
68 Some(TypeNs::TypeAliasId(alias.into()))
69 }
70 }
71 }
72
73 /// Returns an iterator over associated types that may be specified after this path (using
74 /// `Ty::Assoc` syntax).
75 pub fn assoc_type_shorthand_candidates<R>(
76 &self,
77 db: &dyn HirDatabase,
78 mut cb: impl FnMut(TypeAlias) -> Option<R>,
79 ) -> Option<R> {
80 if let Some(res) = self.clone().in_type_ns() {
81 associated_types(db, res, |_, _, id| cb(id.into()))
82 } else {
83 None
84 }
85 }
86}
87
43/// Primary API to get semantic information, like types, from syntax trees. 88/// Primary API to get semantic information, like types, from syntax trees.
44pub struct Semantics<'db, DB> { 89pub struct Semantics<'db, DB> {
45 pub db: &'db DB, 90 pub db: &'db DB,