aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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/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
-rw-r--r--crates/ra_hir_def/src/body/lower.rs2
-rw-r--r--crates/ra_hir_def/src/body/scope.rs18
-rw-r--r--crates/ra_hir_def/src/lib.rs1
-rw-r--r--crates/ra_hir_def/src/marks.rs1
-rw-r--r--crates/ra_hir_def/src/resolver.rs (renamed from crates/ra_hir/src/resolve.rs)358
-rw-r--r--crates/ra_hir_def/src/traits.rs9
19 files changed, 493 insertions, 327 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/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 }
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index a5bb60e85..77f091288 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -12,6 +12,7 @@ use ra_syntax::{
12 }, 12 },
13 AstNode, AstPtr, 13 AstNode, AstPtr,
14}; 14};
15use test_utils::tested_by;
15 16
16use crate::{ 17use crate::{
17 body::{Body, BodySourceMap, Expander, PatPtr}, 18 body::{Body, BodySourceMap, Expander, PatPtr},
@@ -153,6 +154,7 @@ where
153 None => self.collect_expr_opt(condition.expr()), 154 None => self.collect_expr_opt(condition.expr()),
154 // if let -- desugar to match 155 // if let -- desugar to match
155 Some(pat) => { 156 Some(pat) => {
157 tested_by!(infer_resolve_while_let);
156 let pat = self.collect_pat(pat); 158 let pat = self.collect_pat(pat);
157 let match_expr = self.collect_expr_opt(condition.expr()); 159 let match_expr = self.collect_expr_opt(condition.expr());
158 let placeholder_pat = self.missing_pat(); 160 let placeholder_pat = self.missing_pat();
diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs
index aeb71ff22..5d7d17231 100644
--- a/crates/ra_hir_def/src/body/scope.rs
+++ b/crates/ra_hir_def/src/body/scope.rs
@@ -174,7 +174,7 @@ mod tests {
174 use hir_expand::{name::AsName, Source}; 174 use hir_expand::{name::AsName, Source};
175 use ra_db::{fixture::WithFixture, FileId, SourceDatabase}; 175 use ra_db::{fixture::WithFixture, FileId, SourceDatabase};
176 use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; 176 use ra_syntax::{algo::find_node_at_offset, ast, AstNode};
177 use test_utils::{assert_eq_text, extract_offset}; 177 use test_utils::{assert_eq_text, covers, extract_offset};
178 178
179 use crate::{db::DefDatabase2, test_db::TestDB, FunctionId, ModuleDefId}; 179 use crate::{db::DefDatabase2, test_db::TestDB, FunctionId, ModuleDefId};
180 180
@@ -382,4 +382,20 @@ mod tests {
382 53, 382 53,
383 ); 383 );
384 } 384 }
385
386 #[test]
387 fn infer_resolve_while_let() {
388 covers!(infer_resolve_while_let);
389 do_check_local_name(
390 r#"
391fn test() {
392 let foo: Option<f32> = None;
393 while let Option::Some(spam) = foo {
394 spam<|>
395 }
396}
397"#,
398 75,
399 );
400 }
385} 401}
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index 0af41de87..d579f5c7e 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -19,6 +19,7 @@ pub mod expr;
19pub mod body; 19pub mod body;
20pub mod generics; 20pub mod generics;
21pub mod traits; 21pub mod traits;
22pub mod resolver;
22 23
23#[cfg(test)] 24#[cfg(test)]
24mod test_db; 25mod test_db;
diff --git a/crates/ra_hir_def/src/marks.rs b/crates/ra_hir_def/src/marks.rs
index 0b99eac71..65239ca0a 100644
--- a/crates/ra_hir_def/src/marks.rs
+++ b/crates/ra_hir_def/src/marks.rs
@@ -11,4 +11,5 @@ test_utils::marks!(
11 prelude_is_macro_use 11 prelude_is_macro_use
12 macro_dollar_crate_self 12 macro_dollar_crate_self
13 macro_dollar_crate_other 13 macro_dollar_crate_other
14 infer_resolve_while_let
14); 15);
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir_def/src/resolver.rs
index eca8e0596..840785baa 100644
--- a/crates/ra_hir/src/resolve.rs
+++ b/crates/ra_hir_def/src/resolver.rs
@@ -1,26 +1,28 @@
1//! Name resolution. 1//! Name resolution façade.
2use std::sync::Arc; 2use std::sync::Arc;
3 3
4use hir_def::{ 4use hir_expand::{
5 builtin_type::BuiltinType, 5 name::{self, Name},
6 nameres::CrateDefMap, 6 MacroDefId,
7 path::{Path, PathKind},
8 AdtId, CrateModuleId, ModuleDefId,
9}; 7};
10use hir_expand::name::{self, Name}; 8use ra_db::CrateId;
11use rustc_hash::FxHashSet; 9use rustc_hash::FxHashSet;
12 10
13use crate::{ 11use crate::{
14 code_model::Crate, 12 body::scope::{ExprScopes, ScopeId},
15 db::{DefDatabase, HirDatabase}, 13 builtin_type::BuiltinType,
16 expr::{ExprScopes, PatId, ScopeId}, 14 db::DefDatabase2,
17 generics::{GenericParams, HasGenericParams}, 15 expr::{ExprId, PatId},
18 Adt, Const, Container, DefWithBody, Enum, EnumVariant, Function, GenericDef, ImplBlock, Local, 16 generics::GenericParams,
19 MacroDef, Module, ModuleDef, PerNs, Static, Struct, Trait, TypeAlias, 17 nameres::{per_ns::PerNs, CrateDefMap},
18 path::{Path, PathKind},
19 AdtId, AstItemDef, ConstId, ContainerId, CrateModuleId, DefWithBodyId, EnumId, EnumVariantId,
20 FunctionId, GenericDefId, ImplId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId,
21 TypeAliasId, UnionId,
20}; 22};
21 23
22#[derive(Debug, Clone, Default)] 24#[derive(Debug, Clone, Default)]
23pub(crate) struct Resolver { 25pub struct Resolver {
24 scopes: Vec<Scope>, 26 scopes: Vec<Scope>,
25} 27}
26 28
@@ -33,7 +35,7 @@ pub(crate) struct ModuleItemMap {
33 35
34#[derive(Debug, Clone)] 36#[derive(Debug, Clone)]
35pub(crate) struct ExprScope { 37pub(crate) struct ExprScope {
36 owner: DefWithBody, 38 owner: DefWithBodyId,
37 expr_scopes: Arc<ExprScopes>, 39 expr_scopes: Arc<ExprScopes>,
38 scope_id: ScopeId, 40 scope_id: ScopeId,
39} 41}
@@ -43,80 +45,76 @@ pub(crate) enum Scope {
43 /// All the items and imported names of a module 45 /// All the items and imported names of a module
44 ModuleScope(ModuleItemMap), 46 ModuleScope(ModuleItemMap),
45 /// Brings the generic parameters of an item into scope 47 /// Brings the generic parameters of an item into scope
46 GenericParams { def: GenericDef, params: Arc<GenericParams> }, 48 GenericParams { def: GenericDefId, params: Arc<GenericParams> },
47 /// Brings `Self` in `impl` block into scope 49 /// Brings `Self` in `impl` block into scope
48 ImplBlockScope(ImplBlock), 50 ImplBlockScope(ImplId),
49 /// Brings `Self` in enum, struct and union definitions into scope 51 /// Brings `Self` in enum, struct and union definitions into scope
50 AdtScope(Adt), 52 AdtScope(AdtId),
51 /// Local bindings 53 /// Local bindings
52 ExprScope(ExprScope), 54 ExprScope(ExprScope),
53} 55}
54 56
55#[derive(Debug, Clone, PartialEq, Eq, Hash)] 57#[derive(Debug, Clone, PartialEq, Eq, Hash)]
56pub(crate) enum TypeNs { 58pub enum TypeNs {
57 SelfType(ImplBlock), 59 SelfType(ImplId),
58 GenericParam(u32), 60 GenericParam(u32),
59 Adt(Adt), 61 AdtId(AdtId),
60 AdtSelfType(Adt), 62 AdtSelfType(AdtId),
61 EnumVariant(EnumVariant), 63 EnumVariantId(EnumVariantId),
62 TypeAlias(TypeAlias), 64 TypeAliasId(TypeAliasId),
63 BuiltinType(BuiltinType), 65 BuiltinType(BuiltinType),
64 Trait(Trait), 66 TraitId(TraitId),
65 // Module belong to type ns, but the resolver is used when all module paths 67 // Module belong to type ns, but the resolver is used when all module paths
66 // are fully resolved. 68 // are fully resolved.
67 // Module(Module) 69 // ModuleId(ModuleId)
68} 70}
69 71
70#[derive(Debug, Clone, PartialEq, Eq, Hash)] 72#[derive(Debug, Clone, PartialEq, Eq, Hash)]
71pub(crate) enum ResolveValueResult { 73pub enum ResolveValueResult {
72 ValueNs(ValueNs), 74 ValueNs(ValueNs),
73 Partial(TypeNs, usize), 75 Partial(TypeNs, usize),
74} 76}
75 77
76#[derive(Debug, Clone, PartialEq, Eq, Hash)] 78#[derive(Debug, Clone, PartialEq, Eq, Hash)]
77pub(crate) enum ValueNs { 79pub enum ValueNs {
78 LocalBinding(PatId), 80 LocalBinding(PatId),
79 Function(Function), 81 FunctionId(FunctionId),
80 Const(Const), 82 ConstId(ConstId),
81 Static(Static), 83 StaticId(StaticId),
82 Struct(Struct), 84 StructId(StructId),
83 EnumVariant(EnumVariant), 85 EnumVariantId(EnumVariantId),
84} 86}
85 87
86impl Resolver { 88impl Resolver {
87 /// Resolve known trait from std, like `std::futures::Future` 89 /// Resolve known trait from std, like `std::futures::Future`
88 pub(crate) fn resolve_known_trait(&self, db: &impl HirDatabase, path: &Path) -> Option<Trait> { 90 pub fn resolve_known_trait(&self, db: &impl DefDatabase2, path: &Path) -> Option<TraitId> {
89 let res = self.resolve_module_path(db, path).take_types()?; 91 let res = self.resolve_module_path(db, path).take_types()?;
90 match res { 92 match res {
91 ModuleDefId::TraitId(it) => Some(it.into()), 93 ModuleDefId::TraitId(it) => Some(it),
92 _ => None, 94 _ => None,
93 } 95 }
94 } 96 }
95 97
96 /// Resolve known struct from std, like `std::boxed::Box` 98 /// Resolve known struct from std, like `std::boxed::Box`
97 pub(crate) fn resolve_known_struct( 99 pub fn resolve_known_struct(&self, db: &impl DefDatabase2, path: &Path) -> Option<StructId> {
98 &self,
99 db: &impl HirDatabase,
100 path: &Path,
101 ) -> Option<Struct> {
102 let res = self.resolve_module_path(db, path).take_types()?; 100 let res = self.resolve_module_path(db, path).take_types()?;
103 match res { 101 match res {
104 ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it.into()), 102 ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it),
105 _ => None, 103 _ => None,
106 } 104 }
107 } 105 }
108 106
109 /// Resolve known enum from std, like `std::result::Result` 107 /// Resolve known enum from std, like `std::result::Result`
110 pub(crate) fn resolve_known_enum(&self, db: &impl HirDatabase, path: &Path) -> Option<Enum> { 108 pub fn resolve_known_enum(&self, db: &impl DefDatabase2, path: &Path) -> Option<EnumId> {
111 let res = self.resolve_module_path(db, path).take_types()?; 109 let res = self.resolve_module_path(db, path).take_types()?;
112 match res { 110 match res {
113 ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it.into()), 111 ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it),
114 _ => None, 112 _ => None,
115 } 113 }
116 } 114 }
117 115
118 /// pub only for source-binder 116 /// pub only for source-binder
119 pub(crate) fn resolve_module_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs { 117 pub fn resolve_module_path(&self, db: &impl DefDatabase2, path: &Path) -> PerNs {
120 let (item_map, module) = match self.module() { 118 let (item_map, module) = match self.module() {
121 Some(it) => it, 119 Some(it) => it,
122 None => return PerNs::none(), 120 None => return PerNs::none(),
@@ -128,9 +126,9 @@ impl Resolver {
128 module_res 126 module_res
129 } 127 }
130 128
131 pub(crate) fn resolve_path_in_type_ns( 129 pub fn resolve_path_in_type_ns(
132 &self, 130 &self,
133 db: &impl HirDatabase, 131 db: &impl DefDatabase2,
134 path: &Path, 132 path: &Path,
135 ) -> Option<(TypeNs, Option<usize>)> { 133 ) -> Option<(TypeNs, Option<usize>)> {
136 if path.is_type_relative() { 134 if path.is_type_relative() {
@@ -164,13 +162,13 @@ impl Resolver {
164 Scope::ModuleScope(m) => { 162 Scope::ModuleScope(m) => {
165 let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); 163 let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path);
166 let res = match module_def.take_types()? { 164 let res = match module_def.take_types()? {
167 ModuleDefId::AdtId(it) => TypeNs::Adt(it.into()), 165 ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
168 ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariant(it.into()), 166 ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it),
169 167
170 ModuleDefId::TypeAliasId(it) => TypeNs::TypeAlias(it.into()), 168 ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it),
171 ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), 169 ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it),
172 170
173 ModuleDefId::TraitId(it) => TypeNs::Trait(it.into()), 171 ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
174 172
175 ModuleDefId::FunctionId(_) 173 ModuleDefId::FunctionId(_)
176 | ModuleDefId::ConstId(_) 174 | ModuleDefId::ConstId(_)
@@ -184,9 +182,9 @@ impl Resolver {
184 None 182 None
185 } 183 }
186 184
187 pub(crate) fn resolve_path_in_type_ns_fully( 185 pub fn resolve_path_in_type_ns_fully(
188 &self, 186 &self,
189 db: &impl HirDatabase, 187 db: &impl DefDatabase2,
190 path: &Path, 188 path: &Path,
191 ) -> Option<TypeNs> { 189 ) -> Option<TypeNs> {
192 let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?; 190 let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?;
@@ -196,9 +194,9 @@ impl Resolver {
196 Some(res) 194 Some(res)
197 } 195 }
198 196
199 pub(crate) fn resolve_path_in_value_ns<'p>( 197 pub fn resolve_path_in_value_ns<'p>(
200 &self, 198 &self,
201 db: &impl HirDatabase, 199 db: &impl DefDatabase2,
202 path: &'p Path, 200 path: &'p Path,
203 ) -> Option<ResolveValueResult> { 201 ) -> Option<ResolveValueResult> {
204 if path.is_type_relative() { 202 if path.is_type_relative() {
@@ -259,13 +257,11 @@ impl Resolver {
259 return match idx { 257 return match idx {
260 None => { 258 None => {
261 let value = match module_def.take_values()? { 259 let value = match module_def.take_values()? {
262 ModuleDefId::FunctionId(it) => ValueNs::Function(it.into()), 260 ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it),
263 ModuleDefId::AdtId(AdtId::StructId(it)) => { 261 ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it),
264 ValueNs::Struct(it.into()) 262 ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it),
265 } 263 ModuleDefId::ConstId(it) => ValueNs::ConstId(it),
266 ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariant(it.into()), 264 ModuleDefId::StaticId(it) => ValueNs::StaticId(it),
267 ModuleDefId::ConstId(it) => ValueNs::Const(it.into()),
268 ModuleDefId::StaticId(it) => ValueNs::Static(it.into()),
269 265
270 ModuleDefId::AdtId(AdtId::EnumId(_)) 266 ModuleDefId::AdtId(AdtId::EnumId(_))
271 | ModuleDefId::AdtId(AdtId::UnionId(_)) 267 | ModuleDefId::AdtId(AdtId::UnionId(_))
@@ -278,9 +274,9 @@ impl Resolver {
278 } 274 }
279 Some(idx) => { 275 Some(idx) => {
280 let ty = match module_def.take_types()? { 276 let ty = match module_def.take_types()? {
281 ModuleDefId::AdtId(it) => TypeNs::Adt(it.into()), 277 ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
282 ModuleDefId::TraitId(it) => TypeNs::Trait(it.into()), 278 ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
283 ModuleDefId::TypeAliasId(it) => TypeNs::TypeAlias(it.into()), 279 ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it),
284 ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), 280 ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it),
285 281
286 ModuleDefId::ModuleId(_) 282 ModuleDefId::ModuleId(_)
@@ -298,9 +294,9 @@ impl Resolver {
298 None 294 None
299 } 295 }
300 296
301 pub(crate) fn resolve_path_in_value_ns_fully( 297 pub fn resolve_path_in_value_ns_fully(
302 &self, 298 &self,
303 db: &impl HirDatabase, 299 db: &impl DefDatabase2,
304 path: &Path, 300 path: &Path,
305 ) -> Option<ValueNs> { 301 ) -> Option<ValueNs> {
306 match self.resolve_path_in_value_ns(db, path)? { 302 match self.resolve_path_in_value_ns(db, path)? {
@@ -309,35 +305,26 @@ impl Resolver {
309 } 305 }
310 } 306 }
311 307
312 pub(crate) fn resolve_path_as_macro( 308 pub fn resolve_path_as_macro(&self, db: &impl DefDatabase2, path: &Path) -> Option<MacroDefId> {
313 &self,
314 db: &impl DefDatabase,
315 path: &Path,
316 ) -> Option<MacroDef> {
317 let (item_map, module) = self.module()?; 309 let (item_map, module) = self.module()?;
318 item_map.resolve_path(db, module, path).0.get_macros().map(MacroDef::from) 310 item_map.resolve_path(db, module, path).0.get_macros()
319 } 311 }
320 312
321 pub(crate) fn process_all_names( 313 pub fn process_all_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef)) {
322 &self,
323 db: &impl HirDatabase,
324 f: &mut dyn FnMut(Name, ScopeDef),
325 ) {
326 for scope in self.scopes.iter().rev() { 314 for scope in self.scopes.iter().rev() {
327 scope.process_names(db, f); 315 scope.process_names(db, f);
328 } 316 }
329 } 317 }
330 318
331 pub(crate) fn traits_in_scope(&self, db: &impl HirDatabase) -> FxHashSet<Trait> { 319 pub fn traits_in_scope(&self, db: &impl DefDatabase2) -> FxHashSet<TraitId> {
332 let mut traits = FxHashSet::default(); 320 let mut traits = FxHashSet::default();
333 for scope in &self.scopes { 321 for scope in &self.scopes {
334 if let Scope::ModuleScope(m) = scope { 322 if let Scope::ModuleScope(m) = scope {
335 if let Some(prelude) = m.crate_def_map.prelude() { 323 if let Some(prelude) = m.crate_def_map.prelude() {
336 let prelude_def_map = db.crate_def_map(prelude.krate); 324 let prelude_def_map = db.crate_def_map(prelude.krate);
337 traits 325 traits.extend(prelude_def_map[prelude.module_id].scope.traits());
338 .extend(prelude_def_map[prelude.module_id].scope.traits().map(Trait::from));
339 } 326 }
340 traits.extend(m.crate_def_map[m.module_id].scope.traits().map(Trait::from)); 327 traits.extend(m.crate_def_map[m.module_id].scope.traits());
341 } 328 }
342 } 329 }
343 traits 330 traits
@@ -351,11 +338,11 @@ impl Resolver {
351 }) 338 })
352 } 339 }
353 340
354 pub(crate) fn krate(&self) -> Option<Crate> { 341 pub fn krate(&self) -> Option<CrateId> {
355 self.module().map(|t| Crate { crate_id: t.0.krate() }) 342 self.module().map(|t| t.0.krate())
356 } 343 }
357 344
358 pub(crate) fn where_predicates_in_scope<'a>( 345 pub fn where_predicates_in_scope<'a>(
359 &'a self, 346 &'a self,
360 ) -> impl Iterator<Item = &'a crate::generics::WherePredicate> + 'a { 347 ) -> impl Iterator<Item = &'a crate::generics::WherePredicate> + 'a {
361 self.scopes 348 self.scopes
@@ -367,12 +354,19 @@ impl Resolver {
367 .flat_map(|params| params.where_predicates.iter()) 354 .flat_map(|params| params.where_predicates.iter())
368 } 355 }
369 356
370 pub(crate) fn generic_def(&self) -> Option<crate::generics::GenericDef> { 357 pub fn generic_def(&self) -> Option<GenericDefId> {
371 self.scopes.iter().find_map(|scope| match scope { 358 self.scopes.iter().find_map(|scope| match scope {
372 Scope::GenericParams { def, .. } => Some(*def), 359 Scope::GenericParams { def, .. } => Some(*def),
373 _ => None, 360 _ => None,
374 }) 361 })
375 } 362 }
363
364 pub fn body_owner(&self) -> Option<DefWithBodyId> {
365 self.scopes.iter().find_map(|scope| match scope {
366 Scope::ExprScope(it) => Some(it.owner),
367 _ => None,
368 })
369 }
376} 370}
377 371
378impl Resolver { 372impl Resolver {
@@ -383,10 +377,10 @@ impl Resolver {
383 377
384 pub(crate) fn push_generic_params_scope( 378 pub(crate) fn push_generic_params_scope(
385 self, 379 self,
386 db: &impl DefDatabase, 380 db: &impl DefDatabase2,
387 def: GenericDef, 381 def: GenericDefId,
388 ) -> Resolver { 382 ) -> Resolver {
389 let params = def.generic_params(db); 383 let params = db.generic_params(def);
390 if params.params.is_empty() { 384 if params.params.is_empty() {
391 self 385 self
392 } else { 386 } else {
@@ -394,7 +388,7 @@ impl Resolver {
394 } 388 }
395 } 389 }
396 390
397 pub(crate) fn push_impl_block_scope(self, impl_block: ImplBlock) -> Resolver { 391 pub(crate) fn push_impl_block_scope(self, impl_block: ImplId) -> Resolver {
398 self.push_scope(Scope::ImplBlockScope(impl_block)) 392 self.push_scope(Scope::ImplBlockScope(impl_block))
399 } 393 }
400 394
@@ -408,7 +402,7 @@ impl Resolver {
408 402
409 pub(crate) fn push_expr_scope( 403 pub(crate) fn push_expr_scope(
410 self, 404 self,
411 owner: DefWithBody, 405 owner: DefWithBodyId,
412 expr_scopes: Arc<ExprScopes>, 406 expr_scopes: Arc<ExprScopes>,
413 scope_id: ScopeId, 407 scope_id: ScopeId,
414 ) -> Resolver { 408 ) -> Resolver {
@@ -416,31 +410,16 @@ impl Resolver {
416 } 410 }
417} 411}
418 412
419/// For IDE only
420pub enum ScopeDef { 413pub enum ScopeDef {
421 ModuleDef(ModuleDef), 414 PerNs(PerNs),
422 MacroDef(MacroDef), 415 ImplSelfType(ImplId),
416 AdtSelfType(AdtId),
423 GenericParam(u32), 417 GenericParam(u32),
424 ImplSelfType(ImplBlock), 418 Local(PatId),
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} 419}
441 420
442impl Scope { 421impl Scope {
443 fn process_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { 422 fn process_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef)) {
444 match self { 423 match self {
445 Scope::ModuleScope(m) => { 424 Scope::ModuleScope(m) => {
446 // FIXME: should we provide `self` here? 425 // FIXME: should we provide `self` here?
@@ -451,18 +430,18 @@ impl Scope {
451 // }), 430 // }),
452 // ); 431 // );
453 m.crate_def_map[m.module_id].scope.entries().for_each(|(name, res)| { 432 m.crate_def_map[m.module_id].scope.entries().for_each(|(name, res)| {
454 f(name.clone(), res.def.into()); 433 f(name.clone(), ScopeDef::PerNs(res.def));
455 }); 434 });
456 m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| { 435 m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| {
457 f(name.clone(), ScopeDef::MacroDef(macro_.into())); 436 f(name.clone(), ScopeDef::PerNs(PerNs::macros(macro_)));
458 }); 437 });
459 m.crate_def_map.extern_prelude().iter().for_each(|(name, &def)| { 438 m.crate_def_map.extern_prelude().iter().for_each(|(name, &def)| {
460 f(name.clone(), ScopeDef::ModuleDef(def.into())); 439 f(name.clone(), ScopeDef::PerNs(PerNs::types(def.into())));
461 }); 440 });
462 if let Some(prelude) = m.crate_def_map.prelude() { 441 if let Some(prelude) = m.crate_def_map.prelude() {
463 let prelude_def_map = db.crate_def_map(prelude.krate); 442 let prelude_def_map = db.crate_def_map(prelude.krate);
464 prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| { 443 prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| {
465 f(name.clone(), res.def.into()); 444 f(name.clone(), ScopeDef::PerNs(res.def));
466 }); 445 });
467 } 446 }
468 } 447 }
@@ -472,114 +451,155 @@ impl Scope {
472 } 451 }
473 } 452 }
474 Scope::ImplBlockScope(i) => { 453 Scope::ImplBlockScope(i) => {
475 f(name::SELF_TYPE, ScopeDef::ImplSelfType(*i)); 454 f(name::SELF_TYPE, ScopeDef::ImplSelfType((*i).into()));
476 } 455 }
477 Scope::AdtScope(i) => { 456 Scope::AdtScope(i) => {
478 f(name::SELF_TYPE, ScopeDef::AdtSelfType(*i)); 457 f(name::SELF_TYPE, ScopeDef::AdtSelfType((*i).into()));
479 } 458 }
480 Scope::ExprScope(scope) => { 459 Scope::ExprScope(scope) => {
481 scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| { 460 scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| {
482 let local = Local { parent: scope.owner, pat_id: e.pat() }; 461 f(e.name().clone(), ScopeDef::Local(e.pat()));
483 f(e.name().clone(), ScopeDef::Local(local));
484 }); 462 });
485 } 463 }
486 } 464 }
487 } 465 }
488} 466}
489 467
490pub(crate) trait HasResolver { 468// needs arbitrary_self_types to be a method... or maybe move to the def?
469pub fn resolver_for_expr(
470 db: &impl DefDatabase2,
471 owner: DefWithBodyId,
472 expr_id: ExprId,
473) -> Resolver {
474 let scopes = db.expr_scopes(owner);
475 resolver_for_scope(db, owner, scopes.scope_for(expr_id))
476}
477
478pub fn resolver_for_scope(
479 db: &impl DefDatabase2,
480 owner: DefWithBodyId,
481 scope_id: Option<ScopeId>,
482) -> Resolver {
483 let mut r = owner.resolver(db);
484 let scopes = db.expr_scopes(owner);
485 let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>();
486 for scope in scope_chain.into_iter().rev() {
487 r = r.push_expr_scope(owner, Arc::clone(&scopes), scope);
488 }
489 r
490}
491
492pub trait HasResolver {
491 /// Builds a resolver for type references inside this def. 493 /// Builds a resolver for type references inside this def.
492 fn resolver(self, db: &impl DefDatabase) -> Resolver; 494 fn resolver(self, db: &impl DefDatabase2) -> Resolver;
493} 495}
494 496
495impl HasResolver for Module { 497impl HasResolver for ModuleId {
496 fn resolver(self, db: &impl DefDatabase) -> Resolver { 498 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
497 let def_map = db.crate_def_map(self.id.krate); 499 let def_map = db.crate_def_map(self.krate);
498 Resolver::default().push_module_scope(def_map, self.id.module_id) 500 Resolver::default().push_module_scope(def_map, self.module_id)
499 } 501 }
500} 502}
501 503
502impl HasResolver for Trait { 504impl HasResolver for TraitId {
503 fn resolver(self, db: &impl DefDatabase) -> Resolver { 505 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
504 self.module(db).resolver(db).push_generic_params_scope(db, self.into()) 506 self.module(db).resolver(db).push_generic_params_scope(db, self.into())
505 } 507 }
506} 508}
507 509
508impl<T: Into<Adt>> HasResolver for T { 510impl HasResolver for AdtId {
509 fn resolver(self, db: &impl DefDatabase) -> Resolver { 511 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
510 let def = self.into(); 512 let module = match self {
511 def.module(db) 513 AdtId::StructId(it) => it.0.module(db),
514 AdtId::UnionId(it) => it.0.module(db),
515 AdtId::EnumId(it) => it.module(db),
516 };
517
518 module
512 .resolver(db) 519 .resolver(db)
513 .push_generic_params_scope(db, def.into()) 520 .push_generic_params_scope(db, self.into())
514 .push_scope(Scope::AdtScope(def)) 521 .push_scope(Scope::AdtScope(self.into()))
515 } 522 }
516} 523}
517 524
518impl HasResolver for Function { 525impl HasResolver for StructId {
519 fn resolver(self, db: &impl DefDatabase) -> Resolver { 526 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
520 self.container(db) 527 AdtId::from(self).resolver(db)
521 .map(|c| c.resolver(db)) 528 }
522 .unwrap_or_else(|| self.module(db).resolver(db)) 529}
523 .push_generic_params_scope(db, self.into()) 530
531impl HasResolver for UnionId {
532 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
533 AdtId::from(self).resolver(db)
534 }
535}
536
537impl HasResolver for EnumId {
538 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
539 AdtId::from(self).resolver(db)
524 } 540 }
525} 541}
526 542
527impl HasResolver for DefWithBody { 543impl HasResolver for FunctionId {
528 fn resolver(self, db: &impl DefDatabase) -> Resolver { 544 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
545 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
546 }
547}
548
549impl HasResolver for DefWithBodyId {
550 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
529 match self { 551 match self {
530 DefWithBody::Const(c) => c.resolver(db), 552 DefWithBodyId::ConstId(c) => c.resolver(db),
531 DefWithBody::Function(f) => f.resolver(db), 553 DefWithBodyId::FunctionId(f) => f.resolver(db),
532 DefWithBody::Static(s) => s.resolver(db), 554 DefWithBodyId::StaticId(s) => s.resolver(db),
533 } 555 }
534 } 556 }
535} 557}
536 558
537impl HasResolver for Const { 559impl HasResolver for ConstId {
538 fn resolver(self, db: &impl DefDatabase) -> Resolver { 560 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
539 self.container(db).map(|c| c.resolver(db)).unwrap_or_else(|| self.module(db).resolver(db)) 561 self.lookup(db).container.resolver(db)
540 } 562 }
541} 563}
542 564
543impl HasResolver for Static { 565impl HasResolver for StaticId {
544 fn resolver(self, db: &impl DefDatabase) -> Resolver { 566 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
545 self.module(db).resolver(db) 567 self.module(db).resolver(db)
546 } 568 }
547} 569}
548 570
549impl HasResolver for TypeAlias { 571impl HasResolver for TypeAliasId {
550 fn resolver(self, db: &impl DefDatabase) -> Resolver { 572 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
551 self.container(db) 573 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
552 .map(|ib| ib.resolver(db))
553 .unwrap_or_else(|| self.module(db).resolver(db))
554 .push_generic_params_scope(db, self.into())
555 } 574 }
556} 575}
557 576
558impl HasResolver for Container { 577impl HasResolver for ContainerId {
559 fn resolver(self, db: &impl DefDatabase) -> Resolver { 578 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
560 match self { 579 match self {
561 Container::Trait(trait_) => trait_.resolver(db), 580 ContainerId::TraitId(it) => it.resolver(db),
562 Container::ImplBlock(impl_block) => impl_block.resolver(db), 581 ContainerId::ImplId(it) => it.resolver(db),
582 ContainerId::ModuleId(it) => it.resolver(db),
563 } 583 }
564 } 584 }
565} 585}
566 586
567impl HasResolver for GenericDef { 587impl HasResolver for GenericDefId {
568 fn resolver(self, db: &impl DefDatabase) -> crate::Resolver { 588 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
569 match self { 589 match self {
570 GenericDef::Function(inner) => inner.resolver(db), 590 GenericDefId::FunctionId(inner) => inner.resolver(db),
571 GenericDef::Adt(adt) => adt.resolver(db), 591 GenericDefId::AdtId(adt) => adt.resolver(db),
572 GenericDef::Trait(inner) => inner.resolver(db), 592 GenericDefId::TraitId(inner) => inner.resolver(db),
573 GenericDef::TypeAlias(inner) => inner.resolver(db), 593 GenericDefId::TypeAliasId(inner) => inner.resolver(db),
574 GenericDef::ImplBlock(inner) => inner.resolver(db), 594 GenericDefId::ImplId(inner) => inner.resolver(db),
575 GenericDef::EnumVariant(inner) => inner.parent_enum(db).resolver(db), 595 GenericDefId::EnumVariantId(inner) => inner.parent.resolver(db),
576 GenericDef::Const(inner) => inner.resolver(db), 596 GenericDefId::ConstId(inner) => inner.resolver(db),
577 } 597 }
578 } 598 }
579} 599}
580 600
581impl HasResolver for ImplBlock { 601impl HasResolver for ImplId {
582 fn resolver(self, db: &impl DefDatabase) -> Resolver { 602 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
583 self.module(db) 603 self.module(db)
584 .resolver(db) 604 .resolver(db)
585 .push_generic_params_scope(db, self.into()) 605 .push_generic_params_scope(db, self.into())
diff --git a/crates/ra_hir_def/src/traits.rs b/crates/ra_hir_def/src/traits.rs
index 877d73d66..6c2d5b2a9 100644
--- a/crates/ra_hir_def/src/traits.rs
+++ b/crates/ra_hir_def/src/traits.rs
@@ -11,7 +11,7 @@ use ra_syntax::ast::{self, NameOwner};
11 11
12use crate::{ 12use crate::{
13 db::DefDatabase2, AssocItemId, AstItemDef, ConstLoc, ContainerId, FunctionLoc, Intern, TraitId, 13 db::DefDatabase2, AssocItemId, AstItemDef, ConstLoc, ContainerId, FunctionLoc, Intern, TraitId,
14 TypeAliasLoc, 14 TypeAliasId, TypeAliasLoc,
15}; 15};
16 16
17#[derive(Debug, Clone, PartialEq, Eq)] 17#[derive(Debug, Clone, PartialEq, Eq)]
@@ -56,4 +56,11 @@ impl TraitData {
56 }; 56 };
57 Arc::new(TraitData { name, items, auto }) 57 Arc::new(TraitData { name, items, auto })
58 } 58 }
59
60 pub fn associated_types(&self) -> impl Iterator<Item = TypeAliasId> + '_ {
61 self.items.iter().filter_map(|item| match item {
62 AssocItemId::TypeAliasId(t) => Some(*t),
63 _ => None,
64 })
65 }
59} 66}