diff options
Diffstat (limited to 'crates/ra_hir/src/resolve.rs')
-rw-r--r-- | crates/ra_hir/src/resolve.rs | 117 |
1 files changed, 61 insertions, 56 deletions
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index eca8e0596..f4165babd 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs | |||
@@ -3,19 +3,21 @@ use std::sync::Arc; | |||
3 | 3 | ||
4 | use hir_def::{ | 4 | use hir_def::{ |
5 | builtin_type::BuiltinType, | 5 | builtin_type::BuiltinType, |
6 | db::DefDatabase2, | ||
7 | generics::GenericParams, | ||
6 | nameres::CrateDefMap, | 8 | nameres::CrateDefMap, |
7 | path::{Path, PathKind}, | 9 | path::{Path, PathKind}, |
8 | AdtId, CrateModuleId, ModuleDefId, | 10 | AdtId, CrateModuleId, DefWithBodyId, EnumId, EnumVariantId, GenericDefId, ImplId, ModuleDefId, |
11 | StructId, TraitId, TypeAliasId, | ||
9 | }; | 12 | }; |
10 | use hir_expand::name::{self, Name}; | 13 | use hir_expand::name::{self, Name}; |
11 | use rustc_hash::FxHashSet; | 14 | use rustc_hash::FxHashSet; |
12 | 15 | ||
13 | use crate::{ | 16 | use crate::{ |
14 | code_model::Crate, | 17 | code_model::Crate, |
15 | db::{DefDatabase, HirDatabase}, | 18 | db::DefDatabase, |
16 | expr::{ExprScopes, PatId, ScopeId}, | 19 | expr::{ExprScopes, PatId, ScopeId}, |
17 | generics::{GenericParams, HasGenericParams}, | 20 | Adt, Const, Container, DefWithBody, EnumVariant, Function, GenericDef, ImplBlock, Local, |
18 | Adt, Const, Container, DefWithBody, Enum, EnumVariant, Function, GenericDef, ImplBlock, Local, | ||
19 | MacroDef, Module, ModuleDef, PerNs, Static, Struct, Trait, TypeAlias, | 21 | MacroDef, Module, ModuleDef, PerNs, Static, Struct, Trait, TypeAlias, |
20 | }; | 22 | }; |
21 | 23 | ||
@@ -33,7 +35,7 @@ pub(crate) struct ModuleItemMap { | |||
33 | 35 | ||
34 | #[derive(Debug, Clone)] | 36 | #[derive(Debug, Clone)] |
35 | pub(crate) struct ExprScope { | 37 | pub(crate) struct ExprScope { |
36 | owner: DefWithBody, | 38 | owner: DefWithBodyId, |
37 | expr_scopes: Arc<ExprScopes>, | 39 | expr_scopes: Arc<ExprScopes>, |
38 | scope_id: ScopeId, | 40 | scope_id: ScopeId, |
39 | } | 41 | } |
@@ -43,28 +45,28 @@ pub(crate) enum Scope { | |||
43 | /// All the items and imported names of a module | 45 | /// All the items and imported names of a module |
44 | ModuleScope(ModuleItemMap), | 46 | ModuleScope(ModuleItemMap), |
45 | /// Brings the generic parameters of an item into scope | 47 | /// Brings the generic parameters of an item into scope |
46 | GenericParams { def: GenericDef, params: Arc<GenericParams> }, | 48 | GenericParams { def: GenericDefId, params: Arc<GenericParams> }, |
47 | /// Brings `Self` in `impl` block into scope | 49 | /// Brings `Self` in `impl` block into scope |
48 | ImplBlockScope(ImplBlock), | 50 | ImplBlockScope(ImplId), |
49 | /// Brings `Self` in enum, struct and union definitions into scope | 51 | /// Brings `Self` in enum, struct and union definitions into scope |
50 | AdtScope(Adt), | 52 | AdtScope(AdtId), |
51 | /// Local bindings | 53 | /// Local bindings |
52 | ExprScope(ExprScope), | 54 | ExprScope(ExprScope), |
53 | } | 55 | } |
54 | 56 | ||
55 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 57 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
56 | pub(crate) enum TypeNs { | 58 | pub(crate) enum TypeNs { |
57 | SelfType(ImplBlock), | 59 | SelfType(ImplId), |
58 | GenericParam(u32), | 60 | GenericParam(u32), |
59 | Adt(Adt), | 61 | AdtId(AdtId), |
60 | AdtSelfType(Adt), | 62 | AdtSelfType(AdtId), |
61 | EnumVariant(EnumVariant), | 63 | EnumVariantId(EnumVariantId), |
62 | TypeAlias(TypeAlias), | 64 | TypeAliasId(TypeAliasId), |
63 | BuiltinType(BuiltinType), | 65 | BuiltinType(BuiltinType), |
64 | Trait(Trait), | 66 | TraitId(TraitId), |
65 | // Module belong to type ns, but the resolver is used when all module paths | 67 | // Module belong to type ns, but the resolver is used when all module paths |
66 | // are fully resolved. | 68 | // are fully resolved. |
67 | // Module(Module) | 69 | // ModuleId(ModuleId) |
68 | } | 70 | } |
69 | 71 | ||
70 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 72 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
@@ -85,10 +87,14 @@ pub(crate) enum ValueNs { | |||
85 | 87 | ||
86 | impl Resolver { | 88 | impl Resolver { |
87 | /// Resolve known trait from std, like `std::futures::Future` | 89 | /// Resolve known trait from std, like `std::futures::Future` |
88 | pub(crate) fn resolve_known_trait(&self, db: &impl HirDatabase, path: &Path) -> Option<Trait> { | 90 | pub(crate) fn resolve_known_trait( |
91 | &self, | ||
92 | db: &impl DefDatabase2, | ||
93 | path: &Path, | ||
94 | ) -> Option<TraitId> { | ||
89 | let res = self.resolve_module_path(db, path).take_types()?; | 95 | let res = self.resolve_module_path(db, path).take_types()?; |
90 | match res { | 96 | match res { |
91 | ModuleDefId::TraitId(it) => Some(it.into()), | 97 | ModuleDefId::TraitId(it) => Some(it), |
92 | _ => None, | 98 | _ => None, |
93 | } | 99 | } |
94 | } | 100 | } |
@@ -96,27 +102,27 @@ impl Resolver { | |||
96 | /// Resolve known struct from std, like `std::boxed::Box` | 102 | /// Resolve known struct from std, like `std::boxed::Box` |
97 | pub(crate) fn resolve_known_struct( | 103 | pub(crate) fn resolve_known_struct( |
98 | &self, | 104 | &self, |
99 | db: &impl HirDatabase, | 105 | db: &impl DefDatabase2, |
100 | path: &Path, | 106 | path: &Path, |
101 | ) -> Option<Struct> { | 107 | ) -> Option<StructId> { |
102 | let res = self.resolve_module_path(db, path).take_types()?; | 108 | let res = self.resolve_module_path(db, path).take_types()?; |
103 | match res { | 109 | match res { |
104 | ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it.into()), | 110 | ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it), |
105 | _ => None, | 111 | _ => None, |
106 | } | 112 | } |
107 | } | 113 | } |
108 | 114 | ||
109 | /// Resolve known enum from std, like `std::result::Result` | 115 | /// Resolve known enum from std, like `std::result::Result` |
110 | pub(crate) fn resolve_known_enum(&self, db: &impl HirDatabase, path: &Path) -> Option<Enum> { | 116 | pub(crate) fn resolve_known_enum(&self, db: &impl DefDatabase2, path: &Path) -> Option<EnumId> { |
111 | let res = self.resolve_module_path(db, path).take_types()?; | 117 | let res = self.resolve_module_path(db, path).take_types()?; |
112 | match res { | 118 | match res { |
113 | ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it.into()), | 119 | ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it), |
114 | _ => None, | 120 | _ => None, |
115 | } | 121 | } |
116 | } | 122 | } |
117 | 123 | ||
118 | /// pub only for source-binder | 124 | /// pub only for source-binder |
119 | pub(crate) fn resolve_module_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs { | 125 | pub(crate) fn resolve_module_path(&self, db: &impl DefDatabase2, path: &Path) -> PerNs { |
120 | let (item_map, module) = match self.module() { | 126 | let (item_map, module) = match self.module() { |
121 | Some(it) => it, | 127 | Some(it) => it, |
122 | None => return PerNs::none(), | 128 | None => return PerNs::none(), |
@@ -130,7 +136,7 @@ impl Resolver { | |||
130 | 136 | ||
131 | pub(crate) fn resolve_path_in_type_ns( | 137 | pub(crate) fn resolve_path_in_type_ns( |
132 | &self, | 138 | &self, |
133 | db: &impl HirDatabase, | 139 | db: &impl DefDatabase2, |
134 | path: &Path, | 140 | path: &Path, |
135 | ) -> Option<(TypeNs, Option<usize>)> { | 141 | ) -> Option<(TypeNs, Option<usize>)> { |
136 | if path.is_type_relative() { | 142 | if path.is_type_relative() { |
@@ -164,13 +170,13 @@ impl Resolver { | |||
164 | Scope::ModuleScope(m) => { | 170 | Scope::ModuleScope(m) => { |
165 | let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); | 171 | let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); |
166 | let res = match module_def.take_types()? { | 172 | let res = match module_def.take_types()? { |
167 | ModuleDefId::AdtId(it) => TypeNs::Adt(it.into()), | 173 | ModuleDefId::AdtId(it) => TypeNs::AdtId(it), |
168 | ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariant(it.into()), | 174 | ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it), |
169 | 175 | ||
170 | ModuleDefId::TypeAliasId(it) => TypeNs::TypeAlias(it.into()), | 176 | ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it), |
171 | ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), | 177 | ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), |
172 | 178 | ||
173 | ModuleDefId::TraitId(it) => TypeNs::Trait(it.into()), | 179 | ModuleDefId::TraitId(it) => TypeNs::TraitId(it), |
174 | 180 | ||
175 | ModuleDefId::FunctionId(_) | 181 | ModuleDefId::FunctionId(_) |
176 | | ModuleDefId::ConstId(_) | 182 | | ModuleDefId::ConstId(_) |
@@ -186,7 +192,7 @@ impl Resolver { | |||
186 | 192 | ||
187 | pub(crate) fn resolve_path_in_type_ns_fully( | 193 | pub(crate) fn resolve_path_in_type_ns_fully( |
188 | &self, | 194 | &self, |
189 | db: &impl HirDatabase, | 195 | db: &impl DefDatabase2, |
190 | path: &Path, | 196 | path: &Path, |
191 | ) -> Option<TypeNs> { | 197 | ) -> Option<TypeNs> { |
192 | let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?; | 198 | let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?; |
@@ -198,7 +204,7 @@ impl Resolver { | |||
198 | 204 | ||
199 | pub(crate) fn resolve_path_in_value_ns<'p>( | 205 | pub(crate) fn resolve_path_in_value_ns<'p>( |
200 | &self, | 206 | &self, |
201 | db: &impl HirDatabase, | 207 | db: &impl DefDatabase2, |
202 | path: &'p Path, | 208 | path: &'p Path, |
203 | ) -> Option<ResolveValueResult> { | 209 | ) -> Option<ResolveValueResult> { |
204 | if path.is_type_relative() { | 210 | if path.is_type_relative() { |
@@ -278,9 +284,9 @@ impl Resolver { | |||
278 | } | 284 | } |
279 | Some(idx) => { | 285 | Some(idx) => { |
280 | let ty = match module_def.take_types()? { | 286 | let ty = match module_def.take_types()? { |
281 | ModuleDefId::AdtId(it) => TypeNs::Adt(it.into()), | 287 | ModuleDefId::AdtId(it) => TypeNs::AdtId(it), |
282 | ModuleDefId::TraitId(it) => TypeNs::Trait(it.into()), | 288 | ModuleDefId::TraitId(it) => TypeNs::TraitId(it), |
283 | ModuleDefId::TypeAliasId(it) => TypeNs::TypeAlias(it.into()), | 289 | ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it), |
284 | ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), | 290 | ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), |
285 | 291 | ||
286 | ModuleDefId::ModuleId(_) | 292 | ModuleDefId::ModuleId(_) |
@@ -300,7 +306,7 @@ impl Resolver { | |||
300 | 306 | ||
301 | pub(crate) fn resolve_path_in_value_ns_fully( | 307 | pub(crate) fn resolve_path_in_value_ns_fully( |
302 | &self, | 308 | &self, |
303 | db: &impl HirDatabase, | 309 | db: &impl DefDatabase2, |
304 | path: &Path, | 310 | path: &Path, |
305 | ) -> Option<ValueNs> { | 311 | ) -> Option<ValueNs> { |
306 | match self.resolve_path_in_value_ns(db, path)? { | 312 | match self.resolve_path_in_value_ns(db, path)? { |
@@ -311,7 +317,7 @@ impl Resolver { | |||
311 | 317 | ||
312 | pub(crate) fn resolve_path_as_macro( | 318 | pub(crate) fn resolve_path_as_macro( |
313 | &self, | 319 | &self, |
314 | db: &impl DefDatabase, | 320 | db: &impl DefDatabase2, |
315 | path: &Path, | 321 | path: &Path, |
316 | ) -> Option<MacroDef> { | 322 | ) -> Option<MacroDef> { |
317 | let (item_map, module) = self.module()?; | 323 | let (item_map, module) = self.module()?; |
@@ -320,7 +326,7 @@ impl Resolver { | |||
320 | 326 | ||
321 | pub(crate) fn process_all_names( | 327 | pub(crate) fn process_all_names( |
322 | &self, | 328 | &self, |
323 | db: &impl HirDatabase, | 329 | db: &impl DefDatabase2, |
324 | f: &mut dyn FnMut(Name, ScopeDef), | 330 | f: &mut dyn FnMut(Name, ScopeDef), |
325 | ) { | 331 | ) { |
326 | for scope in self.scopes.iter().rev() { | 332 | for scope in self.scopes.iter().rev() { |
@@ -328,16 +334,15 @@ impl Resolver { | |||
328 | } | 334 | } |
329 | } | 335 | } |
330 | 336 | ||
331 | pub(crate) fn traits_in_scope(&self, db: &impl HirDatabase) -> FxHashSet<Trait> { | 337 | pub(crate) fn traits_in_scope(&self, db: &impl DefDatabase2) -> FxHashSet<TraitId> { |
332 | let mut traits = FxHashSet::default(); | 338 | let mut traits = FxHashSet::default(); |
333 | for scope in &self.scopes { | 339 | for scope in &self.scopes { |
334 | if let Scope::ModuleScope(m) = scope { | 340 | if let Scope::ModuleScope(m) = scope { |
335 | if let Some(prelude) = m.crate_def_map.prelude() { | 341 | if let Some(prelude) = m.crate_def_map.prelude() { |
336 | let prelude_def_map = db.crate_def_map(prelude.krate); | 342 | let prelude_def_map = db.crate_def_map(prelude.krate); |
337 | traits | 343 | traits.extend(prelude_def_map[prelude.module_id].scope.traits()); |
338 | .extend(prelude_def_map[prelude.module_id].scope.traits().map(Trait::from)); | ||
339 | } | 344 | } |
340 | traits.extend(m.crate_def_map[m.module_id].scope.traits().map(Trait::from)); | 345 | traits.extend(m.crate_def_map[m.module_id].scope.traits()); |
341 | } | 346 | } |
342 | } | 347 | } |
343 | traits | 348 | traits |
@@ -367,7 +372,7 @@ impl Resolver { | |||
367 | .flat_map(|params| params.where_predicates.iter()) | 372 | .flat_map(|params| params.where_predicates.iter()) |
368 | } | 373 | } |
369 | 374 | ||
370 | pub(crate) fn generic_def(&self) -> Option<crate::generics::GenericDef> { | 375 | pub(crate) fn generic_def(&self) -> Option<GenericDefId> { |
371 | self.scopes.iter().find_map(|scope| match scope { | 376 | self.scopes.iter().find_map(|scope| match scope { |
372 | Scope::GenericParams { def, .. } => Some(*def), | 377 | Scope::GenericParams { def, .. } => Some(*def), |
373 | _ => None, | 378 | _ => None, |
@@ -383,10 +388,10 @@ impl Resolver { | |||
383 | 388 | ||
384 | pub(crate) fn push_generic_params_scope( | 389 | pub(crate) fn push_generic_params_scope( |
385 | self, | 390 | self, |
386 | db: &impl DefDatabase, | 391 | db: &impl DefDatabase2, |
387 | def: GenericDef, | 392 | def: GenericDefId, |
388 | ) -> Resolver { | 393 | ) -> Resolver { |
389 | let params = def.generic_params(db); | 394 | let params = db.generic_params(def); |
390 | if params.params.is_empty() { | 395 | if params.params.is_empty() { |
391 | self | 396 | self |
392 | } else { | 397 | } else { |
@@ -394,7 +399,7 @@ impl Resolver { | |||
394 | } | 399 | } |
395 | } | 400 | } |
396 | 401 | ||
397 | pub(crate) fn push_impl_block_scope(self, impl_block: ImplBlock) -> Resolver { | 402 | pub(crate) fn push_impl_block_scope(self, impl_block: ImplId) -> Resolver { |
398 | self.push_scope(Scope::ImplBlockScope(impl_block)) | 403 | self.push_scope(Scope::ImplBlockScope(impl_block)) |
399 | } | 404 | } |
400 | 405 | ||
@@ -408,7 +413,7 @@ impl Resolver { | |||
408 | 413 | ||
409 | pub(crate) fn push_expr_scope( | 414 | pub(crate) fn push_expr_scope( |
410 | self, | 415 | self, |
411 | owner: DefWithBody, | 416 | owner: DefWithBodyId, |
412 | expr_scopes: Arc<ExprScopes>, | 417 | expr_scopes: Arc<ExprScopes>, |
413 | scope_id: ScopeId, | 418 | scope_id: ScopeId, |
414 | ) -> Resolver { | 419 | ) -> Resolver { |
@@ -440,7 +445,7 @@ impl From<PerNs> for ScopeDef { | |||
440 | } | 445 | } |
441 | 446 | ||
442 | impl Scope { | 447 | impl Scope { |
443 | fn process_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { | 448 | fn process_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef)) { |
444 | match self { | 449 | match self { |
445 | Scope::ModuleScope(m) => { | 450 | Scope::ModuleScope(m) => { |
446 | // FIXME: should we provide `self` here? | 451 | // FIXME: should we provide `self` here? |
@@ -472,14 +477,14 @@ impl Scope { | |||
472 | } | 477 | } |
473 | } | 478 | } |
474 | Scope::ImplBlockScope(i) => { | 479 | Scope::ImplBlockScope(i) => { |
475 | f(name::SELF_TYPE, ScopeDef::ImplSelfType(*i)); | 480 | f(name::SELF_TYPE, ScopeDef::ImplSelfType((*i).into())); |
476 | } | 481 | } |
477 | Scope::AdtScope(i) => { | 482 | Scope::AdtScope(i) => { |
478 | f(name::SELF_TYPE, ScopeDef::AdtSelfType(*i)); | 483 | f(name::SELF_TYPE, ScopeDef::AdtSelfType((*i).into())); |
479 | } | 484 | } |
480 | Scope::ExprScope(scope) => { | 485 | Scope::ExprScope(scope) => { |
481 | scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| { | 486 | scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| { |
482 | let local = Local { parent: scope.owner, pat_id: e.pat() }; | 487 | let local = Local { parent: scope.owner.into(), pat_id: e.pat() }; |
483 | f(e.name().clone(), ScopeDef::Local(local)); | 488 | f(e.name().clone(), ScopeDef::Local(local)); |
484 | }); | 489 | }); |
485 | } | 490 | } |
@@ -501,7 +506,7 @@ impl HasResolver for Module { | |||
501 | 506 | ||
502 | impl HasResolver for Trait { | 507 | impl HasResolver for Trait { |
503 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | 508 | fn resolver(self, db: &impl DefDatabase) -> Resolver { |
504 | self.module(db).resolver(db).push_generic_params_scope(db, self.into()) | 509 | self.module(db).resolver(db).push_generic_params_scope(db, self.id.into()) |
505 | } | 510 | } |
506 | } | 511 | } |
507 | 512 | ||
@@ -511,7 +516,7 @@ impl<T: Into<Adt>> HasResolver for T { | |||
511 | def.module(db) | 516 | def.module(db) |
512 | .resolver(db) | 517 | .resolver(db) |
513 | .push_generic_params_scope(db, def.into()) | 518 | .push_generic_params_scope(db, def.into()) |
514 | .push_scope(Scope::AdtScope(def)) | 519 | .push_scope(Scope::AdtScope(def.into())) |
515 | } | 520 | } |
516 | } | 521 | } |
517 | 522 | ||
@@ -520,7 +525,7 @@ impl HasResolver for Function { | |||
520 | self.container(db) | 525 | self.container(db) |
521 | .map(|c| c.resolver(db)) | 526 | .map(|c| c.resolver(db)) |
522 | .unwrap_or_else(|| self.module(db).resolver(db)) | 527 | .unwrap_or_else(|| self.module(db).resolver(db)) |
523 | .push_generic_params_scope(db, self.into()) | 528 | .push_generic_params_scope(db, self.id.into()) |
524 | } | 529 | } |
525 | } | 530 | } |
526 | 531 | ||
@@ -551,7 +556,7 @@ impl HasResolver for TypeAlias { | |||
551 | self.container(db) | 556 | self.container(db) |
552 | .map(|ib| ib.resolver(db)) | 557 | .map(|ib| ib.resolver(db)) |
553 | .unwrap_or_else(|| self.module(db).resolver(db)) | 558 | .unwrap_or_else(|| self.module(db).resolver(db)) |
554 | .push_generic_params_scope(db, self.into()) | 559 | .push_generic_params_scope(db, self.id.into()) |
555 | } | 560 | } |
556 | } | 561 | } |
557 | 562 | ||
@@ -582,7 +587,7 @@ impl HasResolver for ImplBlock { | |||
582 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | 587 | fn resolver(self, db: &impl DefDatabase) -> Resolver { |
583 | self.module(db) | 588 | self.module(db) |
584 | .resolver(db) | 589 | .resolver(db) |
585 | .push_generic_params_scope(db, self.into()) | 590 | .push_generic_params_scope(db, self.id.into()) |
586 | .push_impl_block_scope(self) | 591 | .push_impl_block_scope(self.id) |
587 | } | 592 | } |
588 | } | 593 | } |