diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-11-21 12:50:12 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2019-11-21 12:50:12 +0000 |
commit | 1f61915bde4c5d8d4fe2e9b8dfa9445008730b79 (patch) | |
tree | a6fd0b6ad8b6c87d28e6e1b36bb9b2fbae2c1b09 /crates/ra_hir/src | |
parent | 612a72fc4ea4376920f2a7da7b3c334227c1716c (diff) | |
parent | c37d1c5b381365ce2d07dfe4b871e43995ccea2d (diff) |
Merge #2337
2337: Move resolver to hir_def r=matklad a=matklad
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 48 | ||||
-rw-r--r-- | crates/ra_hir/src/expr.rs | 33 | ||||
-rw-r--r-- | crates/ra_hir/src/from_id.rs | 88 | ||||
-rw-r--r-- | crates/ra_hir/src/impl_block.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/resolve.rs | 588 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 75 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/autoderef.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 32 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/coerce.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/expr.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/path.rs | 36 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 56 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 21 |
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 | }; |
18 | use hir_expand::{ | 20 | use 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 { | |||
1068 | pub struct ImplBlock { | 1065 | pub struct ImplBlock { |
1069 | pub(crate) id: ImplId, | 1066 | pub(crate) id: ImplId, |
1070 | } | 1067 | } |
1068 | |||
1069 | /// For IDE only | ||
1070 | pub enum ScopeDef { | ||
1071 | ModuleDef(ModuleDef), | ||
1072 | MacroDef(MacroDef), | ||
1073 | GenericParam(GenericParam), | ||
1074 | ImplSelfType(ImplBlock), | ||
1075 | AdtSelfType(Adt), | ||
1076 | Local(Local), | ||
1077 | Unknown, | ||
1078 | } | ||
1079 | |||
1080 | impl 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 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::path::known; | 5 | use hir_def::{path::known, resolver::HasResolver}; |
6 | use hir_expand::diagnostics::DiagnosticSink; | 6 | use hir_expand::diagnostics::DiagnosticSink; |
7 | use ra_syntax::ast; | 7 | use ra_syntax::ast; |
8 | use ra_syntax::AstPtr; | 8 | use ra_syntax::AstPtr; |
@@ -11,9 +11,8 @@ use rustc_hash::FxHashSet; | |||
11 | use crate::{ | 11 | use 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 | ||
19 | pub use hir_def::{ | 18 | pub 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? | ||
31 | pub(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 | |||
40 | pub(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 | |||
54 | pub(crate) struct ExprValidator<'a, 'b: 'a> { | 29 | pub(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 | ||
6 | use hir_def::{AdtId, AssocItemId, DefWithBodyId, EnumVariantId, GenericDefId, ModuleDefId}; | 6 | use hir_def::{ |
7 | AdtId, AssocItemId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, | ||
8 | ModuleDefId, StaticId, StructId, TypeAliasId, UnionId, | ||
9 | }; | ||
7 | 10 | ||
8 | use crate::{Adt, AssocItem, DefWithBody, EnumVariant, GenericDef, ModuleDef}; | 11 | use crate::{ |
12 | ty::TypableDef, Adt, AssocItem, Const, Crate, DefWithBody, EnumVariant, Function, GenericDef, | ||
13 | ModuleDef, Static, TypeAlias, | ||
14 | }; | ||
15 | |||
16 | impl From<ra_db::CrateId> for Crate { | ||
17 | fn from(crate_id: ra_db::CrateId) -> Self { | ||
18 | Crate { crate_id } | ||
19 | } | ||
20 | } | ||
9 | 21 | ||
10 | macro_rules! from_id { | 22 | macro_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 | ||
98 | impl 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 | |||
86 | impl From<AssocItemId> for AssocItem { | 108 | impl 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 | |||
148 | impl From<AdtId> for TypableDef { | ||
149 | fn from(id: AdtId) -> Self { | ||
150 | Adt::from(id).into() | ||
151 | } | ||
152 | } | ||
153 | |||
154 | impl From<StructId> for TypableDef { | ||
155 | fn from(id: StructId) -> Self { | ||
156 | AdtId::StructId(id).into() | ||
157 | } | ||
158 | } | ||
159 | |||
160 | impl From<UnionId> for TypableDef { | ||
161 | fn from(id: UnionId) -> Self { | ||
162 | AdtId::UnionId(id).into() | ||
163 | } | ||
164 | } | ||
165 | |||
166 | impl From<EnumId> for TypableDef { | ||
167 | fn from(id: EnumId) -> Self { | ||
168 | AdtId::EnumId(id).into() | ||
169 | } | ||
170 | } | ||
171 | |||
172 | impl From<EnumVariantId> for TypableDef { | ||
173 | fn from(id: EnumVariantId) -> Self { | ||
174 | EnumVariant::from(id).into() | ||
175 | } | ||
176 | } | ||
177 | |||
178 | impl From<TypeAliasId> for TypableDef { | ||
179 | fn from(id: TypeAliasId) -> Self { | ||
180 | TypeAlias::from(id).into() | ||
181 | } | ||
182 | } | ||
183 | |||
184 | impl From<FunctionId> for TypableDef { | ||
185 | fn from(id: FunctionId) -> Self { | ||
186 | Function::from(id).into() | ||
187 | } | ||
188 | } | ||
189 | impl From<ConstId> for TypableDef { | ||
190 | fn from(id: ConstId) -> Self { | ||
191 | Const::from(id).into() | ||
192 | } | ||
193 | } | ||
194 | impl From<StaticId> for TypableDef { | ||
195 | fn from(id: StaticId) -> Self { | ||
196 | Static::from(id).into() | ||
197 | } | ||
198 | } | ||
199 | |||
200 | impl 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 | ||
3 | use hir_def::{type_ref::TypeRef, AstItemDef}; | 3 | use hir_def::{resolver::HasResolver, type_ref::TypeRef, AstItemDef}; |
4 | use ra_syntax::ast::{self}; | 4 | use ra_syntax::ast; |
5 | 5 | ||
6 | use crate::{ | 6 | use 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; | |||
38 | mod expr; | 38 | mod expr; |
39 | mod lang_item; | 39 | mod lang_item; |
40 | pub mod generics; | 40 | pub mod generics; |
41 | mod resolve; | ||
42 | pub mod diagnostics; | 41 | pub mod diagnostics; |
43 | mod util; | 42 | mod util; |
44 | 43 | ||
@@ -52,8 +51,6 @@ mod test_db; | |||
52 | #[cfg(test)] | 51 | #[cfg(test)] |
53 | mod marks; | 52 | mod marks; |
54 | 53 | ||
55 | use crate::resolve::Resolver; | ||
56 | |||
57 | pub use crate::{ | 54 | pub 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. | ||
2 | use std::sync::Arc; | ||
3 | |||
4 | use hir_def::{ | ||
5 | builtin_type::BuiltinType, | ||
6 | nameres::CrateDefMap, | ||
7 | path::{Path, PathKind}, | ||
8 | AdtId, CrateModuleId, ModuleDefId, | ||
9 | }; | ||
10 | use hir_expand::name::{self, Name}; | ||
11 | use rustc_hash::FxHashSet; | ||
12 | |||
13 | use 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)] | ||
23 | pub(crate) struct Resolver { | ||
24 | scopes: Vec<Scope>, | ||
25 | } | ||
26 | |||
27 | // FIXME how to store these best | ||
28 | #[derive(Debug, Clone)] | ||
29 | pub(crate) struct ModuleItemMap { | ||
30 | crate_def_map: Arc<CrateDefMap>, | ||
31 | module_id: CrateModuleId, | ||
32 | } | ||
33 | |||
34 | #[derive(Debug, Clone)] | ||
35 | pub(crate) struct ExprScope { | ||
36 | owner: DefWithBody, | ||
37 | expr_scopes: Arc<ExprScopes>, | ||
38 | scope_id: ScopeId, | ||
39 | } | ||
40 | |||
41 | #[derive(Debug, Clone)] | ||
42 | pub(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)] | ||
56 | pub(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)] | ||
71 | pub(crate) enum ResolveValueResult { | ||
72 | ValueNs(ValueNs), | ||
73 | Partial(TypeNs, usize), | ||
74 | } | ||
75 | |||
76 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
77 | pub(crate) enum ValueNs { | ||
78 | LocalBinding(PatId), | ||
79 | Function(Function), | ||
80 | Const(Const), | ||
81 | Static(Static), | ||
82 | Struct(Struct), | ||
83 | EnumVariant(EnumVariant), | ||
84 | } | ||
85 | |||
86 | impl 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 | |||
378 | impl 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 | ||
420 | pub enum ScopeDef { | ||
421 | ModuleDef(ModuleDef), | ||
422 | MacroDef(MacroDef), | ||
423 | GenericParam(u32), | ||
424 | ImplSelfType(ImplBlock), | ||
425 | AdtSelfType(Adt), | ||
426 | Local(Local), | ||
427 | Unknown, | ||
428 | } | ||
429 | |||
430 | impl 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 | |||
442 | impl 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 | |||
490 | pub(crate) trait HasResolver { | ||
491 | /// Builds a resolver for type references inside this def. | ||
492 | fn resolver(self, db: &impl DefDatabase) -> Resolver; | ||
493 | } | ||
494 | |||
495 | impl 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 | |||
502 | impl 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 | |||
508 | impl<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 | |||
518 | impl 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 | |||
527 | impl 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 | |||
537 | impl 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 | |||
543 | impl HasResolver for Static { | ||
544 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
545 | self.module(db).resolver(db) | ||
546 | } | ||
547 | } | ||
548 | |||
549 | impl 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 | |||
558 | impl 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 | |||
567 | impl 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 | |||
581 | impl 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; | |||
10 | use hir_def::{ | 10 | use 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 | }; |
14 | use hir_expand::{name::AsName, AstId, MacroCallId, MacroCallLoc, MacroFileKind, Source}; | 16 | use hir_expand::{name::AsName, AstId, MacroCallId, MacroCallLoc, MacroFileKind, Source}; |
15 | use ra_syntax::{ | 17 | use ra_syntax::{ |
@@ -21,12 +23,12 @@ use ra_syntax::{ | |||
21 | 23 | ||
22 | use crate::{ | 24 | use 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 | ||
32 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { | 34 | fn 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 | ||
6 | use std::iter::successors; | 6 | use std::iter::successors; |
7 | 7 | ||
8 | use hir_def::resolver::Resolver; | ||
8 | use hir_expand::name; | 9 | use hir_expand::name; |
9 | use log::{info, warn}; | 10 | use log::{info, warn}; |
10 | 11 | ||
11 | use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; | 12 | use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; |
12 | use crate::{db::HirDatabase, generics::HasGenericParams, Resolver}; | 13 | use crate::{db::HirDatabase, generics::HasGenericParams}; |
13 | 14 | ||
14 | const AUTODEREF_RECURSION_LIMIT: usize = 10; | 15 | const 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 | ||
24 | use hir_def::{ | 24 | use 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 | }; |
28 | use hir_expand::{diagnostics::DiagnosticSink, name}; | 30 | use hir_expand::{diagnostics::DiagnosticSink, name}; |
29 | use ra_arena::map::ArenaMap; | 31 | use 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 | ||
49 | macro_rules! ty_app { | 50 | macro_rules! ty_app { |
@@ -64,7 +65,7 @@ mod coerce; | |||
64 | /// The entry point of type inference. | 65 | /// The entry point of type inference. |
65 | pub fn infer_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> { | 66 | pub 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 | ||
7 | use hir_def::resolver::Resolver; | ||
7 | use rustc_hash::FxHashMap; | 8 | use rustc_hash::FxHashMap; |
8 | |||
9 | use test_utils::tested_by; | 9 | use test_utils::tested_by; |
10 | 10 | ||
11 | use super::{InferTy, InferenceContext, TypeVarValue}; | ||
12 | use crate::{ | 11 | use 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 | ||
18 | use super::{InferTy, InferenceContext, TypeVarValue}; | ||
19 | |||
20 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 20 | impl<'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; | |||
6 | use hir_def::{ | 6 | use 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 | }; |
10 | use hir_expand::name; | 11 | use hir_expand::name; |
11 | 12 | ||
12 | use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; | ||
13 | use crate::{ | 13 | use 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 | ||
25 | use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; | ||
26 | |||
25 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 27 | impl<'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 | ||
3 | use hir_def::path::PathSegment; | 3 | use hir_def::{ |
4 | path::PathSegment, | ||
5 | resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs}, | ||
6 | }; | ||
4 | 7 | ||
5 | use super::{ExprOrPatId, InferenceContext, TraitRef}; | ||
6 | use crate::{ | 8 | use 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 | ||
15 | use super::{ExprOrPatId, InferenceContext, TraitRef}; | ||
16 | |||
14 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 17 | impl<'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; | |||
11 | use hir_def::{ | 11 | use 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 | ||
17 | use super::{ | 19 | use 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 | |||
548 | pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { | 554 | pub(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 |
606 | pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> Substs { | 612 | pub(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 | ||
619 | fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { | 625 | fn 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. |
636 | fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { | 642 | fn 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. |
644 | fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { | 650 | fn 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 | ||
751 | fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { | 757 | fn 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 @@ | |||
5 | use std::sync::Arc; | 5 | use std::sync::Arc; |
6 | 6 | ||
7 | use arrayvec::ArrayVec; | 7 | use arrayvec::ArrayVec; |
8 | use hir_def::resolver::Resolver; | ||
8 | use rustc_hash::FxHashMap; | 9 | use rustc_hash::FxHashMap; |
9 | 10 | ||
10 | use crate::{ | 11 | use 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 | } |