aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/code_model.rs2
-rw-r--r--crates/ra_hir/src/expr.rs3
-rw-r--r--crates/ra_hir/src/impl_block.rs5
-rw-r--r--crates/ra_hir/src/lib.rs3
-rw-r--r--crates/ra_hir/src/resolve.rs623
-rw-r--r--crates/ra_hir/src/source_binder.rs16
-rw-r--r--crates/ra_hir/src/ty/autoderef.rs3
-rw-r--r--crates/ra_hir/src/ty/infer.rs2
-rw-r--r--crates/ra_hir/src/ty/infer/coerce.rs6
-rw-r--r--crates/ra_hir/src/ty/infer/expr.rs5
-rw-r--r--crates/ra_hir/src/ty/infer/path.rs9
-rw-r--r--crates/ra_hir/src/ty/lower.rs2
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs2
13 files changed, 29 insertions, 652 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 3c891547e..92860fb59 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -11,6 +11,7 @@ use hir_def::{
11 body::scope::ExprScopes, 11 body::scope::ExprScopes,
12 builtin_type::BuiltinType, 12 builtin_type::BuiltinType,
13 nameres::per_ns::PerNs, 13 nameres::per_ns::PerNs,
14 resolver::{HasResolver, TypeNs},
14 traits::TraitData, 15 traits::TraitData,
15 type_ref::{Mutability, TypeRef}, 16 type_ref::{Mutability, TypeRef},
16 ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup, 17 ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup,
@@ -31,7 +32,6 @@ use crate::{
31 AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, 32 AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId,
32 TypeAliasId, 33 TypeAliasId,
33 }, 34 },
34 resolve::{HasResolver, TypeNs},
35 ty::{InferenceResult, Namespace, TraitRef}, 35 ty::{InferenceResult, Namespace, TraitRef},
36 Either, HasSource, ImportId, Name, Source, Ty, 36 Either, HasSource, ImportId, Name, Source, Ty,
37}; 37};
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index 9cdc0c645..6b703d8b4 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -2,7 +2,7 @@
2 2
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_def::path::known; 5use hir_def::{path::known, resolver::HasResolver};
6use hir_expand::diagnostics::DiagnosticSink; 6use hir_expand::diagnostics::DiagnosticSink;
7use ra_syntax::ast; 7use ra_syntax::ast;
8use ra_syntax::AstPtr; 8use ra_syntax::AstPtr;
@@ -11,7 +11,6 @@ use rustc_hash::FxHashSet;
11use crate::{ 11use crate::{
12 db::HirDatabase, 12 db::HirDatabase,
13 diagnostics::{MissingFields, MissingOkInTailExpr}, 13 diagnostics::{MissingFields, MissingOkInTailExpr},
14 resolve::HasResolver,
15 ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, 14 ty::{ApplicationTy, InferenceResult, Ty, TypeCtor},
16 Adt, Function, Name, Path, 15 Adt, Function, Name, Path,
17}; 16};
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index c84ceee62..774fa1d96 100644
--- a/crates/ra_hir/src/impl_block.rs
+++ b/crates/ra_hir/src/impl_block.rs
@@ -1,11 +1,10 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir_def::{type_ref::TypeRef, AstItemDef}; 3use hir_def::{resolver::HasResolver, type_ref::TypeRef, AstItemDef};
4use ra_syntax::ast::{self}; 4use ra_syntax::ast;
5 5
6use crate::{ 6use crate::{
7 db::{AstDatabase, DefDatabase, HirDatabase}, 7 db::{AstDatabase, DefDatabase, HirDatabase},
8 resolve::HasResolver,
9 ty::Ty, 8 ty::Ty,
10 AssocItem, Crate, HasSource, ImplBlock, Module, Source, TraitRef, 9 AssocItem, Crate, HasSource, ImplBlock, Module, Source, TraitRef,
11}; 10};
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 095d4964f..76c96bdcf 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -38,7 +38,6 @@ mod impl_block;
38mod expr; 38mod expr;
39mod lang_item; 39mod lang_item;
40pub mod generics; 40pub mod generics;
41mod resolve;
42pub mod diagnostics; 41pub mod diagnostics;
43mod util; 42mod util;
44 43
@@ -52,8 +51,6 @@ mod test_db;
52#[cfg(test)] 51#[cfg(test)]
53mod marks; 52mod marks;
54 53
55use crate::resolve::Resolver;
56
57pub use crate::{ 54pub use crate::{
58 code_model::{ 55 code_model::{
59 attrs::{AttrDef, Attrs}, 56 attrs::{AttrDef, Attrs},
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
deleted file mode 100644
index a616f0ea5..000000000
--- a/crates/ra_hir/src/resolve.rs
+++ /dev/null
@@ -1,623 +0,0 @@
1//! Name resolution.
2use std::sync::Arc;
3
4use hir_def::{
5 body::scope::{ExprScopes, ScopeId},
6 builtin_type::BuiltinType,
7 db::DefDatabase2,
8 expr::{ExprId, PatId},
9 generics::GenericParams,
10 nameres::{per_ns::PerNs, CrateDefMap},
11 path::{Path, PathKind},
12 AdtId, AstItemDef, ConstId, ContainerId, CrateModuleId, DefWithBodyId, EnumId, EnumVariantId,
13 FunctionId, GenericDefId, ImplId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId,
14 TypeAliasId, UnionId,
15};
16use hir_expand::{
17 name::{self, Name},
18 MacroDefId,
19};
20use ra_db::CrateId;
21use rustc_hash::FxHashSet;
22
23#[derive(Debug, Clone, Default)]
24pub(crate) struct Resolver {
25 scopes: Vec<Scope>,
26}
27
28// FIXME how to store these best
29#[derive(Debug, Clone)]
30pub(crate) struct ModuleItemMap {
31 crate_def_map: Arc<CrateDefMap>,
32 module_id: CrateModuleId,
33}
34
35#[derive(Debug, Clone)]
36pub(crate) struct ExprScope {
37 owner: DefWithBodyId,
38 expr_scopes: Arc<ExprScopes>,
39 scope_id: ScopeId,
40}
41
42#[derive(Debug, Clone)]
43pub(crate) enum Scope {
44 /// All the items and imported names of a module
45 ModuleScope(ModuleItemMap),
46 /// Brings the generic parameters of an item into scope
47 GenericParams { def: GenericDefId, params: Arc<GenericParams> },
48 /// Brings `Self` in `impl` block into scope
49 ImplBlockScope(ImplId),
50 /// Brings `Self` in enum, struct and union definitions into scope
51 AdtScope(AdtId),
52 /// Local bindings
53 ExprScope(ExprScope),
54}
55
56#[derive(Debug, Clone, PartialEq, Eq, Hash)]
57pub(crate) enum TypeNs {
58 SelfType(ImplId),
59 GenericParam(u32),
60 AdtId(AdtId),
61 AdtSelfType(AdtId),
62 EnumVariantId(EnumVariantId),
63 TypeAliasId(TypeAliasId),
64 BuiltinType(BuiltinType),
65 TraitId(TraitId),
66 // Module belong to type ns, but the resolver is used when all module paths
67 // are fully resolved.
68 // ModuleId(ModuleId)
69}
70
71#[derive(Debug, Clone, PartialEq, Eq, Hash)]
72pub(crate) enum ResolveValueResult {
73 ValueNs(ValueNs),
74 Partial(TypeNs, usize),
75}
76
77#[derive(Debug, Clone, PartialEq, Eq, Hash)]
78pub(crate) enum ValueNs {
79 LocalBinding(PatId),
80 FunctionId(FunctionId),
81 ConstId(ConstId),
82 StaticId(StaticId),
83 StructId(StructId),
84 EnumVariantId(EnumVariantId),
85}
86
87impl Resolver {
88 /// Resolve known trait from std, like `std::futures::Future`
89 pub(crate) fn resolve_known_trait(
90 &self,
91 db: &impl DefDatabase2,
92 path: &Path,
93 ) -> Option<TraitId> {
94 let res = self.resolve_module_path(db, path).take_types()?;
95 match res {
96 ModuleDefId::TraitId(it) => Some(it),
97 _ => None,
98 }
99 }
100
101 /// Resolve known struct from std, like `std::boxed::Box`
102 pub(crate) fn resolve_known_struct(
103 &self,
104 db: &impl DefDatabase2,
105 path: &Path,
106 ) -> Option<StructId> {
107 let res = self.resolve_module_path(db, path).take_types()?;
108 match res {
109 ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it),
110 _ => None,
111 }
112 }
113
114 /// Resolve known enum from std, like `std::result::Result`
115 pub(crate) fn resolve_known_enum(&self, db: &impl DefDatabase2, path: &Path) -> Option<EnumId> {
116 let res = self.resolve_module_path(db, path).take_types()?;
117 match res {
118 ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it),
119 _ => None,
120 }
121 }
122
123 /// pub only for source-binder
124 pub(crate) fn resolve_module_path(&self, db: &impl DefDatabase2, path: &Path) -> PerNs {
125 let (item_map, module) = match self.module() {
126 Some(it) => it,
127 None => return PerNs::none(),
128 };
129 let (module_res, segment_index) = item_map.resolve_path(db, module, path);
130 if segment_index.is_some() {
131 return PerNs::none();
132 }
133 module_res
134 }
135
136 pub(crate) fn resolve_path_in_type_ns(
137 &self,
138 db: &impl DefDatabase2,
139 path: &Path,
140 ) -> Option<(TypeNs, Option<usize>)> {
141 if path.is_type_relative() {
142 return None;
143 }
144 let first_name = &path.segments.first()?.name;
145 let skip_to_mod = path.kind != PathKind::Plain;
146 for scope in self.scopes.iter().rev() {
147 match scope {
148 Scope::ExprScope(_) => continue,
149 Scope::GenericParams { .. } | Scope::ImplBlockScope(_) if skip_to_mod => continue,
150
151 Scope::GenericParams { params, .. } => {
152 if let Some(param) = params.find_by_name(first_name) {
153 let idx = if path.segments.len() == 1 { None } else { Some(1) };
154 return Some((TypeNs::GenericParam(param.idx), idx));
155 }
156 }
157 Scope::ImplBlockScope(impl_) => {
158 if first_name == &name::SELF_TYPE {
159 let idx = if path.segments.len() == 1 { None } else { Some(1) };
160 return Some((TypeNs::SelfType(*impl_), idx));
161 }
162 }
163 Scope::AdtScope(adt) => {
164 if first_name == &name::SELF_TYPE {
165 let idx = if path.segments.len() == 1 { None } else { Some(1) };
166 return Some((TypeNs::AdtSelfType(*adt), idx));
167 }
168 }
169 Scope::ModuleScope(m) => {
170 let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path);
171 let res = match module_def.take_types()? {
172 ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
173 ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it),
174
175 ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it),
176 ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it),
177
178 ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
179
180 ModuleDefId::FunctionId(_)
181 | ModuleDefId::ConstId(_)
182 | ModuleDefId::StaticId(_)
183 | ModuleDefId::ModuleId(_) => return None,
184 };
185 return Some((res, idx));
186 }
187 }
188 }
189 None
190 }
191
192 pub(crate) fn resolve_path_in_type_ns_fully(
193 &self,
194 db: &impl DefDatabase2,
195 path: &Path,
196 ) -> Option<TypeNs> {
197 let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?;
198 if unresolved.is_some() {
199 return None;
200 }
201 Some(res)
202 }
203
204 pub(crate) fn resolve_path_in_value_ns<'p>(
205 &self,
206 db: &impl DefDatabase2,
207 path: &'p Path,
208 ) -> Option<ResolveValueResult> {
209 if path.is_type_relative() {
210 return None;
211 }
212 let n_segments = path.segments.len();
213 let tmp = name::SELF_PARAM;
214 let first_name = if path.is_self() { &tmp } else { &path.segments.first()?.name };
215 let skip_to_mod = path.kind != PathKind::Plain && !path.is_self();
216 for scope in self.scopes.iter().rev() {
217 match scope {
218 Scope::AdtScope(_)
219 | Scope::ExprScope(_)
220 | Scope::GenericParams { .. }
221 | Scope::ImplBlockScope(_)
222 if skip_to_mod =>
223 {
224 continue
225 }
226
227 Scope::ExprScope(scope) if n_segments <= 1 => {
228 let entry = scope
229 .expr_scopes
230 .entries(scope.scope_id)
231 .iter()
232 .find(|entry| entry.name() == first_name);
233
234 if let Some(e) = entry {
235 return Some(ResolveValueResult::ValueNs(ValueNs::LocalBinding(e.pat())));
236 }
237 }
238 Scope::ExprScope(_) => continue,
239
240 Scope::GenericParams { params, .. } if n_segments > 1 => {
241 if let Some(param) = params.find_by_name(first_name) {
242 let ty = TypeNs::GenericParam(param.idx);
243 return Some(ResolveValueResult::Partial(ty, 1));
244 }
245 }
246 Scope::GenericParams { .. } => continue,
247
248 Scope::ImplBlockScope(impl_) if n_segments > 1 => {
249 if first_name == &name::SELF_TYPE {
250 let ty = TypeNs::SelfType(*impl_);
251 return Some(ResolveValueResult::Partial(ty, 1));
252 }
253 }
254 Scope::AdtScope(adt) if n_segments > 1 => {
255 if first_name == &name::SELF_TYPE {
256 let ty = TypeNs::AdtSelfType(*adt);
257 return Some(ResolveValueResult::Partial(ty, 1));
258 }
259 }
260 Scope::ImplBlockScope(_) | Scope::AdtScope(_) => continue,
261
262 Scope::ModuleScope(m) => {
263 let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path);
264 return match idx {
265 None => {
266 let value = match module_def.take_values()? {
267 ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it),
268 ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it),
269 ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it),
270 ModuleDefId::ConstId(it) => ValueNs::ConstId(it),
271 ModuleDefId::StaticId(it) => ValueNs::StaticId(it),
272
273 ModuleDefId::AdtId(AdtId::EnumId(_))
274 | ModuleDefId::AdtId(AdtId::UnionId(_))
275 | ModuleDefId::TraitId(_)
276 | ModuleDefId::TypeAliasId(_)
277 | ModuleDefId::BuiltinType(_)
278 | ModuleDefId::ModuleId(_) => return None,
279 };
280 Some(ResolveValueResult::ValueNs(value))
281 }
282 Some(idx) => {
283 let ty = match module_def.take_types()? {
284 ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
285 ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
286 ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it),
287 ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it),
288
289 ModuleDefId::ModuleId(_)
290 | ModuleDefId::FunctionId(_)
291 | ModuleDefId::EnumVariantId(_)
292 | ModuleDefId::ConstId(_)
293 | ModuleDefId::StaticId(_) => return None,
294 };
295 Some(ResolveValueResult::Partial(ty, idx))
296 }
297 };
298 }
299 }
300 }
301 None
302 }
303
304 pub(crate) fn resolve_path_in_value_ns_fully(
305 &self,
306 db: &impl DefDatabase2,
307 path: &Path,
308 ) -> Option<ValueNs> {
309 match self.resolve_path_in_value_ns(db, path)? {
310 ResolveValueResult::ValueNs(it) => Some(it),
311 ResolveValueResult::Partial(..) => None,
312 }
313 }
314
315 pub(crate) fn resolve_path_as_macro(
316 &self,
317 db: &impl DefDatabase2,
318 path: &Path,
319 ) -> Option<MacroDefId> {
320 let (item_map, module) = self.module()?;
321 item_map.resolve_path(db, module, path).0.get_macros()
322 }
323
324 pub(crate) fn process_all_names(
325 &self,
326 db: &impl DefDatabase2,
327 f: &mut dyn FnMut(Name, ScopeDef),
328 ) {
329 for scope in self.scopes.iter().rev() {
330 scope.process_names(db, f);
331 }
332 }
333
334 pub(crate) fn traits_in_scope(&self, db: &impl DefDatabase2) -> FxHashSet<TraitId> {
335 let mut traits = FxHashSet::default();
336 for scope in &self.scopes {
337 if let Scope::ModuleScope(m) = scope {
338 if let Some(prelude) = m.crate_def_map.prelude() {
339 let prelude_def_map = db.crate_def_map(prelude.krate);
340 traits.extend(prelude_def_map[prelude.module_id].scope.traits());
341 }
342 traits.extend(m.crate_def_map[m.module_id].scope.traits());
343 }
344 }
345 traits
346 }
347
348 fn module(&self) -> Option<(&CrateDefMap, CrateModuleId)> {
349 self.scopes.iter().rev().find_map(|scope| match scope {
350 Scope::ModuleScope(m) => Some((&*m.crate_def_map, m.module_id)),
351
352 _ => None,
353 })
354 }
355
356 pub(crate) fn krate(&self) -> Option<CrateId> {
357 self.module().map(|t| t.0.krate())
358 }
359
360 pub(crate) fn where_predicates_in_scope<'a>(
361 &'a self,
362 ) -> impl Iterator<Item = &'a crate::generics::WherePredicate> + 'a {
363 self.scopes
364 .iter()
365 .filter_map(|scope| match scope {
366 Scope::GenericParams { params, .. } => Some(params),
367 _ => None,
368 })
369 .flat_map(|params| params.where_predicates.iter())
370 }
371
372 pub(crate) fn generic_def(&self) -> Option<GenericDefId> {
373 self.scopes.iter().find_map(|scope| match scope {
374 Scope::GenericParams { def, .. } => Some(*def),
375 _ => None,
376 })
377 }
378
379 pub(crate) fn body_owner(&self) -> Option<DefWithBodyId> {
380 self.scopes.iter().find_map(|scope| match scope {
381 Scope::ExprScope(it) => Some(it.owner),
382 _ => None,
383 })
384 }
385}
386
387impl Resolver {
388 pub(crate) fn push_scope(mut self, scope: Scope) -> Resolver {
389 self.scopes.push(scope);
390 self
391 }
392
393 pub(crate) fn push_generic_params_scope(
394 self,
395 db: &impl DefDatabase2,
396 def: GenericDefId,
397 ) -> Resolver {
398 let params = db.generic_params(def);
399 if params.params.is_empty() {
400 self
401 } else {
402 self.push_scope(Scope::GenericParams { def, params })
403 }
404 }
405
406 pub(crate) fn push_impl_block_scope(self, impl_block: ImplId) -> Resolver {
407 self.push_scope(Scope::ImplBlockScope(impl_block))
408 }
409
410 pub(crate) fn push_module_scope(
411 self,
412 crate_def_map: Arc<CrateDefMap>,
413 module_id: CrateModuleId,
414 ) -> Resolver {
415 self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id }))
416 }
417
418 pub(crate) fn push_expr_scope(
419 self,
420 owner: DefWithBodyId,
421 expr_scopes: Arc<ExprScopes>,
422 scope_id: ScopeId,
423 ) -> Resolver {
424 self.push_scope(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id }))
425 }
426}
427
428pub(crate) enum ScopeDef {
429 PerNs(PerNs),
430 ImplSelfType(ImplId),
431 AdtSelfType(AdtId),
432 GenericParam(u32),
433 Local(PatId),
434}
435
436impl Scope {
437 fn process_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef)) {
438 match self {
439 Scope::ModuleScope(m) => {
440 // FIXME: should we provide `self` here?
441 // f(
442 // Name::self_param(),
443 // PerNs::types(Resolution::Def {
444 // def: m.module.into(),
445 // }),
446 // );
447 m.crate_def_map[m.module_id].scope.entries().for_each(|(name, res)| {
448 f(name.clone(), ScopeDef::PerNs(res.def));
449 });
450 m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| {
451 f(name.clone(), ScopeDef::PerNs(PerNs::macros(macro_)));
452 });
453 m.crate_def_map.extern_prelude().iter().for_each(|(name, &def)| {
454 f(name.clone(), ScopeDef::PerNs(PerNs::types(def.into())));
455 });
456 if let Some(prelude) = m.crate_def_map.prelude() {
457 let prelude_def_map = db.crate_def_map(prelude.krate);
458 prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| {
459 f(name.clone(), ScopeDef::PerNs(res.def));
460 });
461 }
462 }
463 Scope::GenericParams { params, .. } => {
464 for param in params.params.iter() {
465 f(param.name.clone(), ScopeDef::GenericParam(param.idx))
466 }
467 }
468 Scope::ImplBlockScope(i) => {
469 f(name::SELF_TYPE, ScopeDef::ImplSelfType((*i).into()));
470 }
471 Scope::AdtScope(i) => {
472 f(name::SELF_TYPE, ScopeDef::AdtSelfType((*i).into()));
473 }
474 Scope::ExprScope(scope) => {
475 scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| {
476 f(e.name().clone(), ScopeDef::Local(e.pat()));
477 });
478 }
479 }
480 }
481}
482
483// needs arbitrary_self_types to be a method... or maybe move to the def?
484pub(crate) fn resolver_for_expr(
485 db: &impl DefDatabase2,
486 owner: DefWithBodyId,
487 expr_id: ExprId,
488) -> Resolver {
489 let scopes = db.expr_scopes(owner);
490 resolver_for_scope(db, owner, scopes.scope_for(expr_id))
491}
492
493pub(crate) fn resolver_for_scope(
494 db: &impl DefDatabase2,
495 owner: DefWithBodyId,
496 scope_id: Option<ScopeId>,
497) -> Resolver {
498 let mut r = owner.resolver(db);
499 let scopes = db.expr_scopes(owner);
500 let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>();
501 for scope in scope_chain.into_iter().rev() {
502 r = r.push_expr_scope(owner, Arc::clone(&scopes), scope);
503 }
504 r
505}
506
507pub(crate) trait HasResolver {
508 /// Builds a resolver for type references inside this def.
509 fn resolver(self, db: &impl DefDatabase2) -> Resolver;
510}
511
512impl HasResolver for ModuleId {
513 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
514 let def_map = db.crate_def_map(self.krate);
515 Resolver::default().push_module_scope(def_map, self.module_id)
516 }
517}
518
519impl HasResolver for TraitId {
520 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
521 self.module(db).resolver(db).push_generic_params_scope(db, self.into())
522 }
523}
524
525impl HasResolver for AdtId {
526 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
527 let module = match self {
528 AdtId::StructId(it) => it.0.module(db),
529 AdtId::UnionId(it) => it.0.module(db),
530 AdtId::EnumId(it) => it.module(db),
531 };
532
533 module
534 .resolver(db)
535 .push_generic_params_scope(db, self.into())
536 .push_scope(Scope::AdtScope(self.into()))
537 }
538}
539
540impl HasResolver for StructId {
541 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
542 AdtId::from(self).resolver(db)
543 }
544}
545
546impl HasResolver for UnionId {
547 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
548 AdtId::from(self).resolver(db)
549 }
550}
551
552impl HasResolver for EnumId {
553 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
554 AdtId::from(self).resolver(db)
555 }
556}
557
558impl HasResolver for FunctionId {
559 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
560 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
561 }
562}
563
564impl HasResolver for DefWithBodyId {
565 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
566 match self {
567 DefWithBodyId::ConstId(c) => c.resolver(db),
568 DefWithBodyId::FunctionId(f) => f.resolver(db),
569 DefWithBodyId::StaticId(s) => s.resolver(db),
570 }
571 }
572}
573
574impl HasResolver for ConstId {
575 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
576 self.lookup(db).container.resolver(db)
577 }
578}
579
580impl HasResolver for StaticId {
581 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
582 self.module(db).resolver(db)
583 }
584}
585
586impl HasResolver for TypeAliasId {
587 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
588 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
589 }
590}
591
592impl HasResolver for ContainerId {
593 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
594 match self {
595 ContainerId::TraitId(it) => it.resolver(db),
596 ContainerId::ImplId(it) => it.resolver(db),
597 ContainerId::ModuleId(it) => it.resolver(db),
598 }
599 }
600}
601
602impl HasResolver for GenericDefId {
603 fn resolver(self, db: &impl DefDatabase2) -> crate::Resolver {
604 match self {
605 GenericDefId::FunctionId(inner) => inner.resolver(db),
606 GenericDefId::AdtId(adt) => adt.resolver(db),
607 GenericDefId::TraitId(inner) => inner.resolver(db),
608 GenericDefId::TypeAliasId(inner) => inner.resolver(db),
609 GenericDefId::ImplId(inner) => inner.resolver(db),
610 GenericDefId::EnumVariantId(inner) => inner.parent.resolver(db),
611 GenericDefId::ConstId(inner) => inner.resolver(db),
612 }
613 }
614}
615
616impl HasResolver for ImplId {
617 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
618 self.module(db)
619 .resolver(db)
620 .push_generic_params_scope(db, self.into())
621 .push_impl_block_scope(self)
622 }
623}
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 898b823c0..c42ceabdf 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -10,6 +10,7 @@ use std::sync::Arc;
10use hir_def::{ 10use hir_def::{
11 expr::{ExprId, PatId}, 11 expr::{ExprId, PatId},
12 path::known, 12 path::known,
13 resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs},
13 DefWithBodyId, 14 DefWithBodyId,
14}; 15};
15use hir_expand::{name::AsName, AstId, MacroCallId, MacroCallLoc, MacroFileKind, Source}; 16use hir_expand::{name::AsName, AstId, MacroCallId, MacroCallLoc, MacroFileKind, Source};
@@ -24,11 +25,10 @@ use crate::{
24 db::HirDatabase, 25 db::HirDatabase,
25 expr::{BodySourceMap, ExprScopes, ScopeId}, 26 expr::{BodySourceMap, ExprScopes, ScopeId},
26 ids::LocationCtx, 27 ids::LocationCtx,
27 resolve::{self, resolver_for_scope, HasResolver, TypeNs, ValueNs},
28 ty::method_resolution::{self, implements_trait}, 28 ty::method_resolution::{self, implements_trait},
29 Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, 29 Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function,
30 GenericParam, HasBody, HirFileId, Local, MacroDef, Module, Name, Path, Resolver, ScopeDef, 30 GenericParam, HasBody, HirFileId, Local, MacroDef, Module, Name, Path, ScopeDef, Static,
31 Static, Struct, Trait, Ty, TypeAlias, 31 Struct, Trait, Ty, TypeAlias,
32}; 32};
33 33
34fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { 34fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> {
@@ -317,14 +317,14 @@ impl SourceAnalyzer {
317 pub fn process_all_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { 317 pub fn process_all_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef)) {
318 self.resolver.process_all_names(db, &mut |name, def| { 318 self.resolver.process_all_names(db, &mut |name, def| {
319 let def = match def { 319 let def = match def {
320 resolve::ScopeDef::PerNs(it) => it.into(), 320 resolver::ScopeDef::PerNs(it) => it.into(),
321 resolve::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), 321 resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()),
322 resolve::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), 322 resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()),
323 resolve::ScopeDef::GenericParam(idx) => { 323 resolver::ScopeDef::GenericParam(idx) => {
324 let parent = self.resolver.generic_def().unwrap().into(); 324 let parent = self.resolver.generic_def().unwrap().into();
325 ScopeDef::GenericParam(GenericParam { parent, idx }) 325 ScopeDef::GenericParam(GenericParam { parent, idx })
326 } 326 }
327 resolve::ScopeDef::Local(pat_id) => { 327 resolver::ScopeDef::Local(pat_id) => {
328 let parent = self.resolver.body_owner().unwrap().into(); 328 let parent = self.resolver.body_owner().unwrap().into();
329 ScopeDef::Local(Local { parent, pat_id }) 329 ScopeDef::Local(Local { parent, pat_id })
330 } 330 }
diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs
index f77492170..5d8518041 100644
--- a/crates/ra_hir/src/ty/autoderef.rs
+++ b/crates/ra_hir/src/ty/autoderef.rs
@@ -5,11 +5,12 @@
5 5
6use std::iter::successors; 6use std::iter::successors;
7 7
8use hir_def::resolver::Resolver;
8use hir_expand::name; 9use hir_expand::name;
9use log::{info, warn}; 10use log::{info, warn};
10 11
11use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; 12use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk};
12use crate::{db::HirDatabase, generics::HasGenericParams, Resolver}; 13use crate::{db::HirDatabase, generics::HasGenericParams};
13 14
14const AUTODEREF_RECURSION_LIMIT: usize = 10; 15const AUTODEREF_RECURSION_LIMIT: usize = 10;
15 16
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index c3d65afa6..69b13baef 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -23,6 +23,7 @@ use rustc_hash::FxHashMap;
23 23
24use hir_def::{ 24use hir_def::{
25 path::known, 25 path::known,
26 resolver::{HasResolver, Resolver, TypeNs},
26 type_ref::{Mutability, TypeRef}, 27 type_ref::{Mutability, TypeRef},
27 AdtId, DefWithBodyId, 28 AdtId, DefWithBodyId,
28}; 29};
@@ -41,7 +42,6 @@ use crate::{
41 code_model::TypeAlias, 42 code_model::TypeAlias,
42 db::HirDatabase, 43 db::HirDatabase,
43 expr::{BindingAnnotation, Body, ExprId, PatId}, 44 expr::{BindingAnnotation, Body, ExprId, PatId},
44 resolve::{HasResolver, Resolver, TypeNs},
45 ty::infer::diagnostics::InferenceDiagnostic, 45 ty::infer::diagnostics::InferenceDiagnostic,
46 Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, 46 Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path,
47 StructField, Trait, VariantDef, 47 StructField, Trait, VariantDef,
diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs
index 6d297c268..0772b9df5 100644
--- a/crates/ra_hir/src/ty/infer/coerce.rs
+++ b/crates/ra_hir/src/ty/infer/coerce.rs
@@ -4,19 +4,19 @@
4//! 4//!
5//! See: https://doc.rust-lang.org/nomicon/coercions.html 5//! See: https://doc.rust-lang.org/nomicon/coercions.html
6 6
7use hir_def::resolver::Resolver;
7use rustc_hash::FxHashMap; 8use rustc_hash::FxHashMap;
8
9use test_utils::tested_by; 9use test_utils::tested_by;
10 10
11use super::{InferTy, InferenceContext, TypeVarValue};
12use crate::{ 11use crate::{
13 db::HirDatabase, 12 db::HirDatabase,
14 lang_item::LangItemTarget, 13 lang_item::LangItemTarget,
15 resolve::Resolver,
16 ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk}, 14 ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk},
17 Adt, Mutability, 15 Adt, Mutability,
18}; 16};
19 17
18use super::{InferTy, InferenceContext, TypeVarValue};
19
20impl<'a, D: HirDatabase> InferenceContext<'a, D> { 20impl<'a, D: HirDatabase> InferenceContext<'a, D> {
21 /// Unify two types, but may coerce the first one to the second one 21 /// Unify two types, but may coerce the first one to the second one
22 /// using "implicit coercion rules" if needed. 22 /// using "implicit coercion rules" if needed.
diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs
index 1ac2709f5..ac570075f 100644
--- a/crates/ra_hir/src/ty/infer/expr.rs
+++ b/crates/ra_hir/src/ty/infer/expr.rs
@@ -6,15 +6,14 @@ use std::sync::Arc;
6use hir_def::{ 6use hir_def::{
7 builtin_type::Signedness, 7 builtin_type::Signedness,
8 path::{GenericArg, GenericArgs}, 8 path::{GenericArg, GenericArgs},
9 resolver::resolver_for_expr,
9}; 10};
10use hir_expand::name; 11use hir_expand::name;
11 12
12use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch};
13use crate::{ 13use crate::{
14 db::HirDatabase, 14 db::HirDatabase,
15 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 15 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
16 generics::{GenericParams, HasGenericParams}, 16 generics::{GenericParams, HasGenericParams},
17 resolve::resolver_for_expr,
18 ty::{ 17 ty::{
19 autoderef, method_resolution, op, CallableDef, InferTy, IntTy, Mutability, Namespace, 18 autoderef, method_resolution, op, CallableDef, InferTy, IntTy, Mutability, Namespace,
20 Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, 19 Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk,
@@ -23,6 +22,8 @@ use crate::{
23 Adt, Name, 22 Adt, Name,
24}; 23};
25 24
25use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch};
26
26impl<'a, D: HirDatabase> InferenceContext<'a, D> { 27impl<'a, D: HirDatabase> InferenceContext<'a, D> {
27 pub(super) fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { 28 pub(super) fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
28 let ty = self.infer_expr_inner(tgt_expr, expected); 29 let ty = self.infer_expr_inner(tgt_expr, expected);
diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs
index 55a5dbec7..70136e514 100644
--- a/crates/ra_hir/src/ty/infer/path.rs
+++ b/crates/ra_hir/src/ty/infer/path.rs
@@ -1,16 +1,19 @@
1//! Path expression resolution. 1//! Path expression resolution.
2 2
3use hir_def::path::PathSegment; 3use hir_def::{
4 path::PathSegment,
5 resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs},
6};
4 7
5use super::{ExprOrPatId, InferenceContext, TraitRef};
6use crate::{ 8use crate::{
7 db::HirDatabase, 9 db::HirDatabase,
8 generics::HasGenericParams, 10 generics::HasGenericParams,
9 resolve::{ResolveValueResult, Resolver, TypeNs, ValueNs},
10 ty::{method_resolution, Namespace, Substs, Ty, TypableDef, TypeWalk}, 11 ty::{method_resolution, Namespace, Substs, Ty, TypableDef, TypeWalk},
11 AssocItem, Container, Function, Name, Path, 12 AssocItem, Container, Function, Name, Path,
12}; 13};
13 14
15use super::{ExprOrPatId, InferenceContext, TraitRef};
16
14impl<'a, D: HirDatabase> InferenceContext<'a, D> { 17impl<'a, D: HirDatabase> InferenceContext<'a, D> {
15 pub(super) fn infer_path( 18 pub(super) fn infer_path(
16 &mut self, 19 &mut self,
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index e477b2439..c6ad0811b 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -11,6 +11,7 @@ use std::sync::Arc;
11use hir_def::{ 11use hir_def::{
12 builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType}, 12 builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType},
13 path::{GenericArg, PathSegment}, 13 path::{GenericArg, PathSegment},
14 resolver::{HasResolver, Resolver, TypeNs},
14 type_ref::{TypeBound, TypeRef}, 15 type_ref::{TypeBound, TypeRef},
15 GenericDefId, 16 GenericDefId,
16}; 17};
@@ -23,7 +24,6 @@ use crate::{
23 db::HirDatabase, 24 db::HirDatabase,
24 generics::HasGenericParams, 25 generics::HasGenericParams,
25 generics::{GenericDef, WherePredicate}, 26 generics::{GenericDef, WherePredicate},
26 resolve::{HasResolver, Resolver, TypeNs},
27 ty::{ 27 ty::{
28 primitive::{FloatTy, IntTy, Uncertain}, 28 primitive::{FloatTy, IntTy, Uncertain},
29 Adt, 29 Adt,
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index 5ad72ef9f..64adb814d 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -5,11 +5,11 @@
5use std::sync::Arc; 5use std::sync::Arc;
6 6
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use hir_def::resolver::Resolver;
8use rustc_hash::FxHashMap; 9use rustc_hash::FxHashMap;
9 10
10use crate::{ 11use crate::{
11 db::HirDatabase, 12 db::HirDatabase,
12 resolve::Resolver,
13 ty::primitive::{FloatBitness, Uncertain}, 13 ty::primitive::{FloatBitness, Uncertain},
14 ty::{Ty, TypeCtor}, 14 ty::{Ty, TypeCtor},
15 AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait, 15 AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait,