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.rs48
-rw-r--r--crates/ra_hir/src/expr.rs33
-rw-r--r--crates/ra_hir/src/from_id.rs88
-rw-r--r--crates/ra_hir/src/impl_block.rs9
-rw-r--r--crates/ra_hir/src/lib.rs8
-rw-r--r--crates/ra_hir/src/resolve.rs588
-rw-r--r--crates/ra_hir/src/source_binder.rs75
-rw-r--r--crates/ra_hir/src/ty/autoderef.rs7
-rw-r--r--crates/ra_hir/src/ty/infer.rs32
-rw-r--r--crates/ra_hir/src/ty/infer/coerce.rs10
-rw-r--r--crates/ra_hir/src/ty/infer/expr.rs8
-rw-r--r--crates/ra_hir/src/ty/infer/path.rs36
-rw-r--r--crates/ra_hir/src/ty/lower.rs56
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs21
14 files changed, 275 insertions, 744 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index a132d128b..92860fb59 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -10,10 +10,12 @@ 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 nameres::per_ns::PerNs,
14 resolver::{HasResolver, TypeNs},
13 traits::TraitData, 15 traits::TraitData,
14 type_ref::{Mutability, TypeRef}, 16 type_ref::{Mutability, TypeRef},
15 AssocItemId, ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, 17 ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup,
16 LocalStructFieldId, Lookup, ModuleId, UnionId, 18 ModuleId, UnionId,
17}; 19};
18use hir_expand::{ 20use hir_expand::{
19 diagnostics::DiagnosticSink, 21 diagnostics::DiagnosticSink,
@@ -30,9 +32,8 @@ use crate::{
30 AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, 32 AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId,
31 TypeAliasId, 33 TypeAliasId,
32 }, 34 },
33 resolve::{HasResolver, TypeNs},
34 ty::{InferenceResult, Namespace, TraitRef}, 35 ty::{InferenceResult, Namespace, TraitRef},
35 Either, HasSource, ImportId, Name, ScopeDef, Source, Ty, 36 Either, HasSource, ImportId, Name, Source, Ty,
36}; 37};
37 38
38/// hir::Crate describes a single crate. It's the main interface with which 39/// hir::Crate describes a single crate. It's the main interface with which
@@ -829,7 +830,7 @@ impl Trait {
829 } 830 }
830 831
831 fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { 832 fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> {
832 let resolver = self.resolver(db); 833 let resolver = self.id.resolver(db);
833 // returning the iterator directly doesn't easily work because of 834 // returning the iterator directly doesn't easily work because of
834 // lifetime problems, but since there usually shouldn't be more than a 835 // lifetime problems, but since there usually shouldn't be more than a
835 // few direct traits this should be fine (we could even use some kind of 836 // few direct traits this should be fine (we could even use some kind of
@@ -842,9 +843,10 @@ impl Trait {
842 _ => None, 843 _ => None,
843 }) 844 })
844 .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) { 845 .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) {
845 Some(TypeNs::Trait(t)) => Some(t), 846 Some(TypeNs::TraitId(t)) => Some(t),
846 _ => None, 847 _ => None,
847 }) 848 })
849 .map(Trait::from)
848 .collect() 850 .collect()
849 } 851 }
850 852
@@ -871,14 +873,9 @@ impl Trait {
871 873
872 pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { 874 pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> {
873 let trait_data = self.trait_data(db); 875 let trait_data = self.trait_data(db);
874 trait_data 876 let res =
875 .items 877 trait_data.associated_types().map(TypeAlias::from).find(|t| &t.name(db) == name)?;
876 .iter() 878 Some(res)
877 .filter_map(|item| match item {
878 AssocItemId::TypeAliasId(t) => Some(TypeAlias::from(*t)),
879 _ => None,
880 })
881 .find(|t| &t.name(db) == name)
882 } 879 }
883 880
884 pub fn associated_type_by_name_including_super_traits( 881 pub fn associated_type_by_name_including_super_traits(
@@ -1068,3 +1065,26 @@ pub struct GenericParam {
1068pub struct ImplBlock { 1065pub struct ImplBlock {
1069 pub(crate) id: ImplId, 1066 pub(crate) id: ImplId,
1070} 1067}
1068
1069/// For IDE only
1070pub enum ScopeDef {
1071 ModuleDef(ModuleDef),
1072 MacroDef(MacroDef),
1073 GenericParam(GenericParam),
1074 ImplSelfType(ImplBlock),
1075 AdtSelfType(Adt),
1076 Local(Local),
1077 Unknown,
1078}
1079
1080impl From<PerNs> for ScopeDef {
1081 fn from(def: PerNs) -> Self {
1082 def.take_types()
1083 .or_else(|| def.take_values())
1084 .map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into()))
1085 .or_else(|| {
1086 def.get_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into()))
1087 })
1088 .unwrap_or(ScopeDef::Unknown)
1089 }
1090}
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index 869879bdf..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,9 +11,8 @@ 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, DefWithBody, Function, HasBody, Name, Path, Resolver, 15 Adt, Function, Name, Path,
17}; 16};
18 17
19pub use hir_def::{ 18pub use hir_def::{
@@ -27,30 +26,6 @@ pub use hir_def::{
27 }, 26 },
28}; 27};
29 28
30// needs arbitrary_self_types to be a method... or maybe move to the def?
31pub(crate) fn resolver_for_expr(
32 db: &impl HirDatabase,
33 owner: DefWithBody,
34 expr_id: ExprId,
35) -> Resolver {
36 let scopes = owner.expr_scopes(db);
37 resolver_for_scope(db, owner, scopes.scope_for(expr_id))
38}
39
40pub(crate) fn resolver_for_scope(
41 db: &impl HirDatabase,
42 owner: DefWithBody,
43 scope_id: Option<ScopeId>,
44) -> Resolver {
45 let mut r = owner.resolver(db);
46 let scopes = owner.expr_scopes(db);
47 let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>();
48 for scope in scope_chain.into_iter().rev() {
49 r = r.push_expr_scope(owner, Arc::clone(&scopes), scope);
50 }
51 r
52}
53
54pub(crate) struct ExprValidator<'a, 'b: 'a> { 29pub(crate) struct ExprValidator<'a, 'b: 'a> {
55 func: Function, 30 func: Function,
56 infer: Arc<InferenceResult>, 31 infer: Arc<InferenceResult>,
@@ -146,13 +121,13 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
146 121
147 let std_result_path = known::std_result_result(); 122 let std_result_path = known::std_result_result();
148 123
149 let resolver = self.func.resolver(db); 124 let resolver = self.func.id.resolver(db);
150 let std_result_enum = match resolver.resolve_known_enum(db, &std_result_path) { 125 let std_result_enum = match resolver.resolve_known_enum(db, &std_result_path) {
151 Some(it) => it, 126 Some(it) => it,
152 _ => return, 127 _ => return,
153 }; 128 };
154 129
155 let std_result_ctor = TypeCtor::Adt(Adt::Enum(std_result_enum)); 130 let std_result_ctor = TypeCtor::Adt(Adt::Enum(std_result_enum.into()));
156 let params = match &mismatch.expected { 131 let params = match &mismatch.expected {
157 Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters, 132 Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters,
158 _ => return, 133 _ => return,
diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs
index b7692d407..a3e9d8525 100644
--- a/crates/ra_hir/src/from_id.rs
+++ b/crates/ra_hir/src/from_id.rs
@@ -3,9 +3,21 @@
3//! It's unclear if we need this long-term, but it's definitelly useful while we 3//! It's unclear if we need this long-term, but it's definitelly useful while we
4//! are splitting the hir. 4//! are splitting the hir.
5 5
6use hir_def::{AdtId, AssocItemId, DefWithBodyId, EnumVariantId, GenericDefId, ModuleDefId}; 6use hir_def::{
7 AdtId, AssocItemId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId,
8 ModuleDefId, StaticId, StructId, TypeAliasId, UnionId,
9};
7 10
8use crate::{Adt, AssocItem, DefWithBody, EnumVariant, GenericDef, ModuleDef}; 11use crate::{
12 ty::TypableDef, Adt, AssocItem, Const, Crate, DefWithBody, EnumVariant, Function, GenericDef,
13 ModuleDef, Static, TypeAlias,
14};
15
16impl From<ra_db::CrateId> for Crate {
17 fn from(crate_id: ra_db::CrateId) -> Self {
18 Crate { crate_id }
19 }
20}
9 21
10macro_rules! from_id { 22macro_rules! from_id {
11 ($(($id:path, $ty:path)),*) => {$( 23 ($(($id:path, $ty:path)),*) => {$(
@@ -83,6 +95,16 @@ impl From<DefWithBody> for DefWithBodyId {
83 } 95 }
84} 96}
85 97
98impl From<DefWithBodyId> for DefWithBody {
99 fn from(def: DefWithBodyId) -> Self {
100 match def {
101 DefWithBodyId::FunctionId(it) => DefWithBody::Function(it.into()),
102 DefWithBodyId::StaticId(it) => DefWithBody::Static(it.into()),
103 DefWithBodyId::ConstId(it) => DefWithBody::Const(it.into()),
104 }
105 }
106}
107
86impl From<AssocItemId> for AssocItem { 108impl From<AssocItemId> for AssocItem {
87 fn from(def: AssocItemId) -> Self { 109 fn from(def: AssocItemId) -> Self {
88 match def { 110 match def {
@@ -122,3 +144,65 @@ impl From<GenericDefId> for GenericDef {
122 } 144 }
123 } 145 }
124} 146}
147
148impl From<AdtId> for TypableDef {
149 fn from(id: AdtId) -> Self {
150 Adt::from(id).into()
151 }
152}
153
154impl From<StructId> for TypableDef {
155 fn from(id: StructId) -> Self {
156 AdtId::StructId(id).into()
157 }
158}
159
160impl From<UnionId> for TypableDef {
161 fn from(id: UnionId) -> Self {
162 AdtId::UnionId(id).into()
163 }
164}
165
166impl From<EnumId> for TypableDef {
167 fn from(id: EnumId) -> Self {
168 AdtId::EnumId(id).into()
169 }
170}
171
172impl From<EnumVariantId> for TypableDef {
173 fn from(id: EnumVariantId) -> Self {
174 EnumVariant::from(id).into()
175 }
176}
177
178impl From<TypeAliasId> for TypableDef {
179 fn from(id: TypeAliasId) -> Self {
180 TypeAlias::from(id).into()
181 }
182}
183
184impl From<FunctionId> for TypableDef {
185 fn from(id: FunctionId) -> Self {
186 Function::from(id).into()
187 }
188}
189impl From<ConstId> for TypableDef {
190 fn from(id: ConstId) -> Self {
191 Const::from(id).into()
192 }
193}
194impl From<StaticId> for TypableDef {
195 fn from(id: StaticId) -> Self {
196 Static::from(id).into()
197 }
198}
199
200impl From<Adt> for GenericDefId {
201 fn from(id: Adt) -> Self {
202 match id {
203 Adt::Struct(it) => it.id.into(),
204 Adt::Union(it) => it.id.into(),
205 Adt::Enum(it) => it.id.into(),
206 }
207 }
208}
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index 964a3da8c..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};
@@ -27,12 +26,12 @@ impl ImplBlock {
27 } 26 }
28 27
29 pub fn target_ty(&self, db: &impl HirDatabase) -> Ty { 28 pub fn target_ty(&self, db: &impl HirDatabase) -> Ty {
30 Ty::from_hir(db, &self.resolver(db), &self.target_type(db)) 29 Ty::from_hir(db, &self.id.resolver(db), &self.target_type(db))
31 } 30 }
32 31
33 pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> { 32 pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> {
34 let target_ty = self.target_ty(db); 33 let target_ty = self.target_ty(db);
35 TraitRef::from_hir(db, &self.resolver(db), &self.target_trait(db)?, Some(target_ty)) 34 TraitRef::from_hir(db, &self.id.resolver(db), &self.target_trait(db)?, Some(target_ty))
36 } 35 }
37 36
38 pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { 37 pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> {
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 31da74d2f..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},
@@ -61,14 +58,13 @@ pub use crate::{
61 src::{HasBodySource, HasSource}, 58 src::{HasBodySource, HasSource},
62 Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, 59 Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum,
63 EnumVariant, FieldSource, FnData, Function, GenericParam, HasBody, ImplBlock, Local, 60 EnumVariant, FieldSource, FnData, Function, GenericParam, HasBody, ImplBlock, Local,
64 MacroDef, Module, ModuleDef, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, 61 MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField, Trait,
65 Union, VariantDef, 62 TypeAlias, Union, VariantDef,
66 }, 63 },
67 expr::ExprScopes, 64 expr::ExprScopes,
68 from_source::FromSource, 65 from_source::FromSource,
69 generics::GenericDef, 66 generics::GenericDef,
70 ids::{HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile}, 67 ids::{HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile},
71 resolve::ScopeDef,
72 source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, 68 source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer},
73 ty::{ 69 ty::{
74 display::HirDisplay, 70 display::HirDisplay,
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
deleted file mode 100644
index eca8e0596..000000000
--- a/crates/ra_hir/src/resolve.rs
+++ /dev/null
@@ -1,588 +0,0 @@
1//! Name resolution.
2use std::sync::Arc;
3
4use hir_def::{
5 builtin_type::BuiltinType,
6 nameres::CrateDefMap,
7 path::{Path, PathKind},
8 AdtId, CrateModuleId, ModuleDefId,
9};
10use hir_expand::name::{self, Name};
11use rustc_hash::FxHashSet;
12
13use crate::{
14 code_model::Crate,
15 db::{DefDatabase, HirDatabase},
16 expr::{ExprScopes, PatId, ScopeId},
17 generics::{GenericParams, HasGenericParams},
18 Adt, Const, Container, DefWithBody, Enum, EnumVariant, Function, GenericDef, ImplBlock, Local,
19 MacroDef, Module, ModuleDef, PerNs, Static, Struct, Trait, TypeAlias,
20};
21
22#[derive(Debug, Clone, Default)]
23pub(crate) struct Resolver {
24 scopes: Vec<Scope>,
25}
26
27// FIXME how to store these best
28#[derive(Debug, Clone)]
29pub(crate) struct ModuleItemMap {
30 crate_def_map: Arc<CrateDefMap>,
31 module_id: CrateModuleId,
32}
33
34#[derive(Debug, Clone)]
35pub(crate) struct ExprScope {
36 owner: DefWithBody,
37 expr_scopes: Arc<ExprScopes>,
38 scope_id: ScopeId,
39}
40
41#[derive(Debug, Clone)]
42pub(crate) enum Scope {
43 /// All the items and imported names of a module
44 ModuleScope(ModuleItemMap),
45 /// Brings the generic parameters of an item into scope
46 GenericParams { def: GenericDef, params: Arc<GenericParams> },
47 /// Brings `Self` in `impl` block into scope
48 ImplBlockScope(ImplBlock),
49 /// Brings `Self` in enum, struct and union definitions into scope
50 AdtScope(Adt),
51 /// Local bindings
52 ExprScope(ExprScope),
53}
54
55#[derive(Debug, Clone, PartialEq, Eq, Hash)]
56pub(crate) enum TypeNs {
57 SelfType(ImplBlock),
58 GenericParam(u32),
59 Adt(Adt),
60 AdtSelfType(Adt),
61 EnumVariant(EnumVariant),
62 TypeAlias(TypeAlias),
63 BuiltinType(BuiltinType),
64 Trait(Trait),
65 // Module belong to type ns, but the resolver is used when all module paths
66 // are fully resolved.
67 // Module(Module)
68}
69
70#[derive(Debug, Clone, PartialEq, Eq, Hash)]
71pub(crate) enum ResolveValueResult {
72 ValueNs(ValueNs),
73 Partial(TypeNs, usize),
74}
75
76#[derive(Debug, Clone, PartialEq, Eq, Hash)]
77pub(crate) enum ValueNs {
78 LocalBinding(PatId),
79 Function(Function),
80 Const(Const),
81 Static(Static),
82 Struct(Struct),
83 EnumVariant(EnumVariant),
84}
85
86impl Resolver {
87 /// Resolve known trait from std, like `std::futures::Future`
88 pub(crate) fn resolve_known_trait(&self, db: &impl HirDatabase, path: &Path) -> Option<Trait> {
89 let res = self.resolve_module_path(db, path).take_types()?;
90 match res {
91 ModuleDefId::TraitId(it) => Some(it.into()),
92 _ => None,
93 }
94 }
95
96 /// Resolve known struct from std, like `std::boxed::Box`
97 pub(crate) fn resolve_known_struct(
98 &self,
99 db: &impl HirDatabase,
100 path: &Path,
101 ) -> Option<Struct> {
102 let res = self.resolve_module_path(db, path).take_types()?;
103 match res {
104 ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it.into()),
105 _ => None,
106 }
107 }
108
109 /// Resolve known enum from std, like `std::result::Result`
110 pub(crate) fn resolve_known_enum(&self, db: &impl HirDatabase, path: &Path) -> Option<Enum> {
111 let res = self.resolve_module_path(db, path).take_types()?;
112 match res {
113 ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it.into()),
114 _ => None,
115 }
116 }
117
118 /// pub only for source-binder
119 pub(crate) fn resolve_module_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs {
120 let (item_map, module) = match self.module() {
121 Some(it) => it,
122 None => return PerNs::none(),
123 };
124 let (module_res, segment_index) = item_map.resolve_path(db, module, path);
125 if segment_index.is_some() {
126 return PerNs::none();
127 }
128 module_res
129 }
130
131 pub(crate) fn resolve_path_in_type_ns(
132 &self,
133 db: &impl HirDatabase,
134 path: &Path,
135 ) -> Option<(TypeNs, Option<usize>)> {
136 if path.is_type_relative() {
137 return None;
138 }
139 let first_name = &path.segments.first()?.name;
140 let skip_to_mod = path.kind != PathKind::Plain;
141 for scope in self.scopes.iter().rev() {
142 match scope {
143 Scope::ExprScope(_) => continue,
144 Scope::GenericParams { .. } | Scope::ImplBlockScope(_) if skip_to_mod => continue,
145
146 Scope::GenericParams { params, .. } => {
147 if let Some(param) = params.find_by_name(first_name) {
148 let idx = if path.segments.len() == 1 { None } else { Some(1) };
149 return Some((TypeNs::GenericParam(param.idx), idx));
150 }
151 }
152 Scope::ImplBlockScope(impl_) => {
153 if first_name == &name::SELF_TYPE {
154 let idx = if path.segments.len() == 1 { None } else { Some(1) };
155 return Some((TypeNs::SelfType(*impl_), idx));
156 }
157 }
158 Scope::AdtScope(adt) => {
159 if first_name == &name::SELF_TYPE {
160 let idx = if path.segments.len() == 1 { None } else { Some(1) };
161 return Some((TypeNs::AdtSelfType(*adt), idx));
162 }
163 }
164 Scope::ModuleScope(m) => {
165 let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path);
166 let res = match module_def.take_types()? {
167 ModuleDefId::AdtId(it) => TypeNs::Adt(it.into()),
168 ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariant(it.into()),
169
170 ModuleDefId::TypeAliasId(it) => TypeNs::TypeAlias(it.into()),
171 ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it),
172
173 ModuleDefId::TraitId(it) => TypeNs::Trait(it.into()),
174
175 ModuleDefId::FunctionId(_)
176 | ModuleDefId::ConstId(_)
177 | ModuleDefId::StaticId(_)
178 | ModuleDefId::ModuleId(_) => return None,
179 };
180 return Some((res, idx));
181 }
182 }
183 }
184 None
185 }
186
187 pub(crate) fn resolve_path_in_type_ns_fully(
188 &self,
189 db: &impl HirDatabase,
190 path: &Path,
191 ) -> Option<TypeNs> {
192 let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?;
193 if unresolved.is_some() {
194 return None;
195 }
196 Some(res)
197 }
198
199 pub(crate) fn resolve_path_in_value_ns<'p>(
200 &self,
201 db: &impl HirDatabase,
202 path: &'p Path,
203 ) -> Option<ResolveValueResult> {
204 if path.is_type_relative() {
205 return None;
206 }
207 let n_segments = path.segments.len();
208 let tmp = name::SELF_PARAM;
209 let first_name = if path.is_self() { &tmp } else { &path.segments.first()?.name };
210 let skip_to_mod = path.kind != PathKind::Plain && !path.is_self();
211 for scope in self.scopes.iter().rev() {
212 match scope {
213 Scope::AdtScope(_)
214 | Scope::ExprScope(_)
215 | Scope::GenericParams { .. }
216 | Scope::ImplBlockScope(_)
217 if skip_to_mod =>
218 {
219 continue
220 }
221
222 Scope::ExprScope(scope) if n_segments <= 1 => {
223 let entry = scope
224 .expr_scopes
225 .entries(scope.scope_id)
226 .iter()
227 .find(|entry| entry.name() == first_name);
228
229 if let Some(e) = entry {
230 return Some(ResolveValueResult::ValueNs(ValueNs::LocalBinding(e.pat())));
231 }
232 }
233 Scope::ExprScope(_) => continue,
234
235 Scope::GenericParams { params, .. } if n_segments > 1 => {
236 if let Some(param) = params.find_by_name(first_name) {
237 let ty = TypeNs::GenericParam(param.idx);
238 return Some(ResolveValueResult::Partial(ty, 1));
239 }
240 }
241 Scope::GenericParams { .. } => continue,
242
243 Scope::ImplBlockScope(impl_) if n_segments > 1 => {
244 if first_name == &name::SELF_TYPE {
245 let ty = TypeNs::SelfType(*impl_);
246 return Some(ResolveValueResult::Partial(ty, 1));
247 }
248 }
249 Scope::AdtScope(adt) if n_segments > 1 => {
250 if first_name == &name::SELF_TYPE {
251 let ty = TypeNs::AdtSelfType(*adt);
252 return Some(ResolveValueResult::Partial(ty, 1));
253 }
254 }
255 Scope::ImplBlockScope(_) | Scope::AdtScope(_) => continue,
256
257 Scope::ModuleScope(m) => {
258 let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path);
259 return match idx {
260 None => {
261 let value = match module_def.take_values()? {
262 ModuleDefId::FunctionId(it) => ValueNs::Function(it.into()),
263 ModuleDefId::AdtId(AdtId::StructId(it)) => {
264 ValueNs::Struct(it.into())
265 }
266 ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariant(it.into()),
267 ModuleDefId::ConstId(it) => ValueNs::Const(it.into()),
268 ModuleDefId::StaticId(it) => ValueNs::Static(it.into()),
269
270 ModuleDefId::AdtId(AdtId::EnumId(_))
271 | ModuleDefId::AdtId(AdtId::UnionId(_))
272 | ModuleDefId::TraitId(_)
273 | ModuleDefId::TypeAliasId(_)
274 | ModuleDefId::BuiltinType(_)
275 | ModuleDefId::ModuleId(_) => return None,
276 };
277 Some(ResolveValueResult::ValueNs(value))
278 }
279 Some(idx) => {
280 let ty = match module_def.take_types()? {
281 ModuleDefId::AdtId(it) => TypeNs::Adt(it.into()),
282 ModuleDefId::TraitId(it) => TypeNs::Trait(it.into()),
283 ModuleDefId::TypeAliasId(it) => TypeNs::TypeAlias(it.into()),
284 ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it),
285
286 ModuleDefId::ModuleId(_)
287 | ModuleDefId::FunctionId(_)
288 | ModuleDefId::EnumVariantId(_)
289 | ModuleDefId::ConstId(_)
290 | ModuleDefId::StaticId(_) => return None,
291 };
292 Some(ResolveValueResult::Partial(ty, idx))
293 }
294 };
295 }
296 }
297 }
298 None
299 }
300
301 pub(crate) fn resolve_path_in_value_ns_fully(
302 &self,
303 db: &impl HirDatabase,
304 path: &Path,
305 ) -> Option<ValueNs> {
306 match self.resolve_path_in_value_ns(db, path)? {
307 ResolveValueResult::ValueNs(it) => Some(it),
308 ResolveValueResult::Partial(..) => None,
309 }
310 }
311
312 pub(crate) fn resolve_path_as_macro(
313 &self,
314 db: &impl DefDatabase,
315 path: &Path,
316 ) -> Option<MacroDef> {
317 let (item_map, module) = self.module()?;
318 item_map.resolve_path(db, module, path).0.get_macros().map(MacroDef::from)
319 }
320
321 pub(crate) fn process_all_names(
322 &self,
323 db: &impl HirDatabase,
324 f: &mut dyn FnMut(Name, ScopeDef),
325 ) {
326 for scope in self.scopes.iter().rev() {
327 scope.process_names(db, f);
328 }
329 }
330
331 pub(crate) fn traits_in_scope(&self, db: &impl HirDatabase) -> FxHashSet<Trait> {
332 let mut traits = FxHashSet::default();
333 for scope in &self.scopes {
334 if let Scope::ModuleScope(m) = scope {
335 if let Some(prelude) = m.crate_def_map.prelude() {
336 let prelude_def_map = db.crate_def_map(prelude.krate);
337 traits
338 .extend(prelude_def_map[prelude.module_id].scope.traits().map(Trait::from));
339 }
340 traits.extend(m.crate_def_map[m.module_id].scope.traits().map(Trait::from));
341 }
342 }
343 traits
344 }
345
346 fn module(&self) -> Option<(&CrateDefMap, CrateModuleId)> {
347 self.scopes.iter().rev().find_map(|scope| match scope {
348 Scope::ModuleScope(m) => Some((&*m.crate_def_map, m.module_id)),
349
350 _ => None,
351 })
352 }
353
354 pub(crate) fn krate(&self) -> Option<Crate> {
355 self.module().map(|t| Crate { crate_id: t.0.krate() })
356 }
357
358 pub(crate) fn where_predicates_in_scope<'a>(
359 &'a self,
360 ) -> impl Iterator<Item = &'a crate::generics::WherePredicate> + 'a {
361 self.scopes
362 .iter()
363 .filter_map(|scope| match scope {
364 Scope::GenericParams { params, .. } => Some(params),
365 _ => None,
366 })
367 .flat_map(|params| params.where_predicates.iter())
368 }
369
370 pub(crate) fn generic_def(&self) -> Option<crate::generics::GenericDef> {
371 self.scopes.iter().find_map(|scope| match scope {
372 Scope::GenericParams { def, .. } => Some(*def),
373 _ => None,
374 })
375 }
376}
377
378impl Resolver {
379 pub(crate) fn push_scope(mut self, scope: Scope) -> Resolver {
380 self.scopes.push(scope);
381 self
382 }
383
384 pub(crate) fn push_generic_params_scope(
385 self,
386 db: &impl DefDatabase,
387 def: GenericDef,
388 ) -> Resolver {
389 let params = def.generic_params(db);
390 if params.params.is_empty() {
391 self
392 } else {
393 self.push_scope(Scope::GenericParams { def, params })
394 }
395 }
396
397 pub(crate) fn push_impl_block_scope(self, impl_block: ImplBlock) -> Resolver {
398 self.push_scope(Scope::ImplBlockScope(impl_block))
399 }
400
401 pub(crate) fn push_module_scope(
402 self,
403 crate_def_map: Arc<CrateDefMap>,
404 module_id: CrateModuleId,
405 ) -> Resolver {
406 self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id }))
407 }
408
409 pub(crate) fn push_expr_scope(
410 self,
411 owner: DefWithBody,
412 expr_scopes: Arc<ExprScopes>,
413 scope_id: ScopeId,
414 ) -> Resolver {
415 self.push_scope(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id }))
416 }
417}
418
419/// For IDE only
420pub enum ScopeDef {
421 ModuleDef(ModuleDef),
422 MacroDef(MacroDef),
423 GenericParam(u32),
424 ImplSelfType(ImplBlock),
425 AdtSelfType(Adt),
426 Local(Local),
427 Unknown,
428}
429
430impl From<PerNs> for ScopeDef {
431 fn from(def: PerNs) -> Self {
432 def.take_types()
433 .or_else(|| def.take_values())
434 .map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into()))
435 .or_else(|| {
436 def.get_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into()))
437 })
438 .unwrap_or(ScopeDef::Unknown)
439 }
440}
441
442impl Scope {
443 fn process_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef)) {
444 match self {
445 Scope::ModuleScope(m) => {
446 // FIXME: should we provide `self` here?
447 // f(
448 // Name::self_param(),
449 // PerNs::types(Resolution::Def {
450 // def: m.module.into(),
451 // }),
452 // );
453 m.crate_def_map[m.module_id].scope.entries().for_each(|(name, res)| {
454 f(name.clone(), res.def.into());
455 });
456 m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| {
457 f(name.clone(), ScopeDef::MacroDef(macro_.into()));
458 });
459 m.crate_def_map.extern_prelude().iter().for_each(|(name, &def)| {
460 f(name.clone(), ScopeDef::ModuleDef(def.into()));
461 });
462 if let Some(prelude) = m.crate_def_map.prelude() {
463 let prelude_def_map = db.crate_def_map(prelude.krate);
464 prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| {
465 f(name.clone(), res.def.into());
466 });
467 }
468 }
469 Scope::GenericParams { params, .. } => {
470 for param in params.params.iter() {
471 f(param.name.clone(), ScopeDef::GenericParam(param.idx))
472 }
473 }
474 Scope::ImplBlockScope(i) => {
475 f(name::SELF_TYPE, ScopeDef::ImplSelfType(*i));
476 }
477 Scope::AdtScope(i) => {
478 f(name::SELF_TYPE, ScopeDef::AdtSelfType(*i));
479 }
480 Scope::ExprScope(scope) => {
481 scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| {
482 let local = Local { parent: scope.owner, pat_id: e.pat() };
483 f(e.name().clone(), ScopeDef::Local(local));
484 });
485 }
486 }
487 }
488}
489
490pub(crate) trait HasResolver {
491 /// Builds a resolver for type references inside this def.
492 fn resolver(self, db: &impl DefDatabase) -> Resolver;
493}
494
495impl HasResolver for Module {
496 fn resolver(self, db: &impl DefDatabase) -> Resolver {
497 let def_map = db.crate_def_map(self.id.krate);
498 Resolver::default().push_module_scope(def_map, self.id.module_id)
499 }
500}
501
502impl HasResolver for Trait {
503 fn resolver(self, db: &impl DefDatabase) -> Resolver {
504 self.module(db).resolver(db).push_generic_params_scope(db, self.into())
505 }
506}
507
508impl<T: Into<Adt>> HasResolver for T {
509 fn resolver(self, db: &impl DefDatabase) -> Resolver {
510 let def = self.into();
511 def.module(db)
512 .resolver(db)
513 .push_generic_params_scope(db, def.into())
514 .push_scope(Scope::AdtScope(def))
515 }
516}
517
518impl HasResolver for Function {
519 fn resolver(self, db: &impl DefDatabase) -> Resolver {
520 self.container(db)
521 .map(|c| c.resolver(db))
522 .unwrap_or_else(|| self.module(db).resolver(db))
523 .push_generic_params_scope(db, self.into())
524 }
525}
526
527impl HasResolver for DefWithBody {
528 fn resolver(self, db: &impl DefDatabase) -> Resolver {
529 match self {
530 DefWithBody::Const(c) => c.resolver(db),
531 DefWithBody::Function(f) => f.resolver(db),
532 DefWithBody::Static(s) => s.resolver(db),
533 }
534 }
535}
536
537impl HasResolver for Const {
538 fn resolver(self, db: &impl DefDatabase) -> Resolver {
539 self.container(db).map(|c| c.resolver(db)).unwrap_or_else(|| self.module(db).resolver(db))
540 }
541}
542
543impl HasResolver for Static {
544 fn resolver(self, db: &impl DefDatabase) -> Resolver {
545 self.module(db).resolver(db)
546 }
547}
548
549impl HasResolver for TypeAlias {
550 fn resolver(self, db: &impl DefDatabase) -> Resolver {
551 self.container(db)
552 .map(|ib| ib.resolver(db))
553 .unwrap_or_else(|| self.module(db).resolver(db))
554 .push_generic_params_scope(db, self.into())
555 }
556}
557
558impl HasResolver for Container {
559 fn resolver(self, db: &impl DefDatabase) -> Resolver {
560 match self {
561 Container::Trait(trait_) => trait_.resolver(db),
562 Container::ImplBlock(impl_block) => impl_block.resolver(db),
563 }
564 }
565}
566
567impl HasResolver for GenericDef {
568 fn resolver(self, db: &impl DefDatabase) -> crate::Resolver {
569 match self {
570 GenericDef::Function(inner) => inner.resolver(db),
571 GenericDef::Adt(adt) => adt.resolver(db),
572 GenericDef::Trait(inner) => inner.resolver(db),
573 GenericDef::TypeAlias(inner) => inner.resolver(db),
574 GenericDef::ImplBlock(inner) => inner.resolver(db),
575 GenericDef::EnumVariant(inner) => inner.parent_enum(db).resolver(db),
576 GenericDef::Const(inner) => inner.resolver(db),
577 }
578 }
579}
580
581impl HasResolver for ImplBlock {
582 fn resolver(self, db: &impl DefDatabase) -> Resolver {
583 self.module(db)
584 .resolver(db)
585 .push_generic_params_scope(db, self.into())
586 .push_impl_block_scope(self)
587 }
588}
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 727310f06..c42ceabdf 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -10,6 +10,8 @@ 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},
14 DefWithBodyId,
13}; 15};
14use hir_expand::{name::AsName, AstId, MacroCallId, MacroCallLoc, MacroFileKind, Source}; 16use hir_expand::{name::AsName, AstId, MacroCallId, MacroCallLoc, MacroFileKind, Source};
15use ra_syntax::{ 17use ra_syntax::{
@@ -21,12 +23,12 @@ use ra_syntax::{
21 23
22use crate::{ 24use crate::{
23 db::HirDatabase, 25 db::HirDatabase,
24 expr::{self, BodySourceMap, ExprScopes, ScopeId}, 26 expr::{BodySourceMap, ExprScopes, ScopeId},
25 ids::LocationCtx, 27 ids::LocationCtx,
26 resolve::{HasResolver, ScopeDef, TypeNs, ValueNs},
27 ty::method_resolution::{self, implements_trait}, 28 ty::method_resolution::{self, implements_trait},
28 AssocItem, Const, DefWithBody, Either, Enum, FromSource, Function, GenericParam, HasBody, 29 Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function,
29 HirFileId, Local, MacroDef, Module, Name, Path, Resolver, Static, Struct, Ty, 30 GenericParam, HasBody, HirFileId, Local, MacroDef, Module, Name, Path, ScopeDef, Static,
31 Struct, Trait, Ty, TypeAlias,
30}; 32};
31 33
32fn 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> {
@@ -34,23 +36,25 @@ fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -
34 match (node.value) { 36 match (node.value) {
35 ast::Module(it) => { 37 ast::Module(it) => {
36 let src = node.with_value(it); 38 let src = node.with_value(it);
37 Some(crate::Module::from_declaration(db, src)?.resolver(db)) 39 Some(crate::Module::from_declaration(db, src)?.id.resolver(db))
38 }, 40 },
39 ast::SourceFile(it) => { 41 ast::SourceFile(it) => {
40 let src = node.with_value(crate::ModuleSource::SourceFile(it)); 42 let src = node.with_value(crate::ModuleSource::SourceFile(it));
41 Some(crate::Module::from_definition(db, src)?.resolver(db)) 43 Some(crate::Module::from_definition(db, src)?.id.resolver(db))
42 }, 44 },
43 ast::StructDef(it) => { 45 ast::StructDef(it) => {
44 let src = node.with_value(it); 46 let src = node.with_value(it);
45 Some(Struct::from_source(db, src)?.resolver(db)) 47 Some(Struct::from_source(db, src)?.id.resolver(db))
46 }, 48 },
47 ast::EnumDef(it) => { 49 ast::EnumDef(it) => {
48 let src = node.with_value(it); 50 let src = node.with_value(it);
49 Some(Enum::from_source(db, src)?.resolver(db)) 51 Some(Enum::from_source(db, src)?.id.resolver(db))
50 }, 52 },
51 _ => match node.value.kind() { 53 _ => match node.value.kind() {
52 FN_DEF | CONST_DEF | STATIC_DEF => { 54 FN_DEF | CONST_DEF | STATIC_DEF => {
53 Some(def_with_body_from_child_node(db, node)?.resolver(db)) 55 let def = def_with_body_from_child_node(db, node)?;
56 let def = DefWithBodyId::from(def);
57 Some(def.resolver(db))
54 } 58 }
55 // FIXME add missing cases 59 // FIXME add missing cases
56 _ => None 60 _ => None
@@ -159,7 +163,7 @@ impl SourceAnalyzer {
159 None => scope_for(&scopes, &source_map, node), 163 None => scope_for(&scopes, &source_map, node),
160 Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)), 164 Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)),
161 }; 165 };
162 let resolver = expr::resolver_for_scope(db, def, scope); 166 let resolver = resolver_for_scope(db, def.into(), scope);
163 SourceAnalyzer { 167 SourceAnalyzer {
164 resolver, 168 resolver,
165 body_owner: Some(def), 169 body_owner: Some(def),
@@ -231,7 +235,7 @@ impl SourceAnalyzer {
231 ) -> Option<MacroDef> { 235 ) -> Option<MacroDef> {
232 // This must be a normal source file rather than macro file. 236 // This must be a normal source file rather than macro file.
233 let path = macro_call.path().and_then(Path::from_ast)?; 237 let path = macro_call.path().and_then(Path::from_ast)?;
234 self.resolver.resolve_path_as_macro(db, &path) 238 self.resolver.resolve_path_as_macro(db, &path).map(|it| it.into())
235 } 239 }
236 240
237 pub fn resolve_hir_path( 241 pub fn resolve_hir_path(
@@ -240,16 +244,18 @@ impl SourceAnalyzer {
240 path: &crate::Path, 244 path: &crate::Path,
241 ) -> Option<PathResolution> { 245 ) -> Option<PathResolution> {
242 let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { 246 let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty {
243 TypeNs::SelfType(it) => PathResolution::SelfType(it), 247 TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
244 TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam { 248 TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam {
245 parent: self.resolver.generic_def().unwrap(), 249 parent: self.resolver.generic_def().unwrap().into(),
246 idx, 250 idx,
247 }), 251 }),
248 TypeNs::AdtSelfType(it) | TypeNs::Adt(it) => PathResolution::Def(it.into()), 252 TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
249 TypeNs::EnumVariant(it) => PathResolution::Def(it.into()), 253 PathResolution::Def(Adt::from(it).into())
250 TypeNs::TypeAlias(it) => PathResolution::Def(it.into()), 254 }
255 TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()),
256 TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
251 TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), 257 TypeNs::BuiltinType(it) => PathResolution::Def(it.into()),
252 TypeNs::Trait(it) => PathResolution::Def(it.into()), 258 TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
253 }); 259 });
254 let values = self.resolver.resolve_path_in_value_ns_fully(db, &path).and_then(|val| { 260 let values = self.resolver.resolve_path_in_value_ns_fully(db, &path).and_then(|val| {
255 let res = match val { 261 let res = match val {
@@ -257,11 +263,11 @@ impl SourceAnalyzer {
257 let var = Local { parent: self.body_owner?, pat_id }; 263 let var = Local { parent: self.body_owner?, pat_id };
258 PathResolution::Local(var) 264 PathResolution::Local(var)
259 } 265 }
260 ValueNs::Function(it) => PathResolution::Def(it.into()), 266 ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()),
261 ValueNs::Const(it) => PathResolution::Def(it.into()), 267 ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()),
262 ValueNs::Static(it) => PathResolution::Def(it.into()), 268 ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()),
263 ValueNs::Struct(it) => PathResolution::Def(it.into()), 269 ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()),
264 ValueNs::EnumVariant(it) => PathResolution::Def(it.into()), 270 ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()),
265 }; 271 };
266 Some(res) 272 Some(res)
267 }); 273 });
@@ -272,7 +278,9 @@ impl SourceAnalyzer {
272 .take_types() 278 .take_types()
273 .map(|it| PathResolution::Def(it.into())); 279 .map(|it| PathResolution::Def(it.into()));
274 types.or(values).or(items).or_else(|| { 280 types.or(values).or(items).or_else(|| {
275 self.resolver.resolve_path_as_macro(db, &path).map(|def| PathResolution::Macro(def)) 281 self.resolver
282 .resolve_path_as_macro(db, &path)
283 .map(|def| PathResolution::Macro(def.into()))
276 }) 284 })
277 } 285 }
278 286
@@ -307,7 +315,22 @@ impl SourceAnalyzer {
307 } 315 }
308 316
309 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)) {
310 self.resolver.process_all_names(db, f) 318 self.resolver.process_all_names(db, &mut |name, def| {
319 let def = match def {
320 resolver::ScopeDef::PerNs(it) => it.into(),
321 resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()),
322 resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()),
323 resolver::ScopeDef::GenericParam(idx) => {
324 let parent = self.resolver.generic_def().unwrap().into();
325 ScopeDef::GenericParam(GenericParam { parent, idx })
326 }
327 resolver::ScopeDef::Local(pat_id) => {
328 let parent = self.resolver.body_owner().unwrap().into();
329 ScopeDef::Local(Local { parent, pat_id })
330 }
331 };
332 f(name, def)
333 })
311 } 334 }
312 335
313 // FIXME: we only use this in `inline_local_variable` assist, ideally, we 336 // FIXME: we only use this in `inline_local_variable` assist, ideally, we
@@ -392,7 +415,7 @@ impl SourceAnalyzer {
392 let std_future_path = known::std_future_future(); 415 let std_future_path = known::std_future_future();
393 416
394 let std_future_trait = match self.resolver.resolve_known_trait(db, &std_future_path) { 417 let std_future_trait = match self.resolver.resolve_known_trait(db, &std_future_path) {
395 Some(it) => it, 418 Some(it) => it.into(),
396 _ => return false, 419 _ => return false,
397 }; 420 };
398 421
@@ -402,7 +425,7 @@ impl SourceAnalyzer {
402 }; 425 };
403 426
404 let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 }; 427 let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 };
405 implements_trait(&canonical_ty, db, &self.resolver, krate, std_future_trait) 428 implements_trait(&canonical_ty, db, &self.resolver, krate.into(), std_future_trait)
406 } 429 }
407 430
408 pub fn expand( 431 pub fn expand(
diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs
index 872a4517d..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
@@ -39,7 +40,7 @@ fn deref_by_trait(
39 ty: &Canonical<Ty>, 40 ty: &Canonical<Ty>,
40) -> Option<Canonical<Ty>> { 41) -> Option<Canonical<Ty>> {
41 let krate = resolver.krate()?; 42 let krate = resolver.krate()?;
42 let deref_trait = match db.lang_item(krate, "deref".into())? { 43 let deref_trait = match db.lang_item(krate.into(), "deref".into())? {
43 crate::lang_item::LangItemTarget::Trait(t) => t, 44 crate::lang_item::LangItemTarget::Trait(t) => t,
44 _ => return None, 45 _ => return None,
45 }; 46 };
@@ -71,7 +72,7 @@ fn deref_by_trait(
71 72
72 let canonical = super::Canonical { num_vars: 1 + ty.num_vars, value: in_env }; 73 let canonical = super::Canonical { num_vars: 1 + ty.num_vars, value: in_env };
73 74
74 let solution = db.trait_solve(krate, canonical)?; 75 let solution = db.trait_solve(krate.into(), canonical)?;
75 76
76 match &solution { 77 match &solution {
77 Solution::Unique(vars) => { 78 Solution::Unique(vars) => {
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 7f9e81d64..69b13baef 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -23,7 +23,9 @@ 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},
28 AdtId, DefWithBodyId,
27}; 29};
28use hir_expand::{diagnostics::DiagnosticSink, name}; 30use hir_expand::{diagnostics::DiagnosticSink, name};
29use ra_arena::map::ArenaMap; 31use ra_arena::map::ArenaMap;
@@ -40,10 +42,9 @@ use crate::{
40 code_model::TypeAlias, 42 code_model::TypeAlias,
41 db::HirDatabase, 43 db::HirDatabase,
42 expr::{BindingAnnotation, Body, ExprId, PatId}, 44 expr::{BindingAnnotation, Body, ExprId, PatId},
43 resolve::{HasResolver, Resolver, TypeNs},
44 ty::infer::diagnostics::InferenceDiagnostic, 45 ty::infer::diagnostics::InferenceDiagnostic,
45 Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, 46 Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path,
46 StructField, VariantDef, 47 StructField, Trait, VariantDef,
47}; 48};
48 49
49macro_rules! ty_app { 50macro_rules! ty_app {
@@ -64,7 +65,7 @@ mod coerce;
64/// The entry point of type inference. 65/// The entry point of type inference.
65pub fn infer_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> { 66pub fn infer_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> {
66 let _p = profile("infer_query"); 67 let _p = profile("infer_query");
67 let resolver = def.resolver(db); 68 let resolver = DefWithBodyId::from(def).resolver(db);
68 let mut ctx = InferenceContext::new(db, def, resolver); 69 let mut ctx = InferenceContext::new(db, def, resolver);
69 70
70 match def { 71 match def {
@@ -377,8 +378,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
377 for obligation in obligations { 378 for obligation in obligations {
378 let in_env = InEnvironment::new(self.trait_env.clone(), obligation.clone()); 379 let in_env = InEnvironment::new(self.trait_env.clone(), obligation.clone());
379 let canonicalized = self.canonicalizer().canonicalize_obligation(in_env); 380 let canonicalized = self.canonicalizer().canonicalize_obligation(in_env);
380 let solution = 381 let solution = self
381 self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone()); 382 .db
383 .trait_solve(self.resolver.krate().unwrap().into(), canonicalized.value.clone());
382 384
383 match solution { 385 match solution {
384 Some(Solution::Unique(substs)) => { 386 Some(Solution::Unique(substs)) => {
@@ -518,17 +520,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
518 // FIXME: this should resolve assoc items as well, see this example: 520 // FIXME: this should resolve assoc items as well, see this example:
519 // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 521 // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521
520 match resolver.resolve_path_in_type_ns_fully(self.db, &path) { 522 match resolver.resolve_path_in_type_ns_fully(self.db, &path) {
521 Some(TypeNs::Adt(Adt::Struct(it))) => it.into(), 523 Some(TypeNs::AdtId(AdtId::StructId(it))) => it.into(),
522 Some(TypeNs::Adt(Adt::Union(it))) => it.into(), 524 Some(TypeNs::AdtId(AdtId::UnionId(it))) => it.into(),
523 Some(TypeNs::AdtSelfType(adt)) => adt.into(), 525 Some(TypeNs::AdtSelfType(adt)) => adt.into(),
524 Some(TypeNs::EnumVariant(it)) => it.into(), 526 Some(TypeNs::EnumVariantId(it)) => it.into(),
525 Some(TypeNs::TypeAlias(it)) => it.into(), 527 Some(TypeNs::TypeAliasId(it)) => it.into(),
526 528
527 Some(TypeNs::SelfType(_)) | 529 Some(TypeNs::SelfType(_)) |
528 Some(TypeNs::GenericParam(_)) | 530 Some(TypeNs::GenericParam(_)) |
529 Some(TypeNs::BuiltinType(_)) | 531 Some(TypeNs::BuiltinType(_)) |
530 Some(TypeNs::Trait(_)) | 532 Some(TypeNs::TraitId(_)) |
531 Some(TypeNs::Adt(Adt::Enum(_))) | 533 Some(TypeNs::AdtId(AdtId::EnumId(_))) |
532 None => { 534 None => {
533 return (Ty::Unknown, None) 535 return (Ty::Unknown, None)
534 } 536 }
@@ -576,26 +578,26 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
576 578
577 fn resolve_into_iter_item(&self) -> Option<TypeAlias> { 579 fn resolve_into_iter_item(&self) -> Option<TypeAlias> {
578 let path = known::std_iter_into_iterator(); 580 let path = known::std_iter_into_iterator();
579 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; 581 let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into();
580 trait_.associated_type_by_name(self.db, &name::ITEM_TYPE) 582 trait_.associated_type_by_name(self.db, &name::ITEM_TYPE)
581 } 583 }
582 584
583 fn resolve_ops_try_ok(&self) -> Option<TypeAlias> { 585 fn resolve_ops_try_ok(&self) -> Option<TypeAlias> {
584 let path = known::std_ops_try(); 586 let path = known::std_ops_try();
585 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; 587 let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into();
586 trait_.associated_type_by_name(self.db, &name::OK_TYPE) 588 trait_.associated_type_by_name(self.db, &name::OK_TYPE)
587 } 589 }
588 590
589 fn resolve_future_future_output(&self) -> Option<TypeAlias> { 591 fn resolve_future_future_output(&self) -> Option<TypeAlias> {
590 let path = known::std_future_future(); 592 let path = known::std_future_future();
591 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; 593 let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into();
592 trait_.associated_type_by_name(self.db, &name::OUTPUT_TYPE) 594 trait_.associated_type_by_name(self.db, &name::OUTPUT_TYPE)
593 } 595 }
594 596
595 fn resolve_boxed_box(&self) -> Option<Adt> { 597 fn resolve_boxed_box(&self) -> Option<Adt> {
596 let path = known::std_boxed_box(); 598 let path = known::std_boxed_box();
597 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; 599 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
598 Some(Adt::Struct(struct_)) 600 Some(Adt::Struct(struct_.into()))
599 } 601 }
600} 602}
601 603
diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs
index 6ea135126..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.
@@ -49,8 +49,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
49 resolver: &Resolver, 49 resolver: &Resolver,
50 ) -> FxHashMap<(TypeCtor, TypeCtor), usize> { 50 ) -> FxHashMap<(TypeCtor, TypeCtor), usize> {
51 let krate = resolver.krate().unwrap(); 51 let krate = resolver.krate().unwrap();
52 let impls = match db.lang_item(krate, "coerce_unsized".into()) { 52 let impls = match db.lang_item(krate.into(), "coerce_unsized".into()) {
53 Some(LangItemTarget::Trait(trait_)) => db.impls_for_trait(krate, trait_), 53 Some(LangItemTarget::Trait(trait_)) => db.impls_for_trait(krate.into(), trait_),
54 _ => return FxHashMap::default(), 54 _ => return FxHashMap::default(),
55 }; 55 };
56 56
diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs
index 5e68a1678..ac570075f 100644
--- a/crates/ra_hir/src/ty/infer/expr.rs
+++ b/crates/ra_hir/src/ty/infer/expr.rs
@@ -6,13 +6,13 @@ 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::{self, 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 ty::{ 17 ty::{
18 autoderef, method_resolution, op, CallableDef, InferTy, IntTy, Mutability, Namespace, 18 autoderef, method_resolution, op, CallableDef, InferTy, IntTy, Mutability, Namespace,
@@ -22,6 +22,8 @@ use crate::{
22 Adt, Name, 22 Adt, Name,
23}; 23};
24 24
25use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch};
26
25impl<'a, D: HirDatabase> InferenceContext<'a, D> { 27impl<'a, D: HirDatabase> InferenceContext<'a, D> {
26 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 {
27 let ty = self.infer_expr_inner(tgt_expr, expected); 29 let ty = self.infer_expr_inner(tgt_expr, expected);
@@ -186,7 +188,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
186 } 188 }
187 Expr::Path(p) => { 189 Expr::Path(p) => {
188 // FIXME this could be more efficient... 190 // FIXME this could be more efficient...
189 let resolver = expr::resolver_for_expr(self.db, self.owner, tgt_expr); 191 let resolver = resolver_for_expr(self.db, self.owner.into(), tgt_expr);
190 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) 192 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown)
191 } 193 }
192 Expr::Continue => Ty::simple(TypeCtor::Never), 194 Expr::Continue => Ty::simple(TypeCtor::Never),
diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs
index 31ca675aa..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, 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,
@@ -60,11 +63,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
60 let ty = self.resolve_ty_as_possible(&mut vec![], ty); 63 let ty = self.resolve_ty_as_possible(&mut vec![], ty);
61 return Some(ty); 64 return Some(ty);
62 } 65 }
63 ValueNs::Function(it) => it.into(), 66 ValueNs::FunctionId(it) => it.into(),
64 ValueNs::Const(it) => it.into(), 67 ValueNs::ConstId(it) => it.into(),
65 ValueNs::Static(it) => it.into(), 68 ValueNs::StaticId(it) => it.into(),
66 ValueNs::Struct(it) => it.into(), 69 ValueNs::StructId(it) => it.into(),
67 ValueNs::EnumVariant(it) => it.into(), 70 ValueNs::EnumVariantId(it) => it.into(),
68 }; 71 };
69 72
70 let mut ty = self.db.type_for_def(typable, Namespace::Values); 73 let mut ty = self.db.type_for_def(typable, Namespace::Values);
@@ -94,13 +97,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
94 let is_before_last = remaining_segments.len() == 1; 97 let is_before_last = remaining_segments.len() == 1;
95 98
96 match (def, is_before_last) { 99 match (def, is_before_last) {
97 (TypeNs::Trait(trait_), true) => { 100 (TypeNs::TraitId(trait_), true) => {
98 let segment = 101 let segment =
99 remaining_segments.last().expect("there should be at least one segment here"); 102 remaining_segments.last().expect("there should be at least one segment here");
100 let trait_ref = TraitRef::from_resolved_path( 103 let trait_ref = TraitRef::from_resolved_path(
101 self.db, 104 self.db,
102 &self.resolver, 105 &self.resolver,
103 trait_, 106 trait_.into(),
104 resolved_segment, 107 resolved_segment,
105 None, 108 None,
106 ); 109 );
@@ -160,8 +163,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
160 AssocItem::TypeAlias(_) => None, 163 AssocItem::TypeAlias(_) => None,
161 })?; 164 })?;
162 let def = match item { 165 let def = match item {
163 AssocItem::Function(f) => ValueNs::Function(f), 166 AssocItem::Function(f) => ValueNs::FunctionId(f.id),
164 AssocItem::Const(c) => ValueNs::Const(c), 167 AssocItem::Const(c) => ValueNs::ConstId(c.id),
165 AssocItem::TypeAlias(_) => unreachable!(), 168 AssocItem::TypeAlias(_) => unreachable!(),
166 }; 169 };
167 let substs = Substs::build_for_def(self.db, item) 170 let substs = Substs::build_for_def(self.db, item)
@@ -193,8 +196,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
193 method_resolution::LookupMode::Path, 196 method_resolution::LookupMode::Path,
194 move |_ty, item| { 197 move |_ty, item| {
195 let def = match item { 198 let def = match item {
196 AssocItem::Function(f) => ValueNs::Function(f), 199 AssocItem::Function(f) => ValueNs::FunctionId(f.id),
197 AssocItem::Const(c) => ValueNs::Const(c), 200 AssocItem::Const(c) => ValueNs::ConstId(c.id),
198 AssocItem::TypeAlias(_) => unreachable!(), 201 AssocItem::TypeAlias(_) => unreachable!(),
199 }; 202 };
200 let substs = match item.container(self.db) { 203 let substs = match item.container(self.db) {
@@ -224,7 +227,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
224 } 227 }
225 228
226 fn find_self_types(&self, def: &ValueNs, actual_def_ty: Ty) -> Option<Substs> { 229 fn find_self_types(&self, def: &ValueNs, actual_def_ty: Ty) -> Option<Substs> {
227 if let ValueNs::Function(func) = def { 230 if let ValueNs::FunctionId(func) = def {
231 let func = Function::from(*func);
228 // We only do the infer if parent has generic params 232 // We only do the infer if parent has generic params
229 let gen = func.generic_params(self.db); 233 let gen = func.generic_params(self.db);
230 if gen.count_parent_params() == 0 { 234 if gen.count_parent_params() == 0 {
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index 397ee7d5f..c6ad0811b 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -11,7 +11,9 @@ 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},
16 GenericDefId,
15}; 17};
16 18
17use super::{ 19use super::{
@@ -22,14 +24,13 @@ use crate::{
22 db::HirDatabase, 24 db::HirDatabase,
23 generics::HasGenericParams, 25 generics::HasGenericParams,
24 generics::{GenericDef, WherePredicate}, 26 generics::{GenericDef, WherePredicate},
25 resolve::{HasResolver, Resolver, TypeNs},
26 ty::{ 27 ty::{
27 primitive::{FloatTy, IntTy, Uncertain}, 28 primitive::{FloatTy, IntTy, Uncertain},
28 Adt, 29 Adt,
29 }, 30 },
30 util::make_mut_slice, 31 util::make_mut_slice,
31 Const, Enum, EnumVariant, Function, ModuleDef, Path, Static, Struct, StructField, Trait, 32 Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, StructField,
32 TypeAlias, Union, VariantDef, 33 Trait, TypeAlias, Union, VariantDef,
33}; 34};
34 35
35// FIXME: this is only really used in `type_for_def`, which contains a bunch of 36// FIXME: this is only really used in `type_for_def`, which contains a bunch of
@@ -156,9 +157,14 @@ impl Ty {
156 remaining_segments: &[PathSegment], 157 remaining_segments: &[PathSegment],
157 ) -> Ty { 158 ) -> Ty {
158 let ty = match resolution { 159 let ty = match resolution {
159 TypeNs::Trait(trait_) => { 160 TypeNs::TraitId(trait_) => {
160 let trait_ref = 161 let trait_ref = TraitRef::from_resolved_path(
161 TraitRef::from_resolved_path(db, resolver, trait_, resolved_segment, None); 162 db,
163 resolver,
164 trait_.into(),
165 resolved_segment,
166 None,
167 );
162 return if remaining_segments.len() == 1 { 168 return if remaining_segments.len() == 1 {
163 let segment = &remaining_segments[0]; 169 let segment = &remaining_segments[0];
164 match trait_ref 170 match trait_ref
@@ -189,18 +195,18 @@ impl Ty {
189 let name = resolved_segment.name.clone(); 195 let name = resolved_segment.name.clone();
190 Ty::Param { idx, name } 196 Ty::Param { idx, name }
191 } 197 }
192 TypeNs::SelfType(impl_block) => impl_block.target_ty(db), 198 TypeNs::SelfType(impl_block) => ImplBlock::from(impl_block).target_ty(db),
193 TypeNs::AdtSelfType(adt) => adt.ty(db), 199 TypeNs::AdtSelfType(adt) => Adt::from(adt).ty(db),
194 200
195 TypeNs::Adt(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), 201 TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()),
196 TypeNs::BuiltinType(it) => { 202 TypeNs::BuiltinType(it) => {
197 Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) 203 Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into())
198 } 204 }
199 TypeNs::TypeAlias(it) => { 205 TypeNs::TypeAliasId(it) => {
200 Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) 206 Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into())
201 } 207 }
202 // FIXME: report error 208 // FIXME: report error
203 TypeNs::EnumVariant(_) => return Ty::Unknown, 209 TypeNs::EnumVariantId(_) => return Ty::Unknown,
204 }; 210 };
205 211
206 Ty::from_type_relative_path(db, resolver, ty, remaining_segments) 212 Ty::from_type_relative_path(db, resolver, ty, remaining_segments)
@@ -247,7 +253,7 @@ impl Ty {
247 Some(def) => def, 253 Some(def) => def,
248 None => return Ty::Unknown, // this can't actually happen 254 None => return Ty::Unknown, // this can't actually happen
249 }; 255 };
250 let predicates = db.generic_predicates_for_param(def, param_idx); 256 let predicates = db.generic_predicates_for_param(def.into(), param_idx);
251 let traits_from_env = predicates.iter().filter_map(|pred| match pred { 257 let traits_from_env = predicates.iter().filter_map(|pred| match pred {
252 GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_), 258 GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_),
253 _ => None, 259 _ => None,
@@ -391,11 +397,11 @@ impl TraitRef {
391 explicit_self_ty: Option<Ty>, 397 explicit_self_ty: Option<Ty>,
392 ) -> Option<Self> { 398 ) -> Option<Self> {
393 let resolved = match resolver.resolve_path_in_type_ns_fully(db, &path)? { 399 let resolved = match resolver.resolve_path_in_type_ns_fully(db, &path)? {
394 TypeNs::Trait(tr) => tr, 400 TypeNs::TraitId(tr) => tr,
395 _ => return None, 401 _ => return None,
396 }; 402 };
397 let segment = path.segments.last().expect("path should have at least one segment"); 403 let segment = path.segments.last().expect("path should have at least one segment");
398 Some(TraitRef::from_resolved_path(db, resolver, resolved, segment, explicit_self_ty)) 404 Some(TraitRef::from_resolved_path(db, resolver, resolved.into(), segment, explicit_self_ty))
399 } 405 }
400 406
401 pub(super) fn from_resolved_path( 407 pub(super) fn from_resolved_path(
@@ -548,8 +554,8 @@ pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSi
548pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { 554pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty {
549 let parent_def = field.parent_def(db); 555 let parent_def = field.parent_def(db);
550 let resolver = match parent_def { 556 let resolver = match parent_def {
551 VariantDef::Struct(it) => it.resolver(db), 557 VariantDef::Struct(it) => it.id.resolver(db),
552 VariantDef::EnumVariant(it) => it.parent_enum(db).resolver(db), 558 VariantDef::EnumVariant(it) => it.parent.id.resolver(db),
553 }; 559 };
554 let var_data = parent_def.variant_data(db); 560 let var_data = parent_def.variant_data(db);
555 let type_ref = &var_data.fields().unwrap()[field.id].type_ref; 561 let type_ref = &var_data.fields().unwrap()[field.id].type_ref;
@@ -569,7 +575,7 @@ pub(crate) fn generic_predicates_for_param_query(
569 def: GenericDef, 575 def: GenericDef,
570 param_idx: u32, 576 param_idx: u32,
571) -> Arc<[GenericPredicate]> { 577) -> Arc<[GenericPredicate]> {
572 let resolver = def.resolver(db); 578 let resolver = GenericDefId::from(def).resolver(db);
573 resolver 579 resolver
574 .where_predicates_in_scope() 580 .where_predicates_in_scope()
575 // we have to filter out all other predicates *first*, before attempting to lower them 581 // we have to filter out all other predicates *first*, before attempting to lower them
@@ -595,7 +601,7 @@ pub(crate) fn generic_predicates_query(
595 db: &impl HirDatabase, 601 db: &impl HirDatabase,
596 def: GenericDef, 602 def: GenericDef,
597) -> Arc<[GenericPredicate]> { 603) -> Arc<[GenericPredicate]> {
598 let resolver = def.resolver(db); 604 let resolver = GenericDefId::from(def).resolver(db);
599 resolver 605 resolver
600 .where_predicates_in_scope() 606 .where_predicates_in_scope()
601 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) 607 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred))
@@ -604,7 +610,7 @@ pub(crate) fn generic_predicates_query(
604 610
605/// Resolve the default type params from generics 611/// Resolve the default type params from generics
606pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> Substs { 612pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> Substs {
607 let resolver = def.resolver(db); 613 let resolver = GenericDefId::from(def).resolver(db);
608 let generic_params = def.generic_params(db); 614 let generic_params = def.generic_params(db);
609 615
610 let defaults = generic_params 616 let defaults = generic_params
@@ -618,7 +624,7 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) ->
618 624
619fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { 625fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig {
620 let data = def.data(db); 626 let data = def.data(db);
621 let resolver = def.resolver(db); 627 let resolver = def.id.resolver(db);
622 let params = data.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); 628 let params = data.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>();
623 let ret = Ty::from_hir(db, &resolver, data.ret_type()); 629 let ret = Ty::from_hir(db, &resolver, data.ret_type());
624 FnSig::from_params_and_return(params, ret) 630 FnSig::from_params_and_return(params, ret)
@@ -635,7 +641,7 @@ fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
635/// Build the declared type of a const. 641/// Build the declared type of a const.
636fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { 642fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty {
637 let data = def.data(db); 643 let data = def.data(db);
638 let resolver = def.resolver(db); 644 let resolver = def.id.resolver(db);
639 645
640 Ty::from_hir(db, &resolver, data.type_ref()) 646 Ty::from_hir(db, &resolver, data.type_ref())
641} 647}
@@ -643,7 +649,7 @@ fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty {
643/// Build the declared type of a static. 649/// Build the declared type of a static.
644fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { 650fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty {
645 let data = def.data(db); 651 let data = def.data(db);
646 let resolver = def.resolver(db); 652 let resolver = def.id.resolver(db);
647 653
648 Ty::from_hir(db, &resolver, data.type_ref()) 654 Ty::from_hir(db, &resolver, data.type_ref())
649} 655}
@@ -695,7 +701,7 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig {
695 Some(fields) => fields, 701 Some(fields) => fields,
696 None => panic!("fn_sig_for_struct_constructor called on unit struct"), 702 None => panic!("fn_sig_for_struct_constructor called on unit struct"),
697 }; 703 };
698 let resolver = def.resolver(db); 704 let resolver = def.id.resolver(db);
699 let params = fields 705 let params = fields
700 .iter() 706 .iter()
701 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 707 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
@@ -721,7 +727,7 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant)
721 Some(fields) => fields, 727 Some(fields) => fields,
722 None => panic!("fn_sig_for_enum_variant_constructor called for unit variant"), 728 None => panic!("fn_sig_for_enum_variant_constructor called for unit variant"),
723 }; 729 };
724 let resolver = def.parent_enum(db).resolver(db); 730 let resolver = def.parent.id.resolver(db);
725 let params = fields 731 let params = fields
726 .iter() 732 .iter()
727 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 733 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
@@ -750,7 +756,7 @@ fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt> + HasGenericParams) -
750 756
751fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { 757fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty {
752 let generics = t.generic_params(db); 758 let generics = t.generic_params(db);
753 let resolver = t.resolver(db); 759 let resolver = t.id.resolver(db);
754 let type_ref = t.type_ref(db); 760 let type_ref = t.type_ref(db);
755 let substs = Substs::identity(&generics); 761 let substs = Substs::identity(&generics);
756 let inner = Ty::from_hir(db, &resolver, &type_ref.unwrap_or(TypeRef::Error)); 762 let inner = Ty::from_hir(db, &resolver, &type_ref.unwrap_or(TypeRef::Error));
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index f377fca48..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,
@@ -172,9 +172,14 @@ pub(crate) fn iterate_method_candidates<T>(
172 // rustc does an autoderef and then autoref again). 172 // rustc does an autoderef and then autoref again).
173 173
174 for derefed_ty in autoderef::autoderef(db, resolver, ty.clone()) { 174 for derefed_ty in autoderef::autoderef(db, resolver, ty.clone()) {
175 if let Some(result) = 175 if let Some(result) = iterate_inherent_methods(
176 iterate_inherent_methods(&derefed_ty, db, name, mode, krate, &mut callback) 176 &derefed_ty,
177 { 177 db,
178 name,
179 mode,
180 krate.into(),
181 &mut callback,
182 ) {
178 return Some(result); 183 return Some(result);
179 } 184 }
180 if let Some(result) = iterate_trait_method_candidates( 185 if let Some(result) = iterate_trait_method_candidates(
@@ -192,7 +197,7 @@ pub(crate) fn iterate_method_candidates<T>(
192 LookupMode::Path => { 197 LookupMode::Path => {
193 // No autoderef for path lookups 198 // No autoderef for path lookups
194 if let Some(result) = 199 if let Some(result) =
195 iterate_inherent_methods(&ty, db, name, mode, krate, &mut callback) 200 iterate_inherent_methods(&ty, db, name, mode, krate.into(), &mut callback)
196 { 201 {
197 return Some(result); 202 return Some(result);
198 } 203 }
@@ -224,7 +229,9 @@ fn iterate_trait_method_candidates<T>(
224 .trait_predicates_for_self_ty(&ty.value) 229 .trait_predicates_for_self_ty(&ty.value)
225 .map(|tr| tr.trait_) 230 .map(|tr| tr.trait_)
226 .flat_map(|t| t.all_super_traits(db)); 231 .flat_map(|t| t.all_super_traits(db));
227 let traits = inherent_trait.chain(traits_from_env).chain(resolver.traits_in_scope(db)); 232 let traits = inherent_trait
233 .chain(traits_from_env)
234 .chain(resolver.traits_in_scope(db).into_iter().map(Trait::from));
228 'traits: for t in traits { 235 'traits: for t in traits {
229 let data = t.trait_data(db); 236 let data = t.trait_data(db);
230 237
@@ -238,7 +245,7 @@ fn iterate_trait_method_candidates<T>(
238 } 245 }
239 if !known_implemented { 246 if !known_implemented {
240 let goal = generic_implements_goal(db, env.clone(), t, ty.clone()); 247 let goal = generic_implements_goal(db, env.clone(), t, ty.clone());
241 if db.trait_solve(krate, goal).is_none() { 248 if db.trait_solve(krate.into(), goal).is_none() {
242 continue 'traits; 249 continue 'traits;
243 } 250 }
244 } 251 }