diff options
author | Florian Diebold <[email protected]> | 2018-12-24 19:32:39 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2018-12-25 14:16:42 +0000 |
commit | 4ff161852016c6c15954d6f30bd637834a2b2b68 (patch) | |
tree | 7ea2d34a8f58f5a242481e6d6294bef22546fcaf /crates | |
parent | b5b68f2094d49cacde6d7f0c49f521a0b25f34bd (diff) |
Do name resolution by namespace (types/values)
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_analysis/src/completion/complete_path.rs | 2 | ||||
-rw-r--r-- | crates/ra_analysis/src/completion/completion_item.rs | 35 | ||||
-rw-r--r-- | crates/ra_analysis/src/db.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 25 | ||||
-rw-r--r-- | crates/ra_hir/src/module.rs | 42 | ||||
-rw-r--r-- | crates/ra_hir/src/module/nameres.rs | 154 | ||||
-rw-r--r-- | crates/ra_hir/src/module/nameres/tests.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 22 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/data/0004_struct.txt | 4 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/conv.rs | 2 |
10 files changed, 212 insertions, 84 deletions
diff --git a/crates/ra_analysis/src/completion/complete_path.rs b/crates/ra_analysis/src/completion/complete_path.rs index ad4d68a33..8c00be499 100644 --- a/crates/ra_analysis/src/completion/complete_path.rs +++ b/crates/ra_analysis/src/completion/complete_path.rs | |||
@@ -8,7 +8,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) -> C | |||
8 | (Some(path), Some(module)) => (path.clone(), module), | 8 | (Some(path), Some(module)) => (path.clone(), module), |
9 | _ => return Ok(()), | 9 | _ => return Ok(()), |
10 | }; | 10 | }; |
11 | let def_id = match module.resolve_path(ctx.db, path)? { | 11 | let def_id = match module.resolve_path(ctx.db, path)?.take_types() { |
12 | Some(it) => it, | 12 | Some(it) => it, |
13 | None => return Ok(()), | 13 | None => return Ok(()), |
14 | }; | 14 | }; |
diff --git a/crates/ra_analysis/src/completion/completion_item.rs b/crates/ra_analysis/src/completion/completion_item.rs index 911f08468..6d466c8bd 100644 --- a/crates/ra_analysis/src/completion/completion_item.rs +++ b/crates/ra_analysis/src/completion/completion_item.rs | |||
@@ -1,5 +1,7 @@ | |||
1 | use crate::db; | 1 | use crate::db; |
2 | 2 | ||
3 | use hir::PerNs; | ||
4 | |||
3 | /// `CompletionItem` describes a single completion variant in the editor pop-up. | 5 | /// `CompletionItem` describes a single completion variant in the editor pop-up. |
4 | /// It is basically a POD with various properties. To construct a | 6 | /// It is basically a POD with various properties. To construct a |
5 | /// `CompletionItem`, use `new` method and the `Builder` struct. | 7 | /// `CompletionItem`, use `new` method and the `Builder` struct. |
@@ -25,6 +27,8 @@ pub enum CompletionItemKind { | |||
25 | Keyword, | 27 | Keyword, |
26 | Module, | 28 | Module, |
27 | Function, | 29 | Function, |
30 | Struct, | ||
31 | Enum, | ||
28 | Binding, | 32 | Binding, |
29 | } | 33 | } |
30 | 34 | ||
@@ -117,16 +121,27 @@ impl Builder { | |||
117 | db: &db::RootDatabase, | 121 | db: &db::RootDatabase, |
118 | resolution: &hir::Resolution, | 122 | resolution: &hir::Resolution, |
119 | ) -> Builder { | 123 | ) -> Builder { |
120 | if let Some(def_id) = resolution.def_id { | 124 | let resolved = resolution.def_id.and_then(|d| d.resolve(db).ok()); |
121 | if let Ok(def) = def_id.resolve(db) { | 125 | let kind = match resolved { |
122 | let kind = match def { | 126 | PerNs { |
123 | hir::Def::Module(..) => CompletionItemKind::Module, | 127 | types: Some(hir::Def::Module(..)), |
124 | hir::Def::Function(..) => CompletionItemKind::Function, | 128 | .. |
125 | _ => return self, | 129 | } => CompletionItemKind::Module, |
126 | }; | 130 | PerNs { |
127 | self.kind = Some(kind); | 131 | types: Some(hir::Def::Struct(..)), |
128 | } | 132 | .. |
129 | } | 133 | } => CompletionItemKind::Struct, |
134 | PerNs { | ||
135 | types: Some(hir::Def::Enum(..)), | ||
136 | .. | ||
137 | } => CompletionItemKind::Enum, | ||
138 | PerNs { | ||
139 | values: Some(hir::Def::Function(..)), | ||
140 | .. | ||
141 | } => CompletionItemKind::Function, | ||
142 | _ => return self, | ||
143 | }; | ||
144 | self.kind = Some(kind); | ||
130 | self | 145 | self |
131 | } | 146 | } |
132 | } | 147 | } |
diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs index 7043a0f4d..677745d57 100644 --- a/crates/ra_analysis/src/db.rs +++ b/crates/ra_analysis/src/db.rs | |||
@@ -95,8 +95,8 @@ salsa::database_storage! { | |||
95 | fn submodules() for hir::db::SubmodulesQuery; | 95 | fn submodules() for hir::db::SubmodulesQuery; |
96 | fn infer() for hir::db::InferQuery; | 96 | fn infer() for hir::db::InferQuery; |
97 | fn type_for_def() for hir::db::TypeForDefQuery; | 97 | fn type_for_def() for hir::db::TypeForDefQuery; |
98 | fn struct_data() for db::StructDataQuery; | 98 | fn struct_data() for hir::db::StructDataQuery; |
99 | fn enum_data() for db::EnumDataQuery; | 99 | fn enum_data() for hir::db::EnumDataQuery; |
100 | } | 100 | } |
101 | } | 101 | } |
102 | } | 102 | } |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 7e9824de9..81526fe9c 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -41,7 +41,7 @@ use crate::{ | |||
41 | pub use self::{ | 41 | pub use self::{ |
42 | path::{Path, PathKind}, | 42 | path::{Path, PathKind}, |
43 | krate::Crate, | 43 | krate::Crate, |
44 | module::{Module, ModuleId, Problem, nameres::ItemMap, ModuleScope, Resolution}, | 44 | module::{Module, ModuleId, Problem, nameres::{ItemMap, PerNs, Namespace}, ModuleScope, Resolution}, |
45 | function::{Function, FnScopes}, | 45 | function::{Function, FnScopes}, |
46 | adt::{Struct, Enum}, | 46 | adt::{Struct, Enum}, |
47 | }; | 47 | }; |
@@ -61,6 +61,8 @@ pub(crate) enum DefKind { | |||
61 | Struct, | 61 | Struct, |
62 | Enum, | 62 | Enum, |
63 | Item, | 63 | Item, |
64 | |||
65 | StructCtor, | ||
64 | } | 66 | } |
65 | 67 | ||
66 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | 68 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] |
@@ -72,18 +74,18 @@ pub struct DefLoc { | |||
72 | } | 74 | } |
73 | 75 | ||
74 | impl DefKind { | 76 | impl DefKind { |
75 | pub(crate) fn for_syntax_kind(kind: SyntaxKind) -> Option<DefKind> { | 77 | pub(crate) fn for_syntax_kind(kind: SyntaxKind) -> PerNs<DefKind> { |
76 | match kind { | 78 | match kind { |
77 | SyntaxKind::FN_DEF => Some(DefKind::Function), | 79 | SyntaxKind::FN_DEF => PerNs::values(DefKind::Function), |
78 | SyntaxKind::MODULE => Some(DefKind::Module), | 80 | SyntaxKind::MODULE => PerNs::types(DefKind::Module), |
81 | SyntaxKind::STRUCT_DEF => PerNs::both(DefKind::Struct, DefKind::StructCtor), | ||
82 | SyntaxKind::ENUM_DEF => PerNs::types(DefKind::Enum), | ||
79 | // These define items, but don't have their own DefKinds yet: | 83 | // These define items, but don't have their own DefKinds yet: |
80 | SyntaxKind::STRUCT_DEF => Some(DefKind::Struct), | 84 | SyntaxKind::TRAIT_DEF => PerNs::types(DefKind::Item), |
81 | SyntaxKind::ENUM_DEF => Some(DefKind::Enum), | 85 | SyntaxKind::TYPE_DEF => PerNs::types(DefKind::Item), |
82 | SyntaxKind::TRAIT_DEF => Some(DefKind::Item), | 86 | SyntaxKind::CONST_DEF => PerNs::values(DefKind::Item), |
83 | SyntaxKind::TYPE_DEF => Some(DefKind::Item), | 87 | SyntaxKind::STATIC_DEF => PerNs::values(DefKind::Item), |
84 | SyntaxKind::CONST_DEF => Some(DefKind::Item), | 88 | _ => PerNs::none(), |
85 | SyntaxKind::STATIC_DEF => Some(DefKind::Item), | ||
86 | _ => None, | ||
87 | } | 89 | } |
88 | } | 90 | } |
89 | } | 91 | } |
@@ -128,6 +130,7 @@ impl DefId { | |||
128 | let enum_def = Enum::new(self); | 130 | let enum_def = Enum::new(self); |
129 | Def::Enum(enum_def) | 131 | Def::Enum(enum_def) |
130 | } | 132 | } |
133 | DefKind::StructCtor => Def::Item, | ||
131 | DefKind::Item => Def::Item, | 134 | DefKind::Item => Def::Item, |
132 | }; | 135 | }; |
133 | Ok(res) | 136 | Ok(res) |
diff --git a/crates/ra_hir/src/module.rs b/crates/ra_hir/src/module.rs index 891119953..e1a0e4b59 100644 --- a/crates/ra_hir/src/module.rs +++ b/crates/ra_hir/src/module.rs | |||
@@ -17,7 +17,7 @@ use crate::{ | |||
17 | arena::{Arena, Id}, | 17 | arena::{Arena, Id}, |
18 | }; | 18 | }; |
19 | 19 | ||
20 | pub use self::nameres::{ModuleScope, Resolution}; | 20 | pub use self::nameres::{ModuleScope, Resolution, Namespace, PerNs}; |
21 | 21 | ||
22 | /// `Module` is API entry point to get all the information | 22 | /// `Module` is API entry point to get all the information |
23 | /// about a particular module. | 23 | /// about a particular module. |
@@ -115,16 +115,29 @@ impl Module { | |||
115 | Ok(res) | 115 | Ok(res) |
116 | } | 116 | } |
117 | 117 | ||
118 | pub fn resolve_path(&self, db: &impl HirDatabase, path: Path) -> Cancelable<Option<DefId>> { | 118 | pub fn resolve_path(&self, db: &impl HirDatabase, path: Path) -> Cancelable<PerNs<DefId>> { |
119 | let mut curr = match path.kind { | 119 | let mut curr_per_ns = PerNs::types( |
120 | PathKind::Crate => self.crate_root(), | 120 | match path.kind { |
121 | PathKind::Self_ | PathKind::Plain => self.clone(), | 121 | PathKind::Crate => self.crate_root(), |
122 | PathKind::Super => ctry!(self.parent()), | 122 | PathKind::Self_ | PathKind::Plain => self.clone(), |
123 | } | 123 | PathKind::Super => { |
124 | .def_id(db); | 124 | if let Some(p) = self.parent() { |
125 | p | ||
126 | } else { | ||
127 | return Ok(PerNs::none()); | ||
128 | } | ||
129 | } | ||
130 | } | ||
131 | .def_id(db), | ||
132 | ); | ||
125 | 133 | ||
126 | let segments = path.segments; | 134 | let segments = path.segments; |
127 | for name in segments.iter() { | 135 | for name in segments.iter() { |
136 | let curr = if let Some(r) = curr_per_ns.as_ref().take(Namespace::Types) { | ||
137 | r | ||
138 | } else { | ||
139 | return Ok(PerNs::none()); | ||
140 | }; | ||
128 | let module = match curr.loc(db) { | 141 | let module = match curr.loc(db) { |
129 | DefLoc { | 142 | DefLoc { |
130 | kind: DefKind::Module, | 143 | kind: DefKind::Module, |
@@ -132,12 +145,17 @@ impl Module { | |||
132 | module_id, | 145 | module_id, |
133 | .. | 146 | .. |
134 | } => Module::new(db, source_root_id, module_id)?, | 147 | } => Module::new(db, source_root_id, module_id)?, |
135 | _ => return Ok(None), | 148 | // TODO here would be the place to handle enum variants... |
149 | _ => return Ok(PerNs::none()), | ||
136 | }; | 150 | }; |
137 | let scope = module.scope(db)?; | 151 | let scope = module.scope(db)?; |
138 | curr = ctry!(ctry!(scope.get(&name)).def_id); | 152 | curr_per_ns = if let Some(r) = scope.get(&name) { |
153 | r.def_id | ||
154 | } else { | ||
155 | return Ok(PerNs::none()); | ||
156 | }; | ||
139 | } | 157 | } |
140 | Ok(Some(curr)) | 158 | Ok(curr_per_ns) |
141 | } | 159 | } |
142 | 160 | ||
143 | pub fn problems(&self, db: &impl HirDatabase) -> Vec<(SyntaxNode, Problem)> { | 161 | pub fn problems(&self, db: &impl HirDatabase) -> Vec<(SyntaxNode, Problem)> { |
@@ -145,7 +163,7 @@ impl Module { | |||
145 | } | 163 | } |
146 | } | 164 | } |
147 | 165 | ||
148 | /// Phisically, rust source is organized as a set of files, but logically it is | 166 | /// Physically, rust source is organized as a set of files, but logically it is |
149 | /// organized as a tree of modules. Usually, a single file corresponds to a | 167 | /// organized as a tree of modules. Usually, a single file corresponds to a |
150 | /// single module, but it is not nessary the case. | 168 | /// single module, but it is not nessary the case. |
151 | /// | 169 | /// |
diff --git a/crates/ra_hir/src/module/nameres.rs b/crates/ra_hir/src/module/nameres.rs index 0b152a406..33c9d93c2 100644 --- a/crates/ra_hir/src/module/nameres.rs +++ b/crates/ra_hir/src/module/nameres.rs | |||
@@ -118,22 +118,96 @@ enum ImportKind { | |||
118 | #[derive(Debug, Clone, PartialEq, Eq)] | 118 | #[derive(Debug, Clone, PartialEq, Eq)] |
119 | pub struct Resolution { | 119 | pub struct Resolution { |
120 | /// None for unresolved | 120 | /// None for unresolved |
121 | pub def_id: Option<DefId>, | 121 | pub def_id: PerNs<DefId>, |
122 | /// ident by whitch this is imported into local scope. | 122 | /// ident by whitch this is imported into local scope. |
123 | pub import: Option<NamedImport>, | 123 | pub import: Option<NamedImport>, |
124 | } | 124 | } |
125 | 125 | ||
126 | // #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] | 126 | #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] |
127 | // enum Namespace { | 127 | pub enum Namespace { |
128 | // Types, | 128 | Types, |
129 | // Values, | 129 | Values, |
130 | // } | 130 | } |
131 | |||
132 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | ||
133 | pub struct PerNs<T> { | ||
134 | pub types: Option<T>, | ||
135 | pub values: Option<T>, | ||
136 | } | ||
137 | |||
138 | impl<T> PerNs<T> { | ||
139 | pub fn none() -> PerNs<T> { | ||
140 | PerNs { | ||
141 | types: None, | ||
142 | values: None, | ||
143 | } | ||
144 | } | ||
145 | |||
146 | pub fn values(t: T) -> PerNs<T> { | ||
147 | PerNs { | ||
148 | types: None, | ||
149 | values: Some(t), | ||
150 | } | ||
151 | } | ||
152 | |||
153 | pub fn types(t: T) -> PerNs<T> { | ||
154 | PerNs { | ||
155 | types: Some(t), | ||
156 | values: None, | ||
157 | } | ||
158 | } | ||
159 | |||
160 | pub fn both(types: T, values: T) -> PerNs<T> { | ||
161 | PerNs { | ||
162 | types: Some(types), | ||
163 | values: Some(values), | ||
164 | } | ||
165 | } | ||
166 | |||
167 | pub fn is_none(&self) -> bool { | ||
168 | self.types.is_none() && self.values.is_none() | ||
169 | } | ||
170 | |||
171 | pub fn take(self, namespace: Namespace) -> Option<T> { | ||
172 | match namespace { | ||
173 | Namespace::Types => self.types, | ||
174 | Namespace::Values => self.values, | ||
175 | } | ||
176 | } | ||
177 | |||
178 | pub fn take_types(self) -> Option<T> { | ||
179 | self.types | ||
180 | } | ||
181 | |||
182 | pub fn take_values(self) -> Option<T> { | ||
183 | self.values | ||
184 | } | ||
131 | 185 | ||
132 | // #[derive(Debug)] | 186 | pub fn get(&self, namespace: Namespace) -> Option<&T> { |
133 | // struct PerNs<T> { | 187 | self.as_ref().take(namespace) |
134 | // types: Option<T>, | 188 | } |
135 | // values: Option<T>, | 189 | |
136 | // } | 190 | pub fn as_ref(&self) -> PerNs<&T> { |
191 | PerNs { | ||
192 | types: self.types.as_ref(), | ||
193 | values: self.values.as_ref(), | ||
194 | } | ||
195 | } | ||
196 | |||
197 | pub fn and_then<U>(self, f: impl Fn(T) -> Option<U>) -> PerNs<U> { | ||
198 | PerNs { | ||
199 | types: self.types.and_then(&f), | ||
200 | values: self.values.and_then(&f), | ||
201 | } | ||
202 | } | ||
203 | |||
204 | pub fn map<U>(self, f: impl Fn(T) -> U) -> PerNs<U> { | ||
205 | PerNs { | ||
206 | types: self.types.map(&f), | ||
207 | values: self.values.map(&f), | ||
208 | } | ||
209 | } | ||
210 | } | ||
137 | 211 | ||
138 | impl InputModuleItems { | 212 | impl InputModuleItems { |
139 | pub(crate) fn new<'a>( | 213 | pub(crate) fn new<'a>( |
@@ -254,7 +328,7 @@ where | |||
254 | for dep in krate.dependencies(self.db) { | 328 | for dep in krate.dependencies(self.db) { |
255 | if let Some(module) = dep.krate.root_module(self.db)? { | 329 | if let Some(module) = dep.krate.root_module(self.db)? { |
256 | let def_id = module.def_id(self.db); | 330 | let def_id = module.def_id(self.db); |
257 | self.add_module_item(&mut module_items, dep.name, def_id); | 331 | self.add_module_item(&mut module_items, dep.name, PerNs::types(def_id)); |
258 | } | 332 | } |
259 | } | 333 | } |
260 | }; | 334 | }; |
@@ -265,7 +339,7 @@ where | |||
265 | module_items.items.insert( | 339 | module_items.items.insert( |
266 | name.clone(), | 340 | name.clone(), |
267 | Resolution { | 341 | Resolution { |
268 | def_id: None, | 342 | def_id: PerNs::none(), |
269 | import: Some(import), | 343 | import: Some(import), |
270 | }, | 344 | }, |
271 | ); | 345 | ); |
@@ -277,18 +351,23 @@ where | |||
277 | if item.kind == MODULE { | 351 | if item.kind == MODULE { |
278 | continue; | 352 | continue; |
279 | } | 353 | } |
280 | let def_loc = DefLoc { | 354 | // depending on the item kind, the location can define something in |
281 | kind: DefKind::for_syntax_kind(item.kind).unwrap_or(DefKind::Item), | 355 | // the values namespace, the types namespace, or both |
282 | source_root_id: self.source_root, | 356 | let kind = DefKind::for_syntax_kind(item.kind); |
283 | module_id, | 357 | let def_id = kind.map(|k| { |
284 | source_item_id: SourceItemId { | 358 | let def_loc = DefLoc { |
285 | file_id, | 359 | kind: k, |
286 | item_id: Some(item.id), | 360 | source_root_id: self.source_root, |
287 | }, | 361 | module_id, |
288 | }; | 362 | source_item_id: SourceItemId { |
289 | let def_id = def_loc.id(self.db); | 363 | file_id, |
364 | item_id: Some(item.id), | ||
365 | }, | ||
366 | }; | ||
367 | def_loc.id(self.db) | ||
368 | }); | ||
290 | let resolution = Resolution { | 369 | let resolution = Resolution { |
291 | def_id: Some(def_id), | 370 | def_id, |
292 | import: None, | 371 | import: None, |
293 | }; | 372 | }; |
294 | module_items.items.insert(item.name.clone(), resolution); | 373 | module_items.items.insert(item.name.clone(), resolution); |
@@ -303,16 +382,16 @@ where | |||
303 | source_item_id: module_id.source(&self.module_tree).0, | 382 | source_item_id: module_id.source(&self.module_tree).0, |
304 | }; | 383 | }; |
305 | let def_id = def_loc.id(self.db); | 384 | let def_id = def_loc.id(self.db); |
306 | self.add_module_item(&mut module_items, name, def_id); | 385 | self.add_module_item(&mut module_items, name, PerNs::types(def_id)); |
307 | } | 386 | } |
308 | 387 | ||
309 | self.result.per_module.insert(module_id, module_items); | 388 | self.result.per_module.insert(module_id, module_items); |
310 | Ok(()) | 389 | Ok(()) |
311 | } | 390 | } |
312 | 391 | ||
313 | fn add_module_item(&self, module_items: &mut ModuleScope, name: SmolStr, def_id: DefId) { | 392 | fn add_module_item(&self, module_items: &mut ModuleScope, name: SmolStr, def_id: PerNs<DefId>) { |
314 | let resolution = Resolution { | 393 | let resolution = Resolution { |
315 | def_id: Some(def_id), | 394 | def_id, |
316 | import: None, | 395 | import: None, |
317 | }; | 396 | }; |
318 | module_items.items.insert(name, resolution); | 397 | module_items.items.insert(name, resolution); |
@@ -347,15 +426,17 @@ where | |||
347 | let is_last = i == import.path.segments.len() - 1; | 426 | let is_last = i == import.path.segments.len() - 1; |
348 | 427 | ||
349 | let def_id = match self.result.per_module[&curr].items.get(name) { | 428 | let def_id = match self.result.per_module[&curr].items.get(name) { |
350 | None => return Ok(()), | 429 | Some(res) if !res.def_id.is_none() => res.def_id, |
351 | Some(res) => match res.def_id { | 430 | _ => return Ok(()), |
352 | Some(it) => it, | ||
353 | None => return Ok(()), | ||
354 | }, | ||
355 | }; | 431 | }; |
356 | 432 | ||
357 | if !is_last { | 433 | if !is_last { |
358 | curr = match def_id.loc(self.db) { | 434 | let type_def_id = if let Some(d) = def_id.take(Namespace::Types) { |
435 | d | ||
436 | } else { | ||
437 | return Ok(()); | ||
438 | }; | ||
439 | curr = match type_def_id.loc(self.db) { | ||
359 | DefLoc { | 440 | DefLoc { |
360 | kind: DefKind::Module, | 441 | kind: DefKind::Module, |
361 | module_id: target_module_id, | 442 | module_id: target_module_id, |
@@ -370,10 +451,11 @@ where | |||
370 | segments: import.path.segments[i + 1..].iter().cloned().collect(), | 451 | segments: import.path.segments[i + 1..].iter().cloned().collect(), |
371 | kind: PathKind::Crate, | 452 | kind: PathKind::Crate, |
372 | }; | 453 | }; |
373 | if let Some(def_id) = module.resolve_path(self.db, path)? { | 454 | let def_id = module.resolve_path(self.db, path)?; |
455 | if !def_id.is_none() { | ||
374 | self.update(module_id, |items| { | 456 | self.update(module_id, |items| { |
375 | let res = Resolution { | 457 | let res = Resolution { |
376 | def_id: Some(def_id), | 458 | def_id: def_id, |
377 | import: Some(ptr), | 459 | import: Some(ptr), |
378 | }; | 460 | }; |
379 | items.items.insert(name.clone(), res); | 461 | items.items.insert(name.clone(), res); |
@@ -387,7 +469,7 @@ where | |||
387 | } else { | 469 | } else { |
388 | self.update(module_id, |items| { | 470 | self.update(module_id, |items| { |
389 | let res = Resolution { | 471 | let res = Resolution { |
390 | def_id: Some(def_id), | 472 | def_id: def_id, |
391 | import: Some(ptr), | 473 | import: Some(ptr), |
392 | }; | 474 | }; |
393 | items.items.insert(name.clone(), res); | 475 | items.items.insert(name.clone(), res); |
diff --git a/crates/ra_hir/src/module/nameres/tests.rs b/crates/ra_hir/src/module/nameres/tests.rs index 3e29c3954..03ea5c1d6 100644 --- a/crates/ra_hir/src/module/nameres/tests.rs +++ b/crates/ra_hir/src/module/nameres/tests.rs | |||
@@ -40,7 +40,7 @@ fn item_map_smoke_test() { | |||
40 | ); | 40 | ); |
41 | let name = SmolStr::from("Baz"); | 41 | let name = SmolStr::from("Baz"); |
42 | let resolution = &item_map.per_module[&module_id].items[&name]; | 42 | let resolution = &item_map.per_module[&module_id].items[&name]; |
43 | assert!(resolution.def_id.is_some()); | 43 | assert!(resolution.def_id.take_types().is_some()); |
44 | } | 44 | } |
45 | 45 | ||
46 | #[test] | 46 | #[test] |
@@ -59,7 +59,7 @@ fn test_self() { | |||
59 | ); | 59 | ); |
60 | let name = SmolStr::from("Baz"); | 60 | let name = SmolStr::from("Baz"); |
61 | let resolution = &item_map.per_module[&module_id].items[&name]; | 61 | let resolution = &item_map.per_module[&module_id].items[&name]; |
62 | assert!(resolution.def_id.is_some()); | 62 | assert!(resolution.def_id.take_types().is_some()); |
63 | } | 63 | } |
64 | 64 | ||
65 | #[test] | 65 | #[test] |
@@ -92,7 +92,7 @@ fn item_map_across_crates() { | |||
92 | 92 | ||
93 | let name = SmolStr::from("Baz"); | 93 | let name = SmolStr::from("Baz"); |
94 | let resolution = &item_map.per_module[&module_id].items[&name]; | 94 | let resolution = &item_map.per_module[&module_id].items[&name]; |
95 | assert!(resolution.def_id.is_some()); | 95 | assert!(resolution.def_id.take_types().is_some()); |
96 | } | 96 | } |
97 | 97 | ||
98 | #[test] | 98 | #[test] |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index f86b749ec..429292cfc 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -15,7 +15,11 @@ use ra_syntax::{ | |||
15 | SyntaxNodeRef | 15 | SyntaxNodeRef |
16 | }; | 16 | }; |
17 | 17 | ||
18 | use crate::{Def, DefId, FnScopes, Module, Function, Path, db::HirDatabase}; | 18 | use crate::{ |
19 | Def, DefId, FnScopes, Module, Function, | ||
20 | Path, db::HirDatabase, | ||
21 | module::nameres::Namespace | ||
22 | }; | ||
19 | 23 | ||
20 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] | 24 | #[derive(Clone, PartialEq, Eq, Hash, Debug)] |
21 | pub enum Ty { | 25 | pub enum Ty { |
@@ -149,11 +153,12 @@ impl Ty { | |||
149 | } | 153 | } |
150 | 154 | ||
151 | // Resolve in module (in type namespace) | 155 | // Resolve in module (in type namespace) |
152 | let resolved = if let Some(r) = module.resolve_path(db, path)? { | 156 | let resolved = |
153 | r | 157 | if let Some(r) = module.resolve_path(db, path)?.take(Namespace::Types) { |
154 | } else { | 158 | r |
155 | return Ok(Ty::Unknown); | 159 | } else { |
156 | }; | 160 | return Ok(Ty::Unknown); |
161 | }; | ||
157 | let ty = db.type_for_def(resolved)?; | 162 | let ty = db.type_for_def(resolved)?; |
158 | ty | 163 | ty |
159 | } | 164 | } |
@@ -325,7 +330,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
325 | }; | 330 | }; |
326 | 331 | ||
327 | // resolve in module | 332 | // resolve in module |
328 | let resolved = ctry!(self.module.resolve_path(self.db, path)?); | 333 | let resolved = ctry!(self |
334 | .module | ||
335 | .resolve_path(self.db, path)? | ||
336 | .take(Namespace::Values)); | ||
329 | let ty = self.db.type_for_def(resolved)?; | 337 | let ty = self.db.type_for_def(resolved)?; |
330 | // TODO we will need to add type variables for type parameters etc. here | 338 | // TODO we will need to add type variables for type parameters etc. here |
331 | Ok(Some(ty)) | 339 | Ok(Some(ty)) |
diff --git a/crates/ra_hir/src/ty/tests/data/0004_struct.txt b/crates/ra_hir/src/ty/tests/data/0004_struct.txt index 70ad055ff..a4371c5a5 100644 --- a/crates/ra_hir/src/ty/tests/data/0004_struct.txt +++ b/crates/ra_hir/src/ty/tests/data/0004_struct.txt | |||
@@ -1,10 +1,10 @@ | |||
1 | [86; 90) 'C(1)': [unknown] | 1 | [86; 90) 'C(1)': [unknown] |
2 | [72; 153) '{ ...a.c; }': () | 2 | [72; 153) '{ ...a.c; }': () |
3 | [86; 87) 'C': C | 3 | [86; 87) 'C': [unknown] |
4 | [107; 108) 'a': A | 4 | [107; 108) 'a': A |
5 | [114; 132) 'A { b:... C() }': [unknown] | 5 | [114; 132) 'A { b:... C() }': [unknown] |
6 | [138; 141) 'a.b': [unknown] | 6 | [138; 141) 'a.b': [unknown] |
7 | [147; 150) 'a.c': [unknown] | 7 | [147; 150) 'a.c': [unknown] |
8 | [96; 97) 'B': B | 8 | [96; 97) 'B': [unknown] |
9 | [88; 89) '1': [unknown] | 9 | [88; 89) '1': [unknown] |
10 | [82; 83) 'c': [unknown] | 10 | [82; 83) 'c': [unknown] |
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index 051f1f995..af5289311 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs | |||
@@ -55,6 +55,8 @@ impl Conv for CompletionItemKind { | |||
55 | CompletionItemKind::Snippet => Snippet, | 55 | CompletionItemKind::Snippet => Snippet, |
56 | CompletionItemKind::Module => Module, | 56 | CompletionItemKind::Module => Module, |
57 | CompletionItemKind::Function => Function, | 57 | CompletionItemKind::Function => Function, |
58 | CompletionItemKind::Struct => Struct, | ||
59 | CompletionItemKind::Enum => Enum, | ||
58 | CompletionItemKind::Binding => Variable, | 60 | CompletionItemKind::Binding => Variable, |
59 | } | 61 | } |
60 | } | 62 | } |