aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/code_model.rs94
-rw-r--r--crates/ra_hir/src/db.rs5
-rw-r--r--crates/ra_hir/src/expr.rs33
-rw-r--r--crates/ra_hir/src/from_id.rs101
-rw-r--r--crates/ra_hir/src/generics.rs54
-rw-r--r--crates/ra_hir/src/impl_block.rs9
-rw-r--r--crates/ra_hir/src/lib.rs12
-rw-r--r--crates/ra_hir/src/source_binder.rs115
-rw-r--r--crates/ra_hir/src/ty.rs22
-rw-r--r--crates/ra_hir/src/ty/autoderef.rs9
-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.rs16
-rw-r--r--crates/ra_hir/src/ty/infer/path.rs39
-rw-r--r--crates/ra_hir/src/ty/lower.rs83
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs21
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs13
-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)399
-rw-r--r--crates/ra_hir_def/src/traits.rs9
-rw-r--r--crates/ra_hir_expand/src/db.rs1
-rw-r--r--crates/ra_hir_expand/src/lib.rs1
-rw-r--r--crates/ra_ide_api/src/expand_macro.rs64
-rw-r--r--crates/ra_mbe/src/syntax_bridge.rs68
27 files changed, 752 insertions, 480 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index a132d128b..5690040a7 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,
@@ -25,14 +27,12 @@ use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
25use crate::{ 27use crate::{
26 db::{AstDatabase, DefDatabase, HirDatabase}, 28 db::{AstDatabase, DefDatabase, HirDatabase},
27 expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, 29 expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId},
28 generics::{GenericDef, HasGenericParams},
29 ids::{ 30 ids::{
30 AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, 31 AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId,
31 TypeAliasId, 32 TypeAliasId,
32 }, 33 },
33 resolve::{HasResolver, TypeNs},
34 ty::{InferenceResult, Namespace, TraitRef}, 34 ty::{InferenceResult, Namespace, TraitRef},
35 Either, HasSource, ImportId, Name, ScopeDef, Source, Ty, 35 Either, HasSource, ImportId, Name, Source, Ty,
36}; 36};
37 37
38/// hir::Crate describes a single crate. It's the main interface with which 38/// hir::Crate describes a single crate. It's the main interface with which
@@ -829,12 +829,12 @@ impl Trait {
829 } 829 }
830 830
831 fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { 831 fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> {
832 let resolver = self.resolver(db); 832 let resolver = self.id.resolver(db);
833 // returning the iterator directly doesn't easily work because of 833 // returning the iterator directly doesn't easily work because of
834 // lifetime problems, but since there usually shouldn't be more than a 834 // 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 835 // few direct traits this should be fine (we could even use some kind of
836 // SmallVec if performance is a concern) 836 // SmallVec if performance is a concern)
837 self.generic_params(db) 837 db.generic_params(self.id.into())
838 .where_predicates 838 .where_predicates
839 .iter() 839 .iter()
840 .filter_map(|pred| match &pred.type_ref { 840 .filter_map(|pred| match &pred.type_ref {
@@ -842,9 +842,10 @@ impl Trait {
842 _ => None, 842 _ => None,
843 }) 843 })
844 .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) { 844 .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) {
845 Some(TypeNs::Trait(t)) => Some(t), 845 Some(TypeNs::TraitId(t)) => Some(t),
846 _ => None, 846 _ => None,
847 }) 847 })
848 .map(Trait::from)
848 .collect() 849 .collect()
849 } 850 }
850 851
@@ -871,14 +872,9 @@ impl Trait {
871 872
872 pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { 873 pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> {
873 let trait_data = self.trait_data(db); 874 let trait_data = self.trait_data(db);
874 trait_data 875 let res =
875 .items 876 trait_data.associated_types().map(TypeAlias::from).find(|t| &t.name(db) == name)?;
876 .iter() 877 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 } 878 }
883 879
884 pub fn associated_type_by_name_including_super_traits( 880 pub fn associated_type_by_name_including_super_traits(
@@ -978,16 +974,6 @@ pub enum AssocItem {
978// casting them, and somehow making the constructors private, which would be annoying. 974// casting them, and somehow making the constructors private, which would be annoying.
979impl_froms!(AssocItem: Function, Const, TypeAlias); 975impl_froms!(AssocItem: Function, Const, TypeAlias);
980 976
981impl From<AssocItem> for crate::generics::GenericDef {
982 fn from(item: AssocItem) -> Self {
983 match item {
984 AssocItem::Function(f) => f.into(),
985 AssocItem::Const(c) => c.into(),
986 AssocItem::TypeAlias(t) => t.into(),
987 }
988 }
989}
990
991impl AssocItem { 977impl AssocItem {
992 pub fn module(self, db: &impl DefDatabase) -> Module { 978 pub fn module(self, db: &impl DefDatabase) -> Module {
993 match self { 979 match self {
@@ -1007,6 +993,39 @@ impl AssocItem {
1007 } 993 }
1008} 994}
1009 995
996#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
997pub enum GenericDef {
998 Function(Function),
999 Adt(Adt),
1000 Trait(Trait),
1001 TypeAlias(TypeAlias),
1002 ImplBlock(ImplBlock),
1003 // enum variants cannot have generics themselves, but their parent enums
1004 // can, and this makes some code easier to write
1005 EnumVariant(EnumVariant),
1006 // consts can have type parameters from their parents (i.e. associated consts of traits)
1007 Const(Const),
1008}
1009impl_froms!(
1010 GenericDef: Function,
1011 Adt(Struct, Enum, Union),
1012 Trait,
1013 TypeAlias,
1014 ImplBlock,
1015 EnumVariant,
1016 Const
1017);
1018
1019impl From<AssocItem> for GenericDef {
1020 fn from(item: AssocItem) -> Self {
1021 match item {
1022 AssocItem::Function(f) => f.into(),
1023 AssocItem::Const(c) => c.into(),
1024 AssocItem::TypeAlias(t) => t.into(),
1025 }
1026 }
1027}
1028
1010#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 1029#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1011pub struct Local { 1030pub struct Local {
1012 pub(crate) parent: DefWithBody, 1031 pub(crate) parent: DefWithBody,
@@ -1068,3 +1087,26 @@ pub struct GenericParam {
1068pub struct ImplBlock { 1087pub struct ImplBlock {
1069 pub(crate) id: ImplId, 1088 pub(crate) id: ImplId,
1070} 1089}
1090
1091/// For IDE only
1092pub enum ScopeDef {
1093 ModuleDef(ModuleDef),
1094 MacroDef(MacroDef),
1095 GenericParam(GenericParam),
1096 ImplSelfType(ImplBlock),
1097 AdtSelfType(Adt),
1098 Local(Local),
1099 Unknown,
1100}
1101
1102impl From<PerNs> for ScopeDef {
1103 fn from(def: PerNs) -> Self {
1104 def.take_types()
1105 .or_else(|| def.take_values())
1106 .map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into()))
1107 .or_else(|| {
1108 def.get_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into()))
1109 })
1110 .unwrap_or(ScopeDef::Unknown)
1111 }
1112}
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index a9982a70f..ed0d68001 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -8,7 +8,6 @@ use ra_syntax::SmolStr;
8 8
9use crate::{ 9use crate::{
10 debug::HirDebugDatabase, 10 debug::HirDebugDatabase,
11 generics::GenericDef,
12 ids, 11 ids,
13 lang_item::{LangItemTarget, LangItems}, 12 lang_item::{LangItemTarget, LangItems},
14 ty::{ 13 ty::{
@@ -18,8 +17,8 @@ use crate::{
18 TypeCtor, 17 TypeCtor,
19 }, 18 },
20 type_alias::TypeAliasData, 19 type_alias::TypeAliasData,
21 Const, ConstData, Crate, DefWithBody, FnData, Function, ImplBlock, Module, Static, StructField, 20 Const, ConstData, Crate, DefWithBody, FnData, Function, GenericDef, ImplBlock, Module, Static,
22 Trait, TypeAlias, 21 StructField, Trait, TypeAlias,
23}; 22};
24 23
25pub use hir_def::db::{ 24pub use hir_def::db::{
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..e8ed04056 100644
--- a/crates/ra_hir/src/from_id.rs
+++ b/crates/ra_hir/src/from_id.rs
@@ -3,9 +3,22 @@
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::{CallableDef, TypableDef},
13 Adt, AssocItem, Const, Crate, DefWithBody, EnumVariant, Function, GenericDef, ModuleDef,
14 Static, TypeAlias,
15};
16
17impl From<ra_db::CrateId> for Crate {
18 fn from(crate_id: ra_db::CrateId) -> Self {
19 Crate { crate_id }
20 }
21}
9 22
10macro_rules! from_id { 23macro_rules! from_id {
11 ($(($id:path, $ty:path)),*) => {$( 24 ($(($id:path, $ty:path)),*) => {$(
@@ -83,6 +96,16 @@ impl From<DefWithBody> for DefWithBodyId {
83 } 96 }
84} 97}
85 98
99impl From<DefWithBodyId> for DefWithBody {
100 fn from(def: DefWithBodyId) -> Self {
101 match def {
102 DefWithBodyId::FunctionId(it) => DefWithBody::Function(it.into()),
103 DefWithBodyId::StaticId(it) => DefWithBody::Static(it.into()),
104 DefWithBodyId::ConstId(it) => DefWithBody::Const(it.into()),
105 }
106 }
107}
108
86impl From<AssocItemId> for AssocItem { 109impl From<AssocItemId> for AssocItem {
87 fn from(def: AssocItemId) -> Self { 110 fn from(def: AssocItemId) -> Self {
88 match def { 111 match def {
@@ -122,3 +145,77 @@ impl From<GenericDefId> for GenericDef {
122 } 145 }
123 } 146 }
124} 147}
148
149impl From<AdtId> for TypableDef {
150 fn from(id: AdtId) -> Self {
151 Adt::from(id).into()
152 }
153}
154
155impl From<StructId> for TypableDef {
156 fn from(id: StructId) -> Self {
157 AdtId::StructId(id).into()
158 }
159}
160
161impl From<UnionId> for TypableDef {
162 fn from(id: UnionId) -> Self {
163 AdtId::UnionId(id).into()
164 }
165}
166
167impl From<EnumId> for TypableDef {
168 fn from(id: EnumId) -> Self {
169 AdtId::EnumId(id).into()
170 }
171}
172
173impl From<EnumVariantId> for TypableDef {
174 fn from(id: EnumVariantId) -> Self {
175 EnumVariant::from(id).into()
176 }
177}
178
179impl From<TypeAliasId> for TypableDef {
180 fn from(id: TypeAliasId) -> Self {
181 TypeAlias::from(id).into()
182 }
183}
184
185impl From<FunctionId> for TypableDef {
186 fn from(id: FunctionId) -> Self {
187 Function::from(id).into()
188 }
189}
190impl From<ConstId> for TypableDef {
191 fn from(id: ConstId) -> Self {
192 Const::from(id).into()
193 }
194}
195impl From<StaticId> for TypableDef {
196 fn from(id: StaticId) -> Self {
197 Static::from(id).into()
198 }
199}
200
201impl From<Adt> for GenericDefId {
202 fn from(id: Adt) -> Self {
203 match id {
204 Adt::Struct(it) => it.id.into(),
205 Adt::Union(it) => it.id.into(),
206 Adt::Enum(it) => it.id.into(),
207 }
208 }
209}
210
211impl From<CallableDef> for GenericDefId {
212 fn from(def: CallableDef) -> Self {
213 match def {
214 CallableDef::Function(it) => it.id.into(),
215 CallableDef::Struct(it) => it.id.into(),
216 CallableDef::EnumVariant(it) => {
217 EnumVariantId { parent: it.parent.id, local_id: it.id }.into()
218 }
219 }
220 }
221}
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs
deleted file mode 100644
index f1bf2ee9d..000000000
--- a/crates/ra_hir/src/generics.rs
+++ /dev/null
@@ -1,54 +0,0 @@
1//! Temp module to wrap hir_def::generics
2use std::sync::Arc;
3
4use crate::{
5 db::DefDatabase, Adt, Const, Container, Enum, EnumVariant, Function, ImplBlock, Struct, Trait,
6 TypeAlias, Union,
7};
8
9pub use hir_def::generics::{GenericParam, GenericParams, WherePredicate};
10
11#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
12pub enum GenericDef {
13 Function(Function),
14 Adt(Adt),
15 Trait(Trait),
16 TypeAlias(TypeAlias),
17 ImplBlock(ImplBlock),
18 // enum variants cannot have generics themselves, but their parent enums
19 // can, and this makes some code easier to write
20 EnumVariant(EnumVariant),
21 // consts can have type parameters from their parents (i.e. associated consts of traits)
22 Const(Const),
23}
24impl_froms!(
25 GenericDef: Function,
26 Adt(Struct, Enum, Union),
27 Trait,
28 TypeAlias,
29 ImplBlock,
30 EnumVariant,
31 Const
32);
33
34impl From<Container> for GenericDef {
35 fn from(c: Container) -> Self {
36 match c {
37 Container::Trait(trait_) => trait_.into(),
38 Container::ImplBlock(impl_block) => impl_block.into(),
39 }
40 }
41}
42
43pub trait HasGenericParams: Copy {
44 fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams>;
45}
46
47impl<T> HasGenericParams for T
48where
49 T: Into<GenericDef> + Copy,
50{
51 fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams> {
52 db.generic_params(self.into().into())
53 }
54}
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..8c6834392 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -37,8 +37,6 @@ mod ty;
37mod impl_block; 37mod impl_block;
38mod expr; 38mod expr;
39mod lang_item; 39mod lang_item;
40pub mod generics;
41mod resolve;
42pub mod diagnostics; 40pub mod diagnostics;
43mod util; 41mod util;
44 42
@@ -52,23 +50,19 @@ mod test_db;
52#[cfg(test)] 50#[cfg(test)]
53mod marks; 51mod marks;
54 52
55use crate::resolve::Resolver;
56
57pub use crate::{ 53pub use crate::{
58 code_model::{ 54 code_model::{
59 attrs::{AttrDef, Attrs}, 55 attrs::{AttrDef, Attrs},
60 docs::{DocDef, Docs, Documentation}, 56 docs::{DocDef, Docs, Documentation},
61 src::{HasBodySource, HasSource}, 57 src::{HasBodySource, HasSource},
62 Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, 58 Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum,
63 EnumVariant, FieldSource, FnData, Function, GenericParam, HasBody, ImplBlock, Local, 59 EnumVariant, FieldSource, FnData, Function, GenericDef, GenericParam, HasBody, ImplBlock,
64 MacroDef, Module, ModuleDef, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, 60 Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField,
65 Union, VariantDef, 61 Trait, TypeAlias, Union, VariantDef,
66 }, 62 },
67 expr::ExprScopes, 63 expr::ExprScopes,
68 from_source::FromSource, 64 from_source::FromSource,
69 generics::GenericDef,
70 ids::{HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile}, 65 ids::{HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile},
71 resolve::ScopeDef,
72 source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, 66 source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer},
73 ty::{ 67 ty::{
74 display::HirDisplay, 68 display::HirDisplay,
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 727310f06..797f90d50 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
@@ -127,6 +131,7 @@ pub struct ReferenceDescriptor {
127} 131}
128 132
129pub struct Expansion { 133pub struct Expansion {
134 macro_file_kind: MacroFileKind,
130 macro_call_id: MacroCallId, 135 macro_call_id: MacroCallId,
131} 136}
132 137
@@ -141,7 +146,7 @@ impl Expansion {
141 } 146 }
142 147
143 pub fn file_id(&self) -> HirFileId { 148 pub fn file_id(&self) -> HirFileId {
144 self.macro_call_id.as_file(MacroFileKind::Items) 149 self.macro_call_id.as_file(self.macro_file_kind)
145 } 150 }
146} 151}
147 152
@@ -159,7 +164,7 @@ impl SourceAnalyzer {
159 None => scope_for(&scopes, &source_map, node), 164 None => scope_for(&scopes, &source_map, node),
160 Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)), 165 Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)),
161 }; 166 };
162 let resolver = expr::resolver_for_scope(db, def, scope); 167 let resolver = resolver_for_scope(db, def.into(), scope);
163 SourceAnalyzer { 168 SourceAnalyzer {
164 resolver, 169 resolver,
165 body_owner: Some(def), 170 body_owner: Some(def),
@@ -231,7 +236,7 @@ impl SourceAnalyzer {
231 ) -> Option<MacroDef> { 236 ) -> Option<MacroDef> {
232 // This must be a normal source file rather than macro file. 237 // This must be a normal source file rather than macro file.
233 let path = macro_call.path().and_then(Path::from_ast)?; 238 let path = macro_call.path().and_then(Path::from_ast)?;
234 self.resolver.resolve_path_as_macro(db, &path) 239 self.resolver.resolve_path_as_macro(db, &path).map(|it| it.into())
235 } 240 }
236 241
237 pub fn resolve_hir_path( 242 pub fn resolve_hir_path(
@@ -240,16 +245,18 @@ impl SourceAnalyzer {
240 path: &crate::Path, 245 path: &crate::Path,
241 ) -> Option<PathResolution> { 246 ) -> Option<PathResolution> {
242 let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { 247 let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty {
243 TypeNs::SelfType(it) => PathResolution::SelfType(it), 248 TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
244 TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam { 249 TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam {
245 parent: self.resolver.generic_def().unwrap(), 250 parent: self.resolver.generic_def().unwrap().into(),
246 idx, 251 idx,
247 }), 252 }),
248 TypeNs::AdtSelfType(it) | TypeNs::Adt(it) => PathResolution::Def(it.into()), 253 TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
249 TypeNs::EnumVariant(it) => PathResolution::Def(it.into()), 254 PathResolution::Def(Adt::from(it).into())
250 TypeNs::TypeAlias(it) => PathResolution::Def(it.into()), 255 }
256 TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()),
257 TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
251 TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), 258 TypeNs::BuiltinType(it) => PathResolution::Def(it.into()),
252 TypeNs::Trait(it) => PathResolution::Def(it.into()), 259 TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
253 }); 260 });
254 let values = self.resolver.resolve_path_in_value_ns_fully(db, &path).and_then(|val| { 261 let values = self.resolver.resolve_path_in_value_ns_fully(db, &path).and_then(|val| {
255 let res = match val { 262 let res = match val {
@@ -257,11 +264,11 @@ impl SourceAnalyzer {
257 let var = Local { parent: self.body_owner?, pat_id }; 264 let var = Local { parent: self.body_owner?, pat_id };
258 PathResolution::Local(var) 265 PathResolution::Local(var)
259 } 266 }
260 ValueNs::Function(it) => PathResolution::Def(it.into()), 267 ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()),
261 ValueNs::Const(it) => PathResolution::Def(it.into()), 268 ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()),
262 ValueNs::Static(it) => PathResolution::Def(it.into()), 269 ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()),
263 ValueNs::Struct(it) => PathResolution::Def(it.into()), 270 ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()),
264 ValueNs::EnumVariant(it) => PathResolution::Def(it.into()), 271 ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()),
265 }; 272 };
266 Some(res) 273 Some(res)
267 }); 274 });
@@ -272,7 +279,9 @@ impl SourceAnalyzer {
272 .take_types() 279 .take_types()
273 .map(|it| PathResolution::Def(it.into())); 280 .map(|it| PathResolution::Def(it.into()));
274 types.or(values).or(items).or_else(|| { 281 types.or(values).or(items).or_else(|| {
275 self.resolver.resolve_path_as_macro(db, &path).map(|def| PathResolution::Macro(def)) 282 self.resolver
283 .resolve_path_as_macro(db, &path)
284 .map(|def| PathResolution::Macro(def.into()))
276 }) 285 })
277 } 286 }
278 287
@@ -307,7 +316,22 @@ impl SourceAnalyzer {
307 } 316 }
308 317
309 pub fn process_all_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { 318 pub fn process_all_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef)) {
310 self.resolver.process_all_names(db, f) 319 self.resolver.process_all_names(db, &mut |name, def| {
320 let def = match def {
321 resolver::ScopeDef::PerNs(it) => it.into(),
322 resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()),
323 resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()),
324 resolver::ScopeDef::GenericParam(idx) => {
325 let parent = self.resolver.generic_def().unwrap().into();
326 ScopeDef::GenericParam(GenericParam { parent, idx })
327 }
328 resolver::ScopeDef::Local(pat_id) => {
329 let parent = self.resolver.body_owner().unwrap().into();
330 ScopeDef::Local(Local { parent, pat_id })
331 }
332 };
333 f(name, def)
334 })
311 } 335 }
312 336
313 // FIXME: we only use this in `inline_local_variable` assist, ideally, we 337 // FIXME: we only use this in `inline_local_variable` assist, ideally, we
@@ -392,7 +416,7 @@ impl SourceAnalyzer {
392 let std_future_path = known::std_future_future(); 416 let std_future_path = known::std_future_future();
393 417
394 let std_future_trait = match self.resolver.resolve_known_trait(db, &std_future_path) { 418 let std_future_trait = match self.resolver.resolve_known_trait(db, &std_future_path) {
395 Some(it) => it, 419 Some(it) => it.into(),
396 _ => return false, 420 _ => return false,
397 }; 421 };
398 422
@@ -402,7 +426,7 @@ impl SourceAnalyzer {
402 }; 426 };
403 427
404 let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 }; 428 let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 };
405 implements_trait(&canonical_ty, db, &self.resolver, krate, std_future_trait) 429 implements_trait(&canonical_ty, db, &self.resolver, krate.into(), std_future_trait)
406 } 430 }
407 431
408 pub fn expand( 432 pub fn expand(
@@ -416,7 +440,10 @@ impl SourceAnalyzer {
416 db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), 440 db.ast_id_map(macro_call.file_id).ast_id(macro_call.value),
417 ); 441 );
418 let macro_call_loc = MacroCallLoc { def, ast_id }; 442 let macro_call_loc = MacroCallLoc { def, ast_id };
419 Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) }) 443 Some(Expansion {
444 macro_call_id: db.intern_macro(macro_call_loc),
445 macro_file_kind: to_macro_file_kind(macro_call.value),
446 })
420 } 447 }
421 448
422 #[cfg(test)] 449 #[cfg(test)]
@@ -515,3 +542,35 @@ fn adjust(
515 }) 542 })
516 .map(|(_ptr, scope)| *scope) 543 .map(|(_ptr, scope)| *scope)
517} 544}
545
546/// Given a `ast::MacroCall`, return what `MacroKindFile` it belongs to.
547/// FIXME: Not completed
548fn to_macro_file_kind(macro_call: &ast::MacroCall) -> MacroFileKind {
549 let syn = macro_call.syntax();
550 let parent = match syn.parent() {
551 Some(it) => it,
552 None => {
553 // FIXME:
554 // If it is root, which means the parent HirFile
555 // MacroKindFile must be non-items
556 // return expr now.
557 return MacroFileKind::Expr;
558 }
559 };
560
561 match parent.kind() {
562 MACRO_ITEMS | SOURCE_FILE => MacroFileKind::Items,
563 LET_STMT => {
564 // FIXME: Handle Pattern
565 MacroFileKind::Expr
566 }
567 EXPR_STMT => MacroFileKind::Statements,
568 BLOCK => MacroFileKind::Statements,
569 ARG_LIST => MacroFileKind::Expr,
570 TRY_EXPR => MacroFileKind::Expr,
571 _ => {
572 // Unknown , Just guess it is `Items`
573 MacroFileKind::Items
574 }
575 }
576}
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 36ece723f..95b8df181 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -17,12 +17,11 @@ use std::ops::Deref;
17use std::sync::Arc; 17use std::sync::Arc;
18use std::{fmt, iter, mem}; 18use std::{fmt, iter, mem};
19 19
20use hir_def::{generics::GenericParams, AdtId};
21
20use crate::{ 22use crate::{
21 db::HirDatabase, 23 db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, DefWithBody, FloatTy,
22 expr::ExprId, 24 GenericDef, IntTy, Mutability, Name, Trait, TypeAlias, Uncertain,
23 generics::{GenericParams, HasGenericParams},
24 util::make_mut_slice,
25 Adt, Crate, DefWithBody, FloatTy, IntTy, Mutability, Name, Trait, TypeAlias, Uncertain,
26}; 25};
27use display::{HirDisplay, HirFormatter}; 26use display::{HirDisplay, HirFormatter};
28 27
@@ -131,15 +130,15 @@ impl TypeCtor {
131 | TypeCtor::Closure { .. } // 1 param representing the signature of the closure 130 | TypeCtor::Closure { .. } // 1 param representing the signature of the closure
132 => 1, 131 => 1,
133 TypeCtor::Adt(adt) => { 132 TypeCtor::Adt(adt) => {
134 let generic_params = adt.generic_params(db); 133 let generic_params = db.generic_params(AdtId::from(adt).into());
135 generic_params.count_params_including_parent() 134 generic_params.count_params_including_parent()
136 } 135 }
137 TypeCtor::FnDef(callable) => { 136 TypeCtor::FnDef(callable) => {
138 let generic_params = callable.generic_params(db); 137 let generic_params = db.generic_params(callable.into());
139 generic_params.count_params_including_parent() 138 generic_params.count_params_including_parent()
140 } 139 }
141 TypeCtor::AssociatedType(type_alias) => { 140 TypeCtor::AssociatedType(type_alias) => {
142 let generic_params = type_alias.generic_params(db); 141 let generic_params = db.generic_params(type_alias.id.into());
143 generic_params.count_params_including_parent() 142 generic_params.count_params_including_parent()
144 } 143 }
145 TypeCtor::FnPtr { num_args } => num_args as usize + 1, 144 TypeCtor::FnPtr { num_args } => num_args as usize + 1,
@@ -168,7 +167,7 @@ impl TypeCtor {
168 } 167 }
169 } 168 }
170 169
171 pub fn as_generic_def(self) -> Option<crate::generics::GenericDef> { 170 pub fn as_generic_def(self) -> Option<crate::GenericDef> {
172 match self { 171 match self {
173 TypeCtor::Bool 172 TypeCtor::Bool
174 | TypeCtor::Char 173 | TypeCtor::Char
@@ -348,8 +347,9 @@ impl Substs {
348 ) 347 )
349 } 348 }
350 349
351 pub fn build_for_def(db: &impl HirDatabase, def: impl HasGenericParams) -> SubstsBuilder { 350 pub fn build_for_def(db: &impl HirDatabase, def: impl Into<GenericDef>) -> SubstsBuilder {
352 let params = def.generic_params(db); 351 let def = def.into();
352 let params = db.generic_params(def.into());
353 let param_count = params.count_params_including_parent(); 353 let param_count = params.count_params_including_parent();
354 Substs::builder(param_count) 354 Substs::builder(param_count)
355 } 355 }
diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs
index 872a4517d..b60e4bb31 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;
13 14
14const AUTODEREF_RECURSION_LIMIT: usize = 10; 15const AUTODEREF_RECURSION_LIMIT: usize = 10;
15 16
@@ -39,13 +40,13 @@ 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 };
46 let target = deref_trait.associated_type_by_name(db, &name::TARGET_TYPE)?; 47 let target = deref_trait.associated_type_by_name(db, &name::TARGET_TYPE)?;
47 48
48 let generic_params = target.generic_params(db); 49 let generic_params = db.generic_params(target.id.into());
49 if generic_params.count_params_including_parent() != 1 { 50 if generic_params.count_params_including_parent() != 1 {
50 // the Target type + Deref trait should only have one generic parameter, 51 // the Target type + Deref trait should only have one generic parameter,
51 // namely Deref's Self type 52 // namely Deref's Self type
@@ -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..20a7e9352 100644
--- a/crates/ra_hir/src/ty/infer/expr.rs
+++ b/crates/ra_hir/src/ty/infer/expr.rs
@@ -5,15 +5,15 @@ use std::sync::Arc;
5 5
6use hir_def::{ 6use hir_def::{
7 builtin_type::Signedness, 7 builtin_type::Signedness,
8 generics::GenericParams,
8 path::{GenericArg, GenericArgs}, 9 path::{GenericArg, GenericArgs},
10 resolver::resolver_for_expr,
9}; 11};
10use hir_expand::name; 12use hir_expand::name;
11 13
12use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch};
13use crate::{ 14use crate::{
14 db::HirDatabase, 15 db::HirDatabase,
15 expr::{self, Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 16 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
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,
19 Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, 19 Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk,
@@ -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),
@@ -532,7 +534,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
532 ( 534 (
533 ty, 535 ty,
534 self.db.type_for_def(func.into(), Namespace::Values), 536 self.db.type_for_def(func.into(), Namespace::Values),
535 Some(func.generic_params(self.db)), 537 Some(self.db.generic_params(func.id.into())),
536 ) 538 )
537 } 539 }
538 None => (receiver_ty, Ty::Unknown, None), 540 None => (receiver_ty, Ty::Unknown, None),
@@ -643,7 +645,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
643 if let Some(trait_) = f.parent_trait(self.db) { 645 if let Some(trait_) = f.parent_trait(self.db) {
644 // construct a TraitDef 646 // construct a TraitDef
645 let substs = a_ty.parameters.prefix( 647 let substs = a_ty.parameters.prefix(
646 trait_.generic_params(self.db).count_params_including_parent(), 648 self.db
649 .generic_params(trait_.id.into())
650 .count_params_including_parent(),
647 ); 651 );
648 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); 652 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
649 } 653 }
diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs
index 31ca675aa..ee54d8217 100644
--- a/crates/ra_hir/src/ty/infer/path.rs
+++ b/crates/ra_hir/src/ty/infer/path.rs
@@ -1,16 +1,18 @@
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,
9 resolve::{ResolveValueResult, Resolver, TypeNs, ValueNs},
10 ty::{method_resolution, Namespace, Substs, Ty, TypableDef, TypeWalk}, 10 ty::{method_resolution, Namespace, Substs, Ty, TypableDef, TypeWalk},
11 AssocItem, Container, Name, Path, 11 AssocItem, Container, Function, Name, Path,
12}; 12};
13 13
14use super::{ExprOrPatId, InferenceContext, TraitRef};
15
14impl<'a, D: HirDatabase> InferenceContext<'a, D> { 16impl<'a, D: HirDatabase> InferenceContext<'a, D> {
15 pub(super) fn infer_path( 17 pub(super) fn infer_path(
16 &mut self, 18 &mut self,
@@ -60,11 +62,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
60 let ty = self.resolve_ty_as_possible(&mut vec![], ty); 62 let ty = self.resolve_ty_as_possible(&mut vec![], ty);
61 return Some(ty); 63 return Some(ty);
62 } 64 }
63 ValueNs::Function(it) => it.into(), 65 ValueNs::FunctionId(it) => it.into(),
64 ValueNs::Const(it) => it.into(), 66 ValueNs::ConstId(it) => it.into(),
65 ValueNs::Static(it) => it.into(), 67 ValueNs::StaticId(it) => it.into(),
66 ValueNs::Struct(it) => it.into(), 68 ValueNs::StructId(it) => it.into(),
67 ValueNs::EnumVariant(it) => it.into(), 69 ValueNs::EnumVariantId(it) => it.into(),
68 }; 70 };
69 71
70 let mut ty = self.db.type_for_def(typable, Namespace::Values); 72 let mut ty = self.db.type_for_def(typable, Namespace::Values);
@@ -94,13 +96,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
94 let is_before_last = remaining_segments.len() == 1; 96 let is_before_last = remaining_segments.len() == 1;
95 97
96 match (def, is_before_last) { 98 match (def, is_before_last) {
97 (TypeNs::Trait(trait_), true) => { 99 (TypeNs::TraitId(trait_), true) => {
98 let segment = 100 let segment =
99 remaining_segments.last().expect("there should be at least one segment here"); 101 remaining_segments.last().expect("there should be at least one segment here");
100 let trait_ref = TraitRef::from_resolved_path( 102 let trait_ref = TraitRef::from_resolved_path(
101 self.db, 103 self.db,
102 &self.resolver, 104 &self.resolver,
103 trait_, 105 trait_.into(),
104 resolved_segment, 106 resolved_segment,
105 None, 107 None,
106 ); 108 );
@@ -160,8 +162,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
160 AssocItem::TypeAlias(_) => None, 162 AssocItem::TypeAlias(_) => None,
161 })?; 163 })?;
162 let def = match item { 164 let def = match item {
163 AssocItem::Function(f) => ValueNs::Function(f), 165 AssocItem::Function(f) => ValueNs::FunctionId(f.id),
164 AssocItem::Const(c) => ValueNs::Const(c), 166 AssocItem::Const(c) => ValueNs::ConstId(c.id),
165 AssocItem::TypeAlias(_) => unreachable!(), 167 AssocItem::TypeAlias(_) => unreachable!(),
166 }; 168 };
167 let substs = Substs::build_for_def(self.db, item) 169 let substs = Substs::build_for_def(self.db, item)
@@ -193,8 +195,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
193 method_resolution::LookupMode::Path, 195 method_resolution::LookupMode::Path,
194 move |_ty, item| { 196 move |_ty, item| {
195 let def = match item { 197 let def = match item {
196 AssocItem::Function(f) => ValueNs::Function(f), 198 AssocItem::Function(f) => ValueNs::FunctionId(f.id),
197 AssocItem::Const(c) => ValueNs::Const(c), 199 AssocItem::Const(c) => ValueNs::ConstId(c.id),
198 AssocItem::TypeAlias(_) => unreachable!(), 200 AssocItem::TypeAlias(_) => unreachable!(),
199 }; 201 };
200 let substs = match item.container(self.db) { 202 let substs = match item.container(self.db) {
@@ -224,9 +226,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
224 } 226 }
225 227
226 fn find_self_types(&self, def: &ValueNs, actual_def_ty: Ty) -> Option<Substs> { 228 fn find_self_types(&self, def: &ValueNs, actual_def_ty: Ty) -> Option<Substs> {
227 if let ValueNs::Function(func) = def { 229 if let ValueNs::FunctionId(func) = def {
230 let func = Function::from(*func);
228 // We only do the infer if parent has generic params 231 // We only do the infer if parent has generic params
229 let gen = func.generic_params(self.db); 232 let gen = self.db.generic_params(func.id.into());
230 if gen.count_parent_params() == 0 { 233 if gen.count_parent_params() == 0 {
231 return None; 234 return None;
232 } 235 }
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index 397ee7d5f..75c552569 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -10,8 +10,11 @@ use std::sync::Arc;
10 10
11use hir_def::{ 11use hir_def::{
12 builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType}, 12 builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType},
13 generics::WherePredicate,
13 path::{GenericArg, PathSegment}, 14 path::{GenericArg, PathSegment},
15 resolver::{HasResolver, Resolver, TypeNs},
14 type_ref::{TypeBound, TypeRef}, 16 type_ref::{TypeBound, TypeRef},
17 AdtId, GenericDefId,
15}; 18};
16 19
17use super::{ 20use super::{
@@ -20,16 +23,13 @@ use super::{
20}; 23};
21use crate::{ 24use crate::{
22 db::HirDatabase, 25 db::HirDatabase,
23 generics::HasGenericParams,
24 generics::{GenericDef, WherePredicate},
25 resolve::{HasResolver, Resolver, TypeNs},
26 ty::{ 26 ty::{
27 primitive::{FloatTy, IntTy, Uncertain}, 27 primitive::{FloatTy, IntTy, Uncertain},
28 Adt, 28 Adt,
29 }, 29 },
30 util::make_mut_slice, 30 util::make_mut_slice,
31 Const, Enum, EnumVariant, Function, ModuleDef, Path, Static, Struct, StructField, Trait, 31 Const, Enum, EnumVariant, Function, GenericDef, ImplBlock, ModuleDef, Path, Static, Struct,
32 TypeAlias, Union, VariantDef, 32 StructField, Trait, TypeAlias, Union, VariantDef,
33}; 33};
34 34
35// FIXME: this is only really used in `type_for_def`, which contains a bunch of 35// FIXME: this is only really used in `type_for_def`, which contains a bunch of
@@ -156,9 +156,14 @@ impl Ty {
156 remaining_segments: &[PathSegment], 156 remaining_segments: &[PathSegment],
157 ) -> Ty { 157 ) -> Ty {
158 let ty = match resolution { 158 let ty = match resolution {
159 TypeNs::Trait(trait_) => { 159 TypeNs::TraitId(trait_) => {
160 let trait_ref = 160 let trait_ref = TraitRef::from_resolved_path(
161 TraitRef::from_resolved_path(db, resolver, trait_, resolved_segment, None); 161 db,
162 resolver,
163 trait_.into(),
164 resolved_segment,
165 None,
166 );
162 return if remaining_segments.len() == 1 { 167 return if remaining_segments.len() == 1 {
163 let segment = &remaining_segments[0]; 168 let segment = &remaining_segments[0];
164 match trait_ref 169 match trait_ref
@@ -189,18 +194,18 @@ impl Ty {
189 let name = resolved_segment.name.clone(); 194 let name = resolved_segment.name.clone();
190 Ty::Param { idx, name } 195 Ty::Param { idx, name }
191 } 196 }
192 TypeNs::SelfType(impl_block) => impl_block.target_ty(db), 197 TypeNs::SelfType(impl_block) => ImplBlock::from(impl_block).target_ty(db),
193 TypeNs::AdtSelfType(adt) => adt.ty(db), 198 TypeNs::AdtSelfType(adt) => Adt::from(adt).ty(db),
194 199
195 TypeNs::Adt(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), 200 TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()),
196 TypeNs::BuiltinType(it) => { 201 TypeNs::BuiltinType(it) => {
197 Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) 202 Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into())
198 } 203 }
199 TypeNs::TypeAlias(it) => { 204 TypeNs::TypeAliasId(it) => {
200 Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) 205 Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into())
201 } 206 }
202 // FIXME: report error 207 // FIXME: report error
203 TypeNs::EnumVariant(_) => return Ty::Unknown, 208 TypeNs::EnumVariantId(_) => return Ty::Unknown,
204 }; 209 };
205 210
206 Ty::from_type_relative_path(db, resolver, ty, remaining_segments) 211 Ty::from_type_relative_path(db, resolver, ty, remaining_segments)
@@ -247,7 +252,7 @@ impl Ty {
247 Some(def) => def, 252 Some(def) => def,
248 None => return Ty::Unknown, // this can't actually happen 253 None => return Ty::Unknown, // this can't actually happen
249 }; 254 };
250 let predicates = db.generic_predicates_for_param(def, param_idx); 255 let predicates = db.generic_predicates_for_param(def.into(), param_idx);
251 let traits_from_env = predicates.iter().filter_map(|pred| match pred { 256 let traits_from_env = predicates.iter().filter_map(|pred| match pred {
252 GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_), 257 GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_),
253 _ => None, 258 _ => None,
@@ -336,7 +341,7 @@ pub(super) fn substs_from_path_segment(
336 add_self_param: bool, 341 add_self_param: bool,
337) -> Substs { 342) -> Substs {
338 let mut substs = Vec::new(); 343 let mut substs = Vec::new();
339 let def_generics = def_generic.map(|def| def.generic_params(db)); 344 let def_generics = def_generic.map(|def| db.generic_params(def.into()));
340 345
341 let (parent_param_count, param_count) = 346 let (parent_param_count, param_count) =
342 def_generics.map_or((0, 0), |g| (g.count_parent_params(), g.params.len())); 347 def_generics.map_or((0, 0), |g| (g.count_parent_params(), g.params.len()));
@@ -391,11 +396,11 @@ impl TraitRef {
391 explicit_self_ty: Option<Ty>, 396 explicit_self_ty: Option<Ty>,
392 ) -> Option<Self> { 397 ) -> Option<Self> {
393 let resolved = match resolver.resolve_path_in_type_ns_fully(db, &path)? { 398 let resolved = match resolver.resolve_path_in_type_ns_fully(db, &path)? {
394 TypeNs::Trait(tr) => tr, 399 TypeNs::TraitId(tr) => tr,
395 _ => return None, 400 _ => return None,
396 }; 401 };
397 let segment = path.segments.last().expect("path should have at least one segment"); 402 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)) 403 Some(TraitRef::from_resolved_path(db, resolver, resolved.into(), segment, explicit_self_ty))
399 } 404 }
400 405
401 pub(super) fn from_resolved_path( 406 pub(super) fn from_resolved_path(
@@ -437,7 +442,7 @@ impl TraitRef {
437 } 442 }
438 443
439 pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef { 444 pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef {
440 let substs = Substs::identity(&trait_.generic_params(db)); 445 let substs = Substs::identity(&db.generic_params(trait_.id.into()));
441 TraitRef { trait_, substs } 446 TraitRef { trait_, substs }
442 } 447 }
443 448
@@ -548,8 +553,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 { 553pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty {
549 let parent_def = field.parent_def(db); 554 let parent_def = field.parent_def(db);
550 let resolver = match parent_def { 555 let resolver = match parent_def {
551 VariantDef::Struct(it) => it.resolver(db), 556 VariantDef::Struct(it) => it.id.resolver(db),
552 VariantDef::EnumVariant(it) => it.parent_enum(db).resolver(db), 557 VariantDef::EnumVariant(it) => it.parent.id.resolver(db),
553 }; 558 };
554 let var_data = parent_def.variant_data(db); 559 let var_data = parent_def.variant_data(db);
555 let type_ref = &var_data.fields().unwrap()[field.id].type_ref; 560 let type_ref = &var_data.fields().unwrap()[field.id].type_ref;
@@ -569,7 +574,7 @@ pub(crate) fn generic_predicates_for_param_query(
569 def: GenericDef, 574 def: GenericDef,
570 param_idx: u32, 575 param_idx: u32,
571) -> Arc<[GenericPredicate]> { 576) -> Arc<[GenericPredicate]> {
572 let resolver = def.resolver(db); 577 let resolver = GenericDefId::from(def).resolver(db);
573 resolver 578 resolver
574 .where_predicates_in_scope() 579 .where_predicates_in_scope()
575 // we have to filter out all other predicates *first*, before attempting to lower them 580 // we have to filter out all other predicates *first*, before attempting to lower them
@@ -595,7 +600,7 @@ pub(crate) fn generic_predicates_query(
595 db: &impl HirDatabase, 600 db: &impl HirDatabase,
596 def: GenericDef, 601 def: GenericDef,
597) -> Arc<[GenericPredicate]> { 602) -> Arc<[GenericPredicate]> {
598 let resolver = def.resolver(db); 603 let resolver = GenericDefId::from(def).resolver(db);
599 resolver 604 resolver
600 .where_predicates_in_scope() 605 .where_predicates_in_scope()
601 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) 606 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred))
@@ -604,8 +609,8 @@ pub(crate) fn generic_predicates_query(
604 609
605/// Resolve the default type params from generics 610/// Resolve the default type params from generics
606pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> Substs { 611pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> Substs {
607 let resolver = def.resolver(db); 612 let resolver = GenericDefId::from(def).resolver(db);
608 let generic_params = def.generic_params(db); 613 let generic_params = db.generic_params(def.into());
609 614
610 let defaults = generic_params 615 let defaults = generic_params
611 .params_including_parent() 616 .params_including_parent()
@@ -618,7 +623,7 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) ->
618 623
619fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { 624fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig {
620 let data = def.data(db); 625 let data = def.data(db);
621 let resolver = def.resolver(db); 626 let resolver = def.id.resolver(db);
622 let params = data.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); 627 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()); 628 let ret = Ty::from_hir(db, &resolver, data.ret_type());
624 FnSig::from_params_and_return(params, ret) 629 FnSig::from_params_and_return(params, ret)
@@ -627,7 +632,7 @@ fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig {
627/// Build the declared type of a function. This should not need to look at the 632/// Build the declared type of a function. This should not need to look at the
628/// function body. 633/// function body.
629fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { 634fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
630 let generics = def.generic_params(db); 635 let generics = db.generic_params(def.id.into());
631 let substs = Substs::identity(&generics); 636 let substs = Substs::identity(&generics);
632 Ty::apply(TypeCtor::FnDef(def.into()), substs) 637 Ty::apply(TypeCtor::FnDef(def.into()), substs)
633} 638}
@@ -635,7 +640,7 @@ fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
635/// Build the declared type of a const. 640/// Build the declared type of a const.
636fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { 641fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty {
637 let data = def.data(db); 642 let data = def.data(db);
638 let resolver = def.resolver(db); 643 let resolver = def.id.resolver(db);
639 644
640 Ty::from_hir(db, &resolver, data.type_ref()) 645 Ty::from_hir(db, &resolver, data.type_ref())
641} 646}
@@ -643,7 +648,7 @@ fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty {
643/// Build the declared type of a static. 648/// Build the declared type of a static.
644fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { 649fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty {
645 let data = def.data(db); 650 let data = def.data(db);
646 let resolver = def.resolver(db); 651 let resolver = def.id.resolver(db);
647 652
648 Ty::from_hir(db, &resolver, data.type_ref()) 653 Ty::from_hir(db, &resolver, data.type_ref())
649} 654}
@@ -695,7 +700,7 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig {
695 Some(fields) => fields, 700 Some(fields) => fields,
696 None => panic!("fn_sig_for_struct_constructor called on unit struct"), 701 None => panic!("fn_sig_for_struct_constructor called on unit struct"),
697 }; 702 };
698 let resolver = def.resolver(db); 703 let resolver = def.id.resolver(db);
699 let params = fields 704 let params = fields
700 .iter() 705 .iter()
701 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 706 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
@@ -710,7 +715,7 @@ fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty {
710 if struct_data.variant_data.fields().is_none() { 715 if struct_data.variant_data.fields().is_none() {
711 return type_for_adt(db, def); // Unit struct 716 return type_for_adt(db, def); // Unit struct
712 } 717 }
713 let generics = def.generic_params(db); 718 let generics = db.generic_params(def.id.into());
714 let substs = Substs::identity(&generics); 719 let substs = Substs::identity(&generics);
715 Ty::apply(TypeCtor::FnDef(def.into()), substs) 720 Ty::apply(TypeCtor::FnDef(def.into()), substs)
716} 721}
@@ -721,12 +726,12 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant)
721 Some(fields) => fields, 726 Some(fields) => fields,
722 None => panic!("fn_sig_for_enum_variant_constructor called for unit variant"), 727 None => panic!("fn_sig_for_enum_variant_constructor called for unit variant"),
723 }; 728 };
724 let resolver = def.parent_enum(db).resolver(db); 729 let resolver = def.parent.id.resolver(db);
725 let params = fields 730 let params = fields
726 .iter() 731 .iter()
727 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 732 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
728 .collect::<Vec<_>>(); 733 .collect::<Vec<_>>();
729 let generics = def.parent_enum(db).generic_params(db); 734 let generics = db.generic_params(def.parent_enum(db).id.into());
730 let substs = Substs::identity(&generics); 735 let substs = Substs::identity(&generics);
731 let ret = type_for_adt(db, def.parent_enum(db)).subst(&substs); 736 let ret = type_for_adt(db, def.parent_enum(db)).subst(&substs);
732 FnSig::from_params_and_return(params, ret) 737 FnSig::from_params_and_return(params, ret)
@@ -738,19 +743,21 @@ fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) ->
738 if var_data.fields().is_none() { 743 if var_data.fields().is_none() {
739 return type_for_adt(db, def.parent_enum(db)); // Unit variant 744 return type_for_adt(db, def.parent_enum(db)); // Unit variant
740 } 745 }
741 let generics = def.parent_enum(db).generic_params(db); 746 let generics = db.generic_params(def.parent_enum(db).id.into());
742 let substs = Substs::identity(&generics); 747 let substs = Substs::identity(&generics);
743 Ty::apply(TypeCtor::FnDef(def.into()), substs) 748 Ty::apply(TypeCtor::FnDef(def.into()), substs)
744} 749}
745 750
746fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt> + HasGenericParams) -> Ty { 751fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt>) -> Ty {
747 let generics = adt.generic_params(db); 752 let adt = adt.into();
748 Ty::apply(TypeCtor::Adt(adt.into()), Substs::identity(&generics)) 753 let adt_id: AdtId = adt.into();
754 let generics = db.generic_params(adt_id.into());
755 Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics))
749} 756}
750 757
751fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { 758fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty {
752 let generics = t.generic_params(db); 759 let generics = db.generic_params(t.id.into());
753 let resolver = t.resolver(db); 760 let resolver = t.id.resolver(db);
754 let type_ref = t.type_ref(db); 761 let type_ref = t.type_ref(db);
755 let substs = Substs::identity(&generics); 762 let substs = Substs::identity(&generics);
756 let inner = Ty::from_hir(db, &resolver, &type_ref.unwrap_or(TypeRef::Error)); 763 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/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index 9bf93981a..88785f305 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -16,10 +16,9 @@ use ra_db::salsa::{InternId, InternKey};
16use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; 16use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation};
17use crate::{ 17use crate::{
18 db::HirDatabase, 18 db::HirDatabase,
19 generics::{GenericDef, HasGenericParams},
20 ty::display::HirDisplay, 19 ty::display::HirDisplay,
21 ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, 20 ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk},
22 Crate, HasBody, ImplBlock, Trait, TypeAlias, 21 Crate, GenericDef, HasBody, ImplBlock, Trait, TypeAlias,
23}; 22};
24 23
25/// This represents a trait whose name we could not resolve. 24/// This represents a trait whose name we could not resolve.
@@ -509,7 +508,7 @@ pub(crate) fn associated_ty_data_query(
509 Some(crate::Container::Trait(t)) => t, 508 Some(crate::Container::Trait(t)) => t,
510 _ => panic!("associated type not in trait"), 509 _ => panic!("associated type not in trait"),
511 }; 510 };
512 let generic_params = type_alias.generic_params(db); 511 let generic_params = db.generic_params(type_alias.id.into());
513 let bound_data = chalk_rust_ir::AssociatedTyDatumBound { 512 let bound_data = chalk_rust_ir::AssociatedTyDatumBound {
514 // FIXME add bounds and where clauses 513 // FIXME add bounds and where clauses
515 bounds: vec![], 514 bounds: vec![],
@@ -550,7 +549,7 @@ pub(crate) fn trait_datum_query(
550 } 549 }
551 let trait_: Trait = from_chalk(db, trait_id); 550 let trait_: Trait = from_chalk(db, trait_id);
552 debug!("trait {:?} = {:?}", trait_id, trait_.name(db)); 551 debug!("trait {:?} = {:?}", trait_id, trait_.name(db));
553 let generic_params = trait_.generic_params(db); 552 let generic_params = db.generic_params(trait_.id.into());
554 let bound_vars = Substs::bound_vars(&generic_params); 553 let bound_vars = Substs::bound_vars(&generic_params);
555 let flags = chalk_rust_ir::TraitFlags { 554 let flags = chalk_rust_ir::TraitFlags {
556 auto: trait_.is_auto(db), 555 auto: trait_.is_auto(db),
@@ -594,7 +593,7 @@ pub(crate) fn struct_datum_query(
594 let where_clauses = type_ctor 593 let where_clauses = type_ctor
595 .as_generic_def() 594 .as_generic_def()
596 .map(|generic_def| { 595 .map(|generic_def| {
597 let generic_params = generic_def.generic_params(db); 596 let generic_params = db.generic_params(generic_def.into());
598 let bound_vars = Substs::bound_vars(&generic_params); 597 let bound_vars = Substs::bound_vars(&generic_params);
599 convert_where_clauses(db, generic_def, &bound_vars) 598 convert_where_clauses(db, generic_def, &bound_vars)
600 }) 599 })
@@ -634,7 +633,7 @@ fn impl_block_datum(
634 impl_id: ImplId, 633 impl_id: ImplId,
635 impl_block: ImplBlock, 634 impl_block: ImplBlock,
636) -> Option<Arc<ImplDatum<ChalkIr>>> { 635) -> Option<Arc<ImplDatum<ChalkIr>>> {
637 let generic_params = impl_block.generic_params(db); 636 let generic_params = db.generic_params(impl_block.id.into());
638 let bound_vars = Substs::bound_vars(&generic_params); 637 let bound_vars = Substs::bound_vars(&generic_params);
639 let trait_ref = impl_block.target_trait_ref(db)?.subst(&bound_vars); 638 let trait_ref = impl_block.target_trait_ref(db)?.subst(&bound_vars);
640 let trait_ = trait_ref.trait_; 639 let trait_ = trait_ref.trait_;
@@ -786,7 +785,7 @@ fn type_alias_associated_ty_value(
786 let assoc_ty = trait_ 785 let assoc_ty = trait_
787 .associated_type_by_name(db, &type_alias.name(db)) 786 .associated_type_by_name(db, &type_alias.name(db))
788 .expect("assoc ty value should not exist"); // validated when building the impl data as well 787 .expect("assoc ty value should not exist"); // validated when building the impl data as well
789 let generic_params = impl_block.generic_params(db); 788 let generic_params = db.generic_params(impl_block.id.into());
790 let bound_vars = Substs::bound_vars(&generic_params); 789 let bound_vars = Substs::bound_vars(&generic_params);
791 let ty = db.type_for_def(type_alias.into(), crate::ty::Namespace::Types).subst(&bound_vars); 790 let ty = db.type_for_def(type_alias.into(), crate::ty::Namespace::Types).subst(&bound_vars);
792 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; 791 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) };
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index a5bb60e85..d8e911aa5 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},
@@ -190,6 +191,7 @@ where
190 None => self.collect_expr_opt(condition.expr()), 191 None => self.collect_expr_opt(condition.expr()),
191 // if let -- desugar to match 192 // if let -- desugar to match
192 Some(pat) => { 193 Some(pat) => {
194 tested_by!(infer_resolve_while_let);
193 let pat = self.collect_pat(pat); 195 let pat = self.collect_pat(pat);
194 let match_expr = self.collect_expr_opt(condition.expr()); 196 let match_expr = self.collect_expr_opt(condition.expr());
195 let placeholder_pat = self.missing_pat(); 197 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..58740b679 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 while_let_desugaring() {
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..7b5c3ec06 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,
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,80 +354,31 @@ 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 }
376}
377
378impl Resolver {
379 pub(crate) fn push_scope(mut self, scope: Scope) -> Resolver {
380 self.scopes.push(scope);
381 self
382 }
383
384 pub(crate) fn push_generic_params_scope(
385 self,
386 db: &impl DefDatabase,
387 def: GenericDef,
388 ) -> Resolver {
389 let params = def.generic_params(db);
390 if params.params.is_empty() {
391 self
392 } else {
393 self.push_scope(Scope::GenericParams { def, params })
394 }
395 }
396
397 pub(crate) fn push_impl_block_scope(self, impl_block: ImplBlock) -> Resolver {
398 self.push_scope(Scope::ImplBlockScope(impl_block))
399 }
400 363
401 pub(crate) fn push_module_scope( 364 pub fn body_owner(&self) -> Option<DefWithBodyId> {
402 self, 365 self.scopes.iter().find_map(|scope| match scope {
403 crate_def_map: Arc<CrateDefMap>, 366 Scope::ExprScope(it) => Some(it.owner),
404 module_id: CrateModuleId, 367 _ => None,
405 ) -> Resolver { 368 })
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 } 369 }
417} 370}
418 371
419/// For IDE only
420pub enum ScopeDef { 372pub enum ScopeDef {
421 ModuleDef(ModuleDef), 373 PerNs(PerNs),
422 MacroDef(MacroDef), 374 ImplSelfType(ImplId),
375 AdtSelfType(AdtId),
423 GenericParam(u32), 376 GenericParam(u32),
424 ImplSelfType(ImplBlock), 377 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} 378}
441 379
442impl Scope { 380impl Scope {
443 fn process_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { 381 fn process_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef)) {
444 match self { 382 match self {
445 Scope::ModuleScope(m) => { 383 Scope::ModuleScope(m) => {
446 // FIXME: should we provide `self` here? 384 // FIXME: should we provide `self` here?
@@ -451,18 +389,18 @@ impl Scope {
451 // }), 389 // }),
452 // ); 390 // );
453 m.crate_def_map[m.module_id].scope.entries().for_each(|(name, res)| { 391 m.crate_def_map[m.module_id].scope.entries().for_each(|(name, res)| {
454 f(name.clone(), res.def.into()); 392 f(name.clone(), ScopeDef::PerNs(res.def));
455 }); 393 });
456 m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| { 394 m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| {
457 f(name.clone(), ScopeDef::MacroDef(macro_.into())); 395 f(name.clone(), ScopeDef::PerNs(PerNs::macros(macro_)));
458 }); 396 });
459 m.crate_def_map.extern_prelude().iter().for_each(|(name, &def)| { 397 m.crate_def_map.extern_prelude().iter().for_each(|(name, &def)| {
460 f(name.clone(), ScopeDef::ModuleDef(def.into())); 398 f(name.clone(), ScopeDef::PerNs(PerNs::types(def.into())));
461 }); 399 });
462 if let Some(prelude) = m.crate_def_map.prelude() { 400 if let Some(prelude) = m.crate_def_map.prelude() {
463 let prelude_def_map = db.crate_def_map(prelude.krate); 401 let prelude_def_map = db.crate_def_map(prelude.krate);
464 prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| { 402 prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| {
465 f(name.clone(), res.def.into()); 403 f(name.clone(), ScopeDef::PerNs(res.def));
466 }); 404 });
467 } 405 }
468 } 406 }
@@ -472,114 +410,175 @@ impl Scope {
472 } 410 }
473 } 411 }
474 Scope::ImplBlockScope(i) => { 412 Scope::ImplBlockScope(i) => {
475 f(name::SELF_TYPE, ScopeDef::ImplSelfType(*i)); 413 f(name::SELF_TYPE, ScopeDef::ImplSelfType((*i).into()));
476 } 414 }
477 Scope::AdtScope(i) => { 415 Scope::AdtScope(i) => {
478 f(name::SELF_TYPE, ScopeDef::AdtSelfType(*i)); 416 f(name::SELF_TYPE, ScopeDef::AdtSelfType((*i).into()));
479 } 417 }
480 Scope::ExprScope(scope) => { 418 Scope::ExprScope(scope) => {
481 scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| { 419 scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| {
482 let local = Local { parent: scope.owner, pat_id: e.pat() }; 420 f(e.name().clone(), ScopeDef::Local(e.pat()));
483 f(e.name().clone(), ScopeDef::Local(local));
484 }); 421 });
485 } 422 }
486 } 423 }
487 } 424 }
488} 425}
489 426
490pub(crate) trait HasResolver { 427// needs arbitrary_self_types to be a method... or maybe move to the def?
428pub fn resolver_for_expr(
429 db: &impl DefDatabase2,
430 owner: DefWithBodyId,
431 expr_id: ExprId,
432) -> Resolver {
433 let scopes = db.expr_scopes(owner);
434 resolver_for_scope(db, owner, scopes.scope_for(expr_id))
435}
436
437pub fn resolver_for_scope(
438 db: &impl DefDatabase2,
439 owner: DefWithBodyId,
440 scope_id: Option<ScopeId>,
441) -> Resolver {
442 let mut r = owner.resolver(db);
443 let scopes = db.expr_scopes(owner);
444 let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>();
445 for scope in scope_chain.into_iter().rev() {
446 r = r.push_expr_scope(owner, Arc::clone(&scopes), scope);
447 }
448 r
449}
450
451impl Resolver {
452 fn push_scope(mut self, scope: Scope) -> Resolver {
453 self.scopes.push(scope);
454 self
455 }
456
457 fn push_generic_params_scope(self, db: &impl DefDatabase2, def: GenericDefId) -> Resolver {
458 let params = db.generic_params(def);
459 if params.params.is_empty() {
460 self
461 } else {
462 self.push_scope(Scope::GenericParams { def, params })
463 }
464 }
465
466 fn push_impl_block_scope(self, impl_block: ImplId) -> Resolver {
467 self.push_scope(Scope::ImplBlockScope(impl_block))
468 }
469
470 fn push_module_scope(
471 self,
472 crate_def_map: Arc<CrateDefMap>,
473 module_id: CrateModuleId,
474 ) -> Resolver {
475 self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id }))
476 }
477
478 fn push_expr_scope(
479 self,
480 owner: DefWithBodyId,
481 expr_scopes: Arc<ExprScopes>,
482 scope_id: ScopeId,
483 ) -> Resolver {
484 self.push_scope(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id }))
485 }
486}
487
488pub trait HasResolver {
491 /// Builds a resolver for type references inside this def. 489 /// Builds a resolver for type references inside this def.
492 fn resolver(self, db: &impl DefDatabase) -> Resolver; 490 fn resolver(self, db: &impl DefDatabase2) -> Resolver;
493} 491}
494 492
495impl HasResolver for Module { 493impl HasResolver for ModuleId {
496 fn resolver(self, db: &impl DefDatabase) -> Resolver { 494 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
497 let def_map = db.crate_def_map(self.id.krate); 495 let def_map = db.crate_def_map(self.krate);
498 Resolver::default().push_module_scope(def_map, self.id.module_id) 496 Resolver::default().push_module_scope(def_map, self.module_id)
499 } 497 }
500} 498}
501 499
502impl HasResolver for Trait { 500impl HasResolver for TraitId {
503 fn resolver(self, db: &impl DefDatabase) -> Resolver { 501 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
504 self.module(db).resolver(db).push_generic_params_scope(db, self.into()) 502 self.module(db).resolver(db).push_generic_params_scope(db, self.into())
505 } 503 }
506} 504}
507 505
508impl<T: Into<Adt>> HasResolver for T { 506impl<T: Into<AdtId>> HasResolver for T {
509 fn resolver(self, db: &impl DefDatabase) -> Resolver { 507 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
510 let def = self.into(); 508 let def = self.into();
511 def.module(db) 509 let module = match def {
510 AdtId::StructId(it) => it.0.module(db),
511 AdtId::UnionId(it) => it.0.module(db),
512 AdtId::EnumId(it) => it.module(db),
513 };
514
515 module
512 .resolver(db) 516 .resolver(db)
513 .push_generic_params_scope(db, def.into()) 517 .push_generic_params_scope(db, def.into())
514 .push_scope(Scope::AdtScope(def)) 518 .push_scope(Scope::AdtScope(def))
515 } 519 }
516} 520}
517 521
518impl HasResolver for Function { 522impl HasResolver for FunctionId {
519 fn resolver(self, db: &impl DefDatabase) -> Resolver { 523 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
520 self.container(db) 524 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
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 }
525} 526}
526 527
527impl HasResolver for DefWithBody { 528impl HasResolver for DefWithBodyId {
528 fn resolver(self, db: &impl DefDatabase) -> Resolver { 529 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
529 match self { 530 match self {
530 DefWithBody::Const(c) => c.resolver(db), 531 DefWithBodyId::ConstId(c) => c.resolver(db),
531 DefWithBody::Function(f) => f.resolver(db), 532 DefWithBodyId::FunctionId(f) => f.resolver(db),
532 DefWithBody::Static(s) => s.resolver(db), 533 DefWithBodyId::StaticId(s) => s.resolver(db),
533 } 534 }
534 } 535 }
535} 536}
536 537
537impl HasResolver for Const { 538impl HasResolver for ConstId {
538 fn resolver(self, db: &impl DefDatabase) -> Resolver { 539 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
539 self.container(db).map(|c| c.resolver(db)).unwrap_or_else(|| self.module(db).resolver(db)) 540 self.lookup(db).container.resolver(db)
540 } 541 }
541} 542}
542 543
543impl HasResolver for Static { 544impl HasResolver for StaticId {
544 fn resolver(self, db: &impl DefDatabase) -> Resolver { 545 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
545 self.module(db).resolver(db) 546 self.module(db).resolver(db)
546 } 547 }
547} 548}
548 549
549impl HasResolver for TypeAlias { 550impl HasResolver for TypeAliasId {
550 fn resolver(self, db: &impl DefDatabase) -> Resolver { 551 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
551 self.container(db) 552 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 } 553 }
556} 554}
557 555
558impl HasResolver for Container { 556impl HasResolver for ContainerId {
559 fn resolver(self, db: &impl DefDatabase) -> Resolver { 557 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
560 match self { 558 match self {
561 Container::Trait(trait_) => trait_.resolver(db), 559 ContainerId::TraitId(it) => it.resolver(db),
562 Container::ImplBlock(impl_block) => impl_block.resolver(db), 560 ContainerId::ImplId(it) => it.resolver(db),
561 ContainerId::ModuleId(it) => it.resolver(db),
563 } 562 }
564 } 563 }
565} 564}
566 565
567impl HasResolver for GenericDef { 566impl HasResolver for GenericDefId {
568 fn resolver(self, db: &impl DefDatabase) -> crate::Resolver { 567 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
569 match self { 568 match self {
570 GenericDef::Function(inner) => inner.resolver(db), 569 GenericDefId::FunctionId(inner) => inner.resolver(db),
571 GenericDef::Adt(adt) => adt.resolver(db), 570 GenericDefId::AdtId(adt) => adt.resolver(db),
572 GenericDef::Trait(inner) => inner.resolver(db), 571 GenericDefId::TraitId(inner) => inner.resolver(db),
573 GenericDef::TypeAlias(inner) => inner.resolver(db), 572 GenericDefId::TypeAliasId(inner) => inner.resolver(db),
574 GenericDef::ImplBlock(inner) => inner.resolver(db), 573 GenericDefId::ImplId(inner) => inner.resolver(db),
575 GenericDef::EnumVariant(inner) => inner.parent_enum(db).resolver(db), 574 GenericDefId::EnumVariantId(inner) => inner.parent.resolver(db),
576 GenericDef::Const(inner) => inner.resolver(db), 575 GenericDefId::ConstId(inner) => inner.resolver(db),
577 } 576 }
578 } 577 }
579} 578}
580 579
581impl HasResolver for ImplBlock { 580impl HasResolver for ImplId {
582 fn resolver(self, db: &impl DefDatabase) -> Resolver { 581 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
583 self.module(db) 582 self.module(db)
584 .resolver(db) 583 .resolver(db)
585 .push_generic_params_scope(db, self.into()) 584 .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}
diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs
index 3c11c8a22..e1d93a8ef 100644
--- a/crates/ra_hir_expand/src/db.rs
+++ b/crates/ra_hir_expand/src/db.rs
@@ -151,6 +151,7 @@ pub(crate) fn parse_macro(
151 let fragment_kind = match macro_file.macro_file_kind { 151 let fragment_kind = match macro_file.macro_file_kind {
152 MacroFileKind::Items => FragmentKind::Items, 152 MacroFileKind::Items => FragmentKind::Items,
153 MacroFileKind::Expr => FragmentKind::Expr, 153 MacroFileKind::Expr => FragmentKind::Expr,
154 MacroFileKind::Statements => FragmentKind::Statements,
154 }; 155 };
155 let (parse, rev_token_map) = mbe::token_tree_to_syntax_node(&tt, fragment_kind).ok()?; 156 let (parse, rev_token_map) = mbe::token_tree_to_syntax_node(&tt, fragment_kind).ok()?;
156 Some((parse, Arc::new(rev_token_map))) 157 Some((parse, Arc::new(rev_token_map)))
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs
index 1389f64ce..126d12fbb 100644
--- a/crates/ra_hir_expand/src/lib.rs
+++ b/crates/ra_hir_expand/src/lib.rs
@@ -109,6 +109,7 @@ pub struct MacroFile {
109pub enum MacroFileKind { 109pub enum MacroFileKind {
110 Items, 110 Items,
111 Expr, 111 Expr,
112 Statements,
112} 113}
113 114
114/// `MacroCallId` identifies a particular macro invocation, like 115/// `MacroCallId` identifies a particular macro invocation, like
diff --git a/crates/ra_ide_api/src/expand_macro.rs b/crates/ra_ide_api/src/expand_macro.rs
index 7f39262dc..7dbf33a16 100644
--- a/crates/ra_ide_api/src/expand_macro.rs
+++ b/crates/ra_ide_api/src/expand_macro.rs
@@ -84,24 +84,19 @@ fn insert_whitespaces(syn: SyntaxNode) -> String {
84 }; 84 };
85 85
86 res += &match token.kind() { 86 res += &match token.kind() {
87 k @ _ 87 k @ _ if is_text(k) && is_next(|it| !it.is_punct(), true) => {
88 if (k.is_keyword() || k.is_literal() || k == IDENT)
89 && is_next(|it| !it.is_punct(), true) =>
90 {
91 token.text().to_string() + " " 88 token.text().to_string() + " "
92 } 89 }
93 L_CURLY if is_next(|it| it != R_CURLY, true) => { 90 L_CURLY if is_next(|it| it != R_CURLY, true) => {
94 indent += 1; 91 indent += 1;
95 format!(" {{\n{}", " ".repeat(indent)) 92 let leading_space = if is_last(|it| is_text(it), false) { " " } else { "" };
93 format!("{}{{\n{}", leading_space, " ".repeat(indent))
96 } 94 }
97 R_CURLY if is_last(|it| it != L_CURLY, true) => { 95 R_CURLY if is_last(|it| it != L_CURLY, true) => {
98 indent = indent.checked_sub(1).unwrap_or(0); 96 indent = indent.checked_sub(1).unwrap_or(0);
99 format!("\n}}{}", " ".repeat(indent)) 97 format!("\n{}}}", " ".repeat(indent))
100 }
101 R_CURLY => {
102 indent = indent.checked_sub(1).unwrap_or(0);
103 format!("}}\n{}", " ".repeat(indent))
104 } 98 }
99 R_CURLY => format!("}}\n{}", " ".repeat(indent)),
105 T![;] => format!(";\n{}", " ".repeat(indent)), 100 T![;] => format!(";\n{}", " ".repeat(indent)),
106 T![->] => " -> ".to_string(), 101 T![->] => " -> ".to_string(),
107 T![=] => " = ".to_string(), 102 T![=] => " = ".to_string(),
@@ -112,7 +107,11 @@ fn insert_whitespaces(syn: SyntaxNode) -> String {
112 last = Some(token.kind()); 107 last = Some(token.kind());
113 } 108 }
114 109
115 res 110 return res;
111
112 fn is_text(k: SyntaxKind) -> bool {
113 k.is_keyword() || k.is_literal() || k == IDENT
114 }
116} 115}
117 116
118#[cfg(test)] 117#[cfg(test)]
@@ -175,4 +174,47 @@ fn some_thing() -> u32 {
175} 174}
176"###); 175"###);
177 } 176 }
177
178 #[test]
179 fn macro_expand_match_ast() {
180 let res = check_expand_macro(
181 r#"
182 //- /lib.rs
183 macro_rules! match_ast {
184 (match $node:ident { $($tt:tt)* }) => { match_ast!(match ($node) { $($tt)* }) };
185
186 (match ($node:expr) {
187 $( ast::$ast:ident($it:ident) => $res:block, )*
188 _ => $catch_all:expr $(,)?
189 }) => {{
190 $( if let Some($it) = ast::$ast::cast($node.clone()) $res else )*
191 { $catch_all }
192 }};
193 }
194
195 fn main() {
196 mat<|>ch_ast! {
197 match container {
198 ast::TraitDef(it) => {},
199 ast::ImplBlock(it) => {},
200 _ => { continue },
201 }
202 }
203 }
204 "#,
205 );
206
207 assert_eq!(res.name, "match_ast");
208 assert_snapshot!(res.expansion, @r###"
209{
210 if let Some(it) = ast::TraitDef::cast(container.clone()){}
211 else if let Some(it) = ast::ImplBlock::cast(container.clone()){}
212 else {
213 {
214 continue
215 }
216 }
217}
218"###);
219 }
178} 220}
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs
index d1c49c0b3..1de399fee 100644
--- a/crates/ra_mbe/src/syntax_bridge.rs
+++ b/crates/ra_mbe/src/syntax_bridge.rs
@@ -5,6 +5,7 @@ use ra_syntax::{
5 ast, AstNode, AstToken, NodeOrToken, Parse, SmolStr, SyntaxKind, SyntaxKind::*, SyntaxNode, 5 ast, AstNode, AstToken, NodeOrToken, Parse, SmolStr, SyntaxKind, SyntaxKind::*, SyntaxNode,
6 SyntaxTreeBuilder, TextRange, TextUnit, T, 6 SyntaxTreeBuilder, TextRange, TextUnit, T,
7}; 7};
8use std::iter::successors;
8use tt::buffer::{Cursor, TokenBuffer}; 9use tt::buffer::{Cursor, TokenBuffer};
9 10
10use crate::subtree_source::SubtreeTokenSource; 11use crate::subtree_source::SubtreeTokenSource;
@@ -160,6 +161,31 @@ impl Convertor {
160 161
161 let first_child = tt.first_child_or_token()?; 162 let first_child = tt.first_child_or_token()?;
162 let last_child = tt.last_child_or_token()?; 163 let last_child = tt.last_child_or_token()?;
164
165 // ignore trivial first_child and last_child
166 let first_child = successors(Some(first_child), |it| {
167 if it.kind().is_trivia() {
168 it.next_sibling_or_token()
169 } else {
170 None
171 }
172 })
173 .last()
174 .unwrap();
175 if first_child.kind().is_trivia() {
176 return Some(tt::Subtree { token_trees: vec![], delimiter: tt::Delimiter::None });
177 }
178
179 let last_child = successors(Some(last_child), |it| {
180 if it.kind().is_trivia() {
181 it.prev_sibling_or_token()
182 } else {
183 None
184 }
185 })
186 .last()
187 .unwrap();
188
163 let (delimiter, skip_first) = match (first_child.kind(), last_child.kind()) { 189 let (delimiter, skip_first) = match (first_child.kind(), last_child.kind()) {
164 (T!['('], T![')']) => (tt::Delimiter::Parenthesis, true), 190 (T!['('], T![')']) => (tt::Delimiter::Parenthesis, true),
165 (T!['{'], T!['}']) => (tt::Delimiter::Brace, true), 191 (T!['{'], T!['}']) => (tt::Delimiter::Brace, true),
@@ -363,6 +389,7 @@ mod tests {
363 use super::*; 389 use super::*;
364 use crate::tests::{create_rules, expand}; 390 use crate::tests::{create_rules, expand};
365 use ra_parser::TokenSource; 391 use ra_parser::TokenSource;
392 use ra_syntax::algo::{insert_children, InsertPosition};
366 393
367 #[test] 394 #[test]
368 fn convert_tt_token_source() { 395 fn convert_tt_token_source() {
@@ -423,4 +450,45 @@ mod tests {
423 let expansion = expand(&rules, "stmts!();"); 450 let expansion = expand(&rules, "stmts!();");
424 assert!(token_tree_to_syntax_node(&expansion, FragmentKind::Expr).is_err()); 451 assert!(token_tree_to_syntax_node(&expansion, FragmentKind::Expr).is_err());
425 } 452 }
453
454 #[test]
455 fn test_token_tree_last_child_is_white_space() {
456 let source_file = ast::SourceFile::parse("f!({} );").ok().unwrap();
457 let macro_call = source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();
458 let token_tree = macro_call.token_tree().unwrap();
459
460 // Token Tree now is :
461 // TokenTree
462 // - T!['(']
463 // - TokenTree
464 // - T!['{']
465 // - T!['}']
466 // - WHITE_SPACE
467 // - T![')']
468
469 let rbrace =
470 token_tree.syntax().descendants_with_tokens().find(|it| it.kind() == T!['}']).unwrap();
471 let space = token_tree
472 .syntax()
473 .descendants_with_tokens()
474 .find(|it| it.kind() == SyntaxKind::WHITESPACE)
475 .unwrap();
476
477 // reorder th white space, such that the white is inside the inner token-tree.
478 let token_tree = insert_children(
479 &rbrace.parent().unwrap(),
480 InsertPosition::Last,
481 &mut std::iter::once(space),
482 );
483
484 // Token Tree now is :
485 // TokenTree
486 // - T!['{']
487 // - T!['}']
488 // - WHITE_SPACE
489 let token_tree = ast::TokenTree::cast(token_tree).unwrap();
490 let tt = ast_to_token_tree(&token_tree).unwrap().0;
491
492 assert_eq!(tt.delimiter, tt::Delimiter::Brace);
493 }
426} 494}