aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-01-26 21:52:04 +0000
committerFlorian Diebold <[email protected]>2019-02-01 21:45:23 +0000
commit6b076f1931d7dc324d7bbbc4c1df9f7c1c1db8b7 (patch)
tree131f12f5b0c9ea0ea499b8d4e9ff0c5112192352 /crates/ra_hir/src
parent758bc72873efe36f579236d1abf240d14866fd82 (diff)
Use new Resolver API in type inference
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/code_model_api.rs39
-rw-r--r--crates/ra_hir/src/expr.rs3
-rw-r--r--crates/ra_hir/src/impl_block.rs27
-rw-r--r--crates/ra_hir/src/lib.rs4
-rw-r--r--crates/ra_hir/src/nameres.rs23
-rw-r--r--crates/ra_hir/src/nameres/tests.rs3
-rw-r--r--crates/ra_hir/src/resolve.rs116
-rw-r--r--crates/ra_hir/src/ty.rs270
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs30
-rw-r--r--crates/ra_hir/src/ty/snapshots/tests__infer_function_generics.snap8
-rw-r--r--crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap8
-rw-r--r--crates/ra_hir/src/ty/snapshots/tests__infer_type_param.snap14
12 files changed, 295 insertions, 250 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index b8ca04c5c..92ab0f692 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -5,7 +5,7 @@ use ra_db::{CrateId, FileId};
5use ra_syntax::{ast::self, TreeArc, SyntaxNode}; 5use ra_syntax::{ast::self, TreeArc, SyntaxNode};
6 6
7use crate::{ 7use crate::{
8 Name, Path, PerNs, ScopesWithSyntaxMapping, Ty, HirFileId, 8 Name, ScopesWithSyntaxMapping, Ty, HirFileId,
9 type_ref::TypeRef, 9 type_ref::TypeRef,
10 nameres::{ModuleScope, lower::ImportId}, 10 nameres::{ModuleScope, lower::ImportId},
11 HirDatabase, PersistentHirDatabase, 11 HirDatabase, PersistentHirDatabase,
@@ -175,18 +175,13 @@ impl Module {
175 db.item_map(self.krate)[self.module_id].clone() 175 db.item_map(self.krate)[self.module_id].clone()
176 } 176 }
177 177
178 pub fn resolve_path(&self, db: &impl PersistentHirDatabase, path: &Path) -> PerNs<ModuleDef> {
179 // TODO replace by Resolver::resolve_path
180 db.item_map(self.krate).resolve_path(db, *self, path)
181 }
182
183 pub fn problems(&self, db: &impl HirDatabase) -> Vec<(TreeArc<SyntaxNode>, Problem)> { 178 pub fn problems(&self, db: &impl HirDatabase) -> Vec<(TreeArc<SyntaxNode>, Problem)> {
184 self.problems_impl(db) 179 self.problems_impl(db)
185 } 180 }
186 181
187 pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { 182 pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
188 let item_map = db.item_map(self.krate); 183 let item_map = db.item_map(self.krate);
189 Resolver::default().push_module_scope(item_map, self.module_id) 184 Resolver::default().push_module_scope(item_map, *self)
190 } 185 }
191} 186}
192 187
@@ -289,6 +284,21 @@ impl Struct {
289 pub fn ty(&self, db: &impl HirDatabase) -> Ty { 284 pub fn ty(&self, db: &impl HirDatabase) -> Ty {
290 db.type_for_def((*self).into()) 285 db.type_for_def((*self).into())
291 } 286 }
287
288 // TODO move to a more general type
289 /// Builds a resolver for type references inside this struct.
290 pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
291 // take the outer scope...
292 let r = self.module(db).resolver(db);
293 // ...and add generic params, if present
294 let p = self.generic_params(db);
295 let r = if !p.params.is_empty() {
296 r.push_generic_params_scope(p)
297 } else {
298 r
299 };
300 r
301 }
292} 302}
293 303
294impl Docs for Struct { 304impl Docs for Struct {
@@ -338,6 +348,21 @@ impl Enum {
338 pub fn ty(&self, db: &impl HirDatabase) -> Ty { 348 pub fn ty(&self, db: &impl HirDatabase) -> Ty {
339 db.type_for_def((*self).into()) 349 db.type_for_def((*self).into())
340 } 350 }
351
352 // TODO move to a more general type
353 /// Builds a resolver for type references inside this struct.
354 pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
355 // take the outer scope...
356 let r = self.module(db).resolver(db);
357 // ...and add generic params, if present
358 let p = self.generic_params(db);
359 let r = if !p.params.is_empty() {
360 r.push_generic_params_scope(p)
361 } else {
362 r
363 };
364 r
365 }
341} 366}
342 367
343impl Docs for Enum { 368impl Docs for Enum {
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index c09d3fbf9..503a09f25 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -75,9 +75,6 @@ impl Body {
75#[allow(dead_code)] 75#[allow(dead_code)]
76pub fn resolver_for_expr(body: Arc<Body>, db: &impl HirDatabase, expr_id: ExprId) -> Resolver { 76pub fn resolver_for_expr(body: Arc<Body>, db: &impl HirDatabase, expr_id: ExprId) -> Resolver {
77 let mut r = body.owner.resolver(db); 77 let mut r = body.owner.resolver(db);
78 if !body.params.is_empty() {
79 r = r.push_function_params(Arc::clone(&body));
80 }
81 let scopes = db.expr_scopes(body.owner); 78 let scopes = db.expr_scopes(body.owner);
82 let scope_chain = scopes.scope_chain_for(expr_id).collect::<Vec<_>>(); 79 let scope_chain = scopes.scope_chain_for(expr_id).collect::<Vec<_>>();
83 for scope in scope_chain.into_iter().rev() { 80 for scope in scope_chain.into_iter().rev() {
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index 5fa49d456..a3908048b 100644
--- a/crates/ra_hir/src/impl_block.rs
+++ b/crates/ra_hir/src/impl_block.rs
@@ -7,13 +7,13 @@ use ra_syntax::{
7ast::{self, AstNode}}; 7ast::{self, AstNode}};
8 8
9use crate::{ 9use crate::{
10 Const, Type, 10 Const, Type, Function, HirFileId,
11 Function, HirFileId, 11 HirDatabase, PersistentHirDatabase,
12 HirDatabase, 12 ModuleDef, Trait, Resolution,
13 PersistentHirDatabase,
14 type_ref::TypeRef, 13 type_ref::TypeRef,
15 ids::LocationCtx, 14 ids::LocationCtx,
16 resolve::Resolver, 15 resolve::Resolver,
16 ty::Ty,
17}; 17};
18 18
19use crate::code_model_api::{Module, ModuleSource}; 19use crate::code_model_api::{Module, ModuleSource};
@@ -75,7 +75,7 @@ impl ImplBlock {
75 self.module_impl_blocks.module.clone() 75 self.module_impl_blocks.module.clone()
76 } 76 }
77 77
78 pub fn target_trait(&self) -> Option<&TypeRef> { 78 pub fn target_trait_ref(&self) -> Option<&TypeRef> {
79 self.impl_data().target_trait() 79 self.impl_data().target_trait()
80 } 80 }
81 81
@@ -83,6 +83,23 @@ impl ImplBlock {
83 self.impl_data().target_type() 83 self.impl_data().target_type()
84 } 84 }
85 85
86 pub fn target_ty(&self, db: &impl HirDatabase) -> Ty {
87 Ty::from_hir(db, &self.resolver(db), self.target_type())
88 }
89
90 pub fn target_trait(&self, db: &impl HirDatabase) -> Option<Trait> {
91 if let Some(TypeRef::Path(path)) = self.target_trait_ref() {
92 let resolver = self.resolver(db);
93 if let Some(Resolution::Def {
94 def: ModuleDef::Trait(tr),
95 }) = resolver.resolve_path(db, path).take_types()
96 {
97 return Some(tr);
98 }
99 }
100 None
101 }
102
86 pub fn items(&self) -> &[ImplItem] { 103 pub fn items(&self) -> &[ImplItem] {
87 self.impl_data().items() 104 self.impl_data().items()
88 } 105 }
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index e58658378..54da55598 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -55,13 +55,13 @@ pub use self::{
55 name::Name, 55 name::Name,
56 ids::{HirFileId, MacroCallId, MacroCallLoc, HirInterner}, 56 ids::{HirFileId, MacroCallId, MacroCallLoc, HirInterner},
57 macros::{MacroDef, MacroInput, MacroExpansion}, 57 macros::{MacroDef, MacroInput, MacroExpansion},
58 nameres::{ItemMap, PerNs, Namespace, Resolution}, 58 nameres::{ItemMap, PerNs, Namespace},
59 ty::Ty, 59 ty::Ty,
60 impl_block::{ImplBlock, ImplItem}, 60 impl_block::{ImplBlock, ImplItem},
61 docs::{Docs, Documentation}, 61 docs::{Docs, Documentation},
62 adt::AdtDef, 62 adt::AdtDef,
63 expr::{ExprScopes, ScopesWithSyntaxMapping}, 63 expr::{ExprScopes, ScopesWithSyntaxMapping},
64 resolve::Resolver, 64 resolve::{Resolver, Resolution},
65}; 65};
66 66
67pub use self::code_model_api::{ 67pub use self::code_model_api::{
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index e825ec089..193c6a977 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -24,8 +24,9 @@ use rustc_hash::{FxHashMap, FxHashSet};
24 24
25use crate::{ 25use crate::{
26 Module, ModuleDef, 26 Module, ModuleDef,
27 Path, PathKind, Crate, 27 Path, PathKind, PersistentHirDatabase,
28 Name, PersistentHirDatabase, 28 Crate,
29 Name,
29 module_tree::{ModuleId, ModuleTree}, 30 module_tree::{ModuleId, ModuleTree},
30 nameres::lower::{ImportId, LoweredModule, ImportData}, 31 nameres::lower::{ImportId, LoweredModule, ImportData},
31}; 32};
@@ -46,7 +47,7 @@ impl std::ops::Index<ModuleId> for ItemMap {
46 47
47#[derive(Debug, Default, PartialEq, Eq, Clone)] 48#[derive(Debug, Default, PartialEq, Eq, Clone)]
48pub struct ModuleScope { 49pub struct ModuleScope {
49 items: FxHashMap<Name, Resolution>, 50 pub(crate) items: FxHashMap<Name, Resolution>,
50} 51}
51 52
52impl ModuleScope { 53impl ModuleScope {
@@ -113,6 +114,10 @@ impl<T> PerNs<T> {
113 self.types.is_none() && self.values.is_none() 114 self.types.is_none() && self.values.is_none()
114 } 115 }
115 116
117 pub fn is_both(&self) -> bool {
118 self.types.is_some() && self.values.is_some()
119 }
120
116 pub fn take(self, namespace: Namespace) -> Option<T> { 121 pub fn take(self, namespace: Namespace) -> Option<T> {
117 match namespace { 122 match namespace {
118 Namespace::Types => self.types, 123 Namespace::Types => self.types,
@@ -139,6 +144,13 @@ impl<T> PerNs<T> {
139 } 144 }
140 } 145 }
141 146
147 pub fn combine(self, other: PerNs<T>) -> PerNs<T> {
148 PerNs {
149 types: self.types.or(other.types),
150 values: self.values.or(other.values),
151 }
152 }
153
142 pub fn and_then<U>(self, f: impl Fn(T) -> Option<U>) -> PerNs<U> { 154 pub fn and_then<U>(self, f: impl Fn(T) -> Option<U>) -> PerNs<U> {
143 PerNs { 155 PerNs {
144 types: self.types.and_then(&f), 156 types: self.types.and_then(&f),
@@ -402,10 +414,11 @@ impl ItemMap {
402 if module.krate != original_module.krate { 414 if module.krate != original_module.krate {
403 let path = Path { 415 let path = Path {
404 segments: path.segments[i..].iter().cloned().collect(), 416 segments: path.segments[i..].iter().cloned().collect(),
405 kind: PathKind::Crate, 417 kind: PathKind::Self_,
406 }; 418 };
407 log::debug!("resolving {:?} in other crate", path); 419 log::debug!("resolving {:?} in other crate", path);
408 let def = module.resolve_path(db, &path); 420 let item_map = db.item_map(module.krate);
421 let def = item_map.resolve_path(db, *module, &path);
409 return (def, ReachedFixedPoint::Yes); 422 return (def, ReachedFixedPoint::Yes);
410 } 423 }
411 424
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs
index 1ce7bd146..0e0683db7 100644
--- a/crates/ra_hir/src/nameres/tests.rs
+++ b/crates/ra_hir/src/nameres/tests.rs
@@ -5,11 +5,12 @@ use relative_path::RelativePath;
5use test_utils::{assert_eq_text, covers}; 5use test_utils::{assert_eq_text, covers};
6 6
7use crate::{ 7use crate::{
8 ItemMap, Resolution, 8 ItemMap,
9 PersistentHirDatabase, 9 PersistentHirDatabase,
10 mock::MockDatabase, 10 mock::MockDatabase,
11 module_tree::ModuleId, 11 module_tree::ModuleId,
12}; 12};
13use super::Resolution;
13 14
14fn item_map(fixture: &str) -> (Arc<ItemMap>, ModuleId) { 15fn item_map(fixture: &str) -> (Arc<ItemMap>, ModuleId) {
15 let (db, pos) = MockDatabase::with_position(fixture); 16 let (db, pos) = MockDatabase::with_position(fixture);
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
index b7fbf6df2..36daed65b 100644
--- a/crates/ra_hir/src/resolve.rs
+++ b/crates/ra_hir/src/resolve.rs
@@ -1,30 +1,29 @@
1#![allow(unused_variables, dead_code)]
2//! Name resolution. 1//! Name resolution.
3use std::sync::Arc; 2use std::sync::Arc;
4 3
5use rustc_hash::FxHashMap; 4use rustc_hash::FxHashMap;
6 5
7use crate::{ 6use crate::{
8 ModuleDef, 7 ModuleDef, Module,
9 name::Name, 8 db::HirDatabase,
10 nameres::{PerNs, lower::ImportId, ItemMap}, 9 name::{Name, KnownName},
11 module_tree::ModuleId, 10 nameres::{PerNs, ItemMap},
12 generics::GenericParams, 11 generics::GenericParams,
13 expr::{Body, scope::{ExprScopes, ScopeId}, PatId}, 12 expr::{scope::{ExprScopes, ScopeId}, PatId},
14 impl_block::ImplBlock, 13 impl_block::ImplBlock,
15 path::Path, 14 path::Path,
16}; 15};
17 16
18#[derive(Debug, Clone, Default)] 17#[derive(Debug, Clone, Default)]
19pub struct Resolver { 18pub struct Resolver {
20 scopes: Vec<Scope>, // maybe a 'linked list' of scopes? or allow linking a Resolver to a parent Resolver? that's an optimization that might not be necessary, though 19 scopes: Vec<Scope>,
21} 20}
22 21
23// TODO how to store these best 22// TODO how to store these best
24#[derive(Debug, Clone)] 23#[derive(Debug, Clone)]
25pub(crate) struct ModuleItemMap { 24pub(crate) struct ModuleItemMap {
26 item_map: Arc<ItemMap>, 25 item_map: Arc<ItemMap>,
27 module_id: ModuleId, 26 module: Module,
28} 27}
29 28
30#[derive(Debug, Clone)] 29#[derive(Debug, Clone)]
@@ -39,8 +38,6 @@ pub(crate) enum Scope {
39 ModuleScope(ModuleItemMap), 38 ModuleScope(ModuleItemMap),
40 /// Brings the generic parameters of an item into scope 39 /// Brings the generic parameters of an item into scope
41 GenericParams(Arc<GenericParams>), 40 GenericParams(Arc<GenericParams>),
42 /// Brings the function parameters into scope
43 FunctionParams(Arc<Body>),
44 /// Brings `Self` into scope 41 /// Brings `Self` into scope
45 ImplBlockScope(ImplBlock), 42 ImplBlockScope(ImplBlock),
46 /// Local bindings 43 /// Local bindings
@@ -49,36 +46,64 @@ pub(crate) enum Scope {
49 46
50#[derive(Debug, Clone, PartialEq, Eq)] 47#[derive(Debug, Clone, PartialEq, Eq)]
51pub enum Resolution { 48pub enum Resolution {
49 // FIXME make these tuple variants
52 /// An item 50 /// An item
53 Def { 51 Def {
54 def: ModuleDef, 52 def: ModuleDef,
55 import: Option<ImportId>,
56 }, 53 },
57 /// A local binding (only value namespace) 54 /// A local binding (only value namespace)
58 LocalBinding { pat: PatId }, 55 LocalBinding {
56 pat: PatId,
57 },
59 /// A generic parameter 58 /// A generic parameter
60 GenericParam { idx: u32 }, 59 GenericParam {
61 // TODO how does `Self` resolve? 60 idx: u32,
61 },
62 SelfType(ImplBlock),
62} 63}
63 64
64impl Resolver { 65impl Resolver {
65 pub fn resolve_name(&self, name: &Name) -> PerNs<Resolution> { 66 pub fn resolve_name(&self, name: &Name) -> PerNs<Resolution> {
67 let mut resolution = PerNs::none();
66 for scope in self.scopes.iter().rev() { 68 for scope in self.scopes.iter().rev() {
67 let resolution = scope.resolve_name(name); 69 resolution = resolution.combine(scope.resolve_name(name));
68 if !resolution.is_none() { 70 if resolution.is_both() {
69 return resolution; 71 return resolution;
70 } 72 }
71 } 73 }
72 PerNs::none() 74 resolution
73 } 75 }
74 76
75 pub fn resolve_path(&self, path: &Path) -> PerNs<Resolution> { 77 pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs<Resolution> {
76 unimplemented!() 78 if let Some(name) = path.as_ident() {
79 self.resolve_name(name)
80 } else if path.is_self() {
81 self.resolve_name(&Name::self_param())
82 } else {
83 let (item_map, module) = match self.module() {
84 Some(m) => m,
85 _ => return PerNs::none(),
86 };
87 let module_res = item_map.resolve_path(db, module, path);
88 module_res.map(|def| Resolution::Def { def })
89 }
77 } 90 }
78 91
79 pub fn all_names(&self) -> FxHashMap<Name, Resolution> { 92 pub fn all_names(&self) -> FxHashMap<Name, Resolution> {
80 unimplemented!() 93 unimplemented!()
81 } 94 }
95
96 fn module(&self) -> Option<(&ItemMap, Module)> {
97 for scope in self.scopes.iter().rev() {
98 match scope {
99 Scope::ModuleScope(m) => {
100 return Some((&m.item_map, m.module.clone()));
101 }
102 _ => {}
103 }
104 }
105 None
106 }
82} 107}
83 108
84impl Resolver { 109impl Resolver {
@@ -95,11 +120,8 @@ impl Resolver {
95 self.push_scope(Scope::ImplBlockScope(impl_block)) 120 self.push_scope(Scope::ImplBlockScope(impl_block))
96 } 121 }
97 122
98 pub(crate) fn push_module_scope(self, item_map: Arc<ItemMap>, module_id: ModuleId) -> Resolver { 123 pub(crate) fn push_module_scope(self, item_map: Arc<ItemMap>, module: Module) -> Resolver {
99 self.push_scope(Scope::ModuleScope(ModuleItemMap { 124 self.push_scope(Scope::ModuleScope(ModuleItemMap { item_map, module }))
100 item_map,
101 module_id,
102 }))
103 } 125 }
104 126
105 pub(crate) fn push_expr_scope( 127 pub(crate) fn push_expr_scope(
@@ -112,19 +134,45 @@ impl Resolver {
112 scope_id, 134 scope_id,
113 })) 135 }))
114 } 136 }
115
116 pub(crate) fn push_function_params(self, body: Arc<Body>) -> Resolver {
117 self.push_scope(Scope::FunctionParams(body))
118 }
119
120 pub(crate) fn pop_scope(mut self) -> Resolver {
121 self.scopes.pop();
122 self
123 }
124} 137}
125 138
126impl Scope { 139impl Scope {
127 fn resolve_name(&self, name: &Name) -> PerNs<Resolution> { 140 fn resolve_name(&self, name: &Name) -> PerNs<Resolution> {
128 unimplemented!() 141 match self {
142 Scope::ModuleScope(m) => {
143 if let Some(KnownName::SelfParam) = name.as_known_name() {
144 PerNs::types(Resolution::Def {
145 def: m.module.into(),
146 })
147 } else {
148 match m.item_map[m.module.module_id].get(name) {
149 Some(res) => res.def.map(|def| Resolution::Def { def }),
150 None => PerNs::none(),
151 }
152 }
153 }
154 Scope::GenericParams(gp) => match gp.find_by_name(name) {
155 Some(gp) => PerNs::types(Resolution::GenericParam { idx: gp.idx }),
156 None => PerNs::none(),
157 },
158 Scope::ImplBlockScope(i) => {
159 if name.as_known_name() == Some(KnownName::SelfType) {
160 PerNs::types(Resolution::SelfType(i.clone()))
161 } else {
162 PerNs::none()
163 }
164 }
165 Scope::ExprScope(e) => {
166 let entry = e
167 .expr_scopes
168 .entries(e.scope_id)
169 .iter()
170 .find(|entry| entry.name() == name);
171 match entry {
172 Some(e) => PerNs::values(Resolution::LocalBinding { pat: e.pat() }),
173 None => PerNs::none(),
174 }
175 }
176 }
129 } 177 }
130} 178}
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index d3e31981a..d9c62f84c 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -33,15 +33,16 @@ use rustc_hash::FxHashMap;
33use test_utils::tested_by; 33use test_utils::tested_by;
34 34
35use crate::{ 35use crate::{
36 Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock, 36 Function, Struct, StructField, Enum, EnumVariant, Path, Name,
37 FnSignature, ExprScopes, ModuleDef, AdtDef, 37 FnSignature, ModuleDef, AdtDef,
38 HirDatabase, 38 HirDatabase,
39 type_ref::{TypeRef, Mutability}, 39 type_ref::{TypeRef, Mutability},
40 name::KnownName, 40 name::KnownName,
41 expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat}, 41 expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat, self},
42 generics::GenericParams, 42 generics::GenericParams,
43 path::GenericArg, 43 path::GenericArg,
44 adt::VariantDef, 44 adt::VariantDef,
45 resolve::{Resolver, Resolution},
45}; 46};
46 47
47/// The ID of a type variable. 48/// The ID of a type variable.
@@ -300,47 +301,38 @@ pub struct FnSig {
300} 301}
301 302
302impl Ty { 303impl Ty {
303 pub(crate) fn from_hir( 304 pub(crate) fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self {
304 db: &impl HirDatabase,
305 // TODO: the next three parameters basically describe the scope for name
306 // resolution; this should be refactored into something like a general
307 // resolver architecture
308 module: &Module,
309 impl_block: Option<&ImplBlock>,
310 generics: &GenericParams,
311 type_ref: &TypeRef,
312 ) -> Self {
313 match type_ref { 305 match type_ref {
314 TypeRef::Never => Ty::Never, 306 TypeRef::Never => Ty::Never,
315 TypeRef::Tuple(inner) => { 307 TypeRef::Tuple(inner) => {
316 let inner_tys = inner 308 let inner_tys = inner
317 .iter() 309 .iter()
318 .map(|tr| Ty::from_hir(db, module, impl_block, generics, tr)) 310 .map(|tr| Ty::from_hir(db, resolver, tr))
319 .collect::<Vec<_>>(); 311 .collect::<Vec<_>>();
320 Ty::Tuple(inner_tys.into()) 312 Ty::Tuple(inner_tys.into())
321 } 313 }
322 TypeRef::Path(path) => Ty::from_hir_path(db, module, impl_block, generics, path), 314 TypeRef::Path(path) => Ty::from_hir_path(db, resolver, path),
323 TypeRef::RawPtr(inner, mutability) => { 315 TypeRef::RawPtr(inner, mutability) => {
324 let inner_ty = Ty::from_hir(db, module, impl_block, generics, inner); 316 let inner_ty = Ty::from_hir(db, resolver, inner);
325 Ty::RawPtr(Arc::new(inner_ty), *mutability) 317 Ty::RawPtr(Arc::new(inner_ty), *mutability)
326 } 318 }
327 TypeRef::Array(inner) => { 319 TypeRef::Array(inner) => {
328 let inner_ty = Ty::from_hir(db, module, impl_block, generics, inner); 320 let inner_ty = Ty::from_hir(db, resolver, inner);
329 Ty::Array(Arc::new(inner_ty)) 321 Ty::Array(Arc::new(inner_ty))
330 } 322 }
331 TypeRef::Slice(inner) => { 323 TypeRef::Slice(inner) => {
332 let inner_ty = Ty::from_hir(db, module, impl_block, generics, inner); 324 let inner_ty = Ty::from_hir(db, resolver, inner);
333 Ty::Slice(Arc::new(inner_ty)) 325 Ty::Slice(Arc::new(inner_ty))
334 } 326 }
335 TypeRef::Reference(inner, mutability) => { 327 TypeRef::Reference(inner, mutability) => {
336 let inner_ty = Ty::from_hir(db, module, impl_block, generics, inner); 328 let inner_ty = Ty::from_hir(db, resolver, inner);
337 Ty::Ref(Arc::new(inner_ty), *mutability) 329 Ty::Ref(Arc::new(inner_ty), *mutability)
338 } 330 }
339 TypeRef::Placeholder => Ty::Unknown, 331 TypeRef::Placeholder => Ty::Unknown,
340 TypeRef::Fn(params) => { 332 TypeRef::Fn(params) => {
341 let mut inner_tys = params 333 let mut inner_tys = params
342 .iter() 334 .iter()
343 .map(|tr| Ty::from_hir(db, module, impl_block, generics, tr)) 335 .map(|tr| Ty::from_hir(db, resolver, tr))
344 .collect::<Vec<_>>(); 336 .collect::<Vec<_>>();
345 let return_ty = inner_tys 337 let return_ty = inner_tys
346 .pop() 338 .pop()
@@ -355,40 +347,13 @@ impl Ty {
355 } 347 }
356 } 348 }
357 349
358 pub(crate) fn from_hir_opt( 350 pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Self {
359 db: &impl HirDatabase,
360 module: &Module,
361 impl_block: Option<&ImplBlock>,
362 generics: &GenericParams,
363 type_ref: Option<&TypeRef>,
364 ) -> Self {
365 type_ref.map_or(Ty::Unknown, |t| {
366 Ty::from_hir(db, module, impl_block, generics, t)
367 })
368 }
369
370 pub(crate) fn from_hir_path(
371 db: &impl HirDatabase,
372 module: &Module,
373 impl_block: Option<&ImplBlock>,
374 generics: &GenericParams,
375 path: &Path,
376 ) -> Self {
377 if let Some(name) = path.as_ident() { 351 if let Some(name) = path.as_ident() {
352 // TODO handle primitive type names in resolver as well?
378 if let Some(int_ty) = primitive::UncertainIntTy::from_name(name) { 353 if let Some(int_ty) = primitive::UncertainIntTy::from_name(name) {
379 return Ty::Int(int_ty); 354 return Ty::Int(int_ty);
380 } else if let Some(float_ty) = primitive::UncertainFloatTy::from_name(name) { 355 } else if let Some(float_ty) = primitive::UncertainFloatTy::from_name(name) {
381 return Ty::Float(float_ty); 356 return Ty::Float(float_ty);
382 } else if name.as_known_name() == Some(KnownName::SelfType) {
383 // TODO pass the impl block's generics?
384 let generics = &GenericParams::default();
385 return Ty::from_hir_opt(
386 db,
387 module,
388 None,
389 generics,
390 impl_block.map(|i| i.target_type()),
391 );
392 } else if let Some(known) = name.as_known_name() { 357 } else if let Some(known) = name.as_known_name() {
393 match known { 358 match known {
394 KnownName::Bool => return Ty::Bool, 359 KnownName::Bool => return Ty::Bool,
@@ -396,25 +361,40 @@ impl Ty {
396 KnownName::Str => return Ty::Str, 361 KnownName::Str => return Ty::Str,
397 _ => {} 362 _ => {}
398 } 363 }
399 } else if let Some(generic_param) = generics.find_by_name(&name) { 364 }
365 }
366
367 // Resolve the path (in type namespace)
368 let resolution = resolver.resolve_path(db, path).take_types();
369
370 let def = match resolution {
371 Some(Resolution::Def { def, .. }) => def,
372 Some(Resolution::LocalBinding { .. }) => {
373 // this should never happen
374 panic!("path resolved to local binding in type ns");
375 }
376 Some(Resolution::GenericParam { idx }) => {
400 return Ty::Param { 377 return Ty::Param {
401 idx: generic_param.idx, 378 idx,
402 name: generic_param.name.clone(), 379 // TODO: maybe return name in resolution?
380 name: path
381 .as_ident()
382 .expect("generic param should be single-segment path")
383 .clone(),
403 }; 384 };
404 } 385 }
405 } 386 Some(Resolution::SelfType(impl_block)) => {
387 return impl_block.target_ty(db);
388 }
389 None => return Ty::Unknown,
390 };
406 391
407 // Resolve in module (in type namespace) 392 let typable: TypableDef = match def.into() {
408 let typable: TypableDef = match module
409 .resolve_path(db, path)
410 .take_types()
411 .and_then(|it| it.into())
412 {
413 None => return Ty::Unknown, 393 None => return Ty::Unknown,
414 Some(it) => it, 394 Some(it) => it,
415 }; 395 };
416 let ty = db.type_for_def(typable); 396 let ty = db.type_for_def(typable);
417 let substs = Ty::substs_from_path(db, module, impl_block, generics, path, typable); 397 let substs = Ty::substs_from_path(db, resolver, path, typable);
418 ty.apply_substs(substs) 398 ty.apply_substs(substs)
419 } 399 }
420 400
@@ -422,10 +402,7 @@ impl Ty {
422 /// `create_substs_for_ast_path` and `def_to_ty` in rustc. 402 /// `create_substs_for_ast_path` and `def_to_ty` in rustc.
423 fn substs_from_path( 403 fn substs_from_path(
424 db: &impl HirDatabase, 404 db: &impl HirDatabase,
425 // the scope of the segment... 405 resolver: &Resolver,
426 module: &Module,
427 impl_block: Option<&ImplBlock>,
428 outer_generics: &GenericParams,
429 path: &Path, 406 path: &Path,
430 resolved: TypableDef, 407 resolved: TypableDef,
431 ) -> Substs { 408 ) -> Substs {
@@ -462,7 +439,7 @@ impl Ty {
462 for arg in generic_args.args.iter().take(param_count) { 439 for arg in generic_args.args.iter().take(param_count) {
463 match arg { 440 match arg {
464 GenericArg::Type(type_ref) => { 441 GenericArg::Type(type_ref) => {
465 let ty = Ty::from_hir(db, module, impl_block, outer_generics, type_ref); 442 let ty = Ty::from_hir(db, resolver, type_ref);
466 substs.push(ty); 443 substs.push(ty);
467 } 444 }
468 } 445 }
@@ -666,24 +643,17 @@ impl fmt::Display for Ty {
666/// function body. 643/// function body.
667fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { 644fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
668 let signature = def.signature(db); 645 let signature = def.signature(db);
669 let module = def.module(db); 646 let resolver = def.resolver(db);
670 let impl_block = def.impl_block(db);
671 let generics = def.generic_params(db); 647 let generics = def.generic_params(db);
648 let name = def.name(db);
672 let input = signature 649 let input = signature
673 .params() 650 .params()
674 .iter() 651 .iter()
675 .map(|tr| Ty::from_hir(db, &module, impl_block.as_ref(), &generics, tr)) 652 .map(|tr| Ty::from_hir(db, &resolver, tr))
676 .collect::<Vec<_>>(); 653 .collect::<Vec<_>>();
677 let output = Ty::from_hir( 654 let output = Ty::from_hir(db, &resolver, signature.ret_type());
678 db,
679 &module,
680 impl_block.as_ref(),
681 &generics,
682 signature.ret_type(),
683 );
684 let sig = Arc::new(FnSig { input, output }); 655 let sig = Arc::new(FnSig { input, output });
685 let substs = make_substs(&generics); 656 let substs = make_substs(&generics);
686 let name = def.name(db);
687 Ty::FnDef { 657 Ty::FnDef {
688 def, 658 def,
689 sig, 659 sig,
@@ -764,13 +734,13 @@ pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef) -> Ty {
764 734
765pub(super) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { 735pub(super) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty {
766 let parent_def = field.parent_def(db); 736 let parent_def = field.parent_def(db);
767 let (generics, module) = match parent_def { 737 let resolver = match parent_def {
768 VariantDef::Struct(it) => (it.generic_params(db), it.module(db)), 738 VariantDef::Struct(it) => it.resolver(db),
769 VariantDef::EnumVariant(it) => (it.parent_enum(db).generic_params(db), it.module(db)), 739 VariantDef::EnumVariant(it) => it.parent_enum(db).resolver(db),
770 }; 740 };
771 let var_data = parent_def.variant_data(db); 741 let var_data = parent_def.variant_data(db);
772 let type_ref = &var_data.fields().unwrap()[field.id].type_ref; 742 let type_ref = &var_data.fields().unwrap()[field.id].type_ref;
773 Ty::from_hir(db, &module, None, &generics, type_ref) 743 Ty::from_hir(db, &resolver, type_ref)
774} 744}
775 745
776/// The result of type inference: A mapping from expressions and patterns to types. 746/// The result of type inference: A mapping from expressions and patterns to types.
@@ -814,9 +784,7 @@ impl Index<PatId> for InferenceResult {
814struct InferenceContext<'a, D: HirDatabase> { 784struct InferenceContext<'a, D: HirDatabase> {
815 db: &'a D, 785 db: &'a D,
816 body: Arc<Body>, 786 body: Arc<Body>,
817 scopes: Arc<ExprScopes>, 787 resolver: Resolver,
818 module: Module,
819 impl_block: Option<ImplBlock>,
820 var_unification_table: InPlaceUnificationTable<TypeVarId>, 788 var_unification_table: InPlaceUnificationTable<TypeVarId>,
821 method_resolutions: FxHashMap<ExprId, Function>, 789 method_resolutions: FxHashMap<ExprId, Function>,
822 field_resolutions: FxHashMap<ExprId, StructField>, 790 field_resolutions: FxHashMap<ExprId, StructField>,
@@ -905,13 +873,7 @@ fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
905} 873}
906 874
907impl<'a, D: HirDatabase> InferenceContext<'a, D> { 875impl<'a, D: HirDatabase> InferenceContext<'a, D> {
908 fn new( 876 fn new(db: &'a D, body: Arc<Body>, resolver: Resolver) -> Self {
909 db: &'a D,
910 body: Arc<Body>,
911 scopes: Arc<ExprScopes>,
912 module: Module,
913 impl_block: Option<ImplBlock>,
914 ) -> Self {
915 InferenceContext { 877 InferenceContext {
916 method_resolutions: FxHashMap::default(), 878 method_resolutions: FxHashMap::default(),
917 field_resolutions: FxHashMap::default(), 879 field_resolutions: FxHashMap::default(),
@@ -921,9 +883,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
921 return_ty: Ty::Unknown, // set in collect_fn_signature 883 return_ty: Ty::Unknown, // set in collect_fn_signature
922 db, 884 db,
923 body, 885 body,
924 scopes, 886 resolver,
925 module,
926 impl_block,
927 } 887 }
928 } 888 }
929 889
@@ -940,8 +900,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
940 *ty = resolved; 900 *ty = resolved;
941 } 901 }
942 InferenceResult { 902 InferenceResult {
943 method_resolutions: mem::replace(&mut self.method_resolutions, Default::default()), 903 method_resolutions: self.method_resolutions,
944 field_resolutions: mem::replace(&mut self.field_resolutions, Default::default()), 904 field_resolutions: self.field_resolutions,
945 type_of_expr: expr_types, 905 type_of_expr: expr_types,
946 type_of_pat: pat_types, 906 type_of_pat: pat_types,
947 } 907 }
@@ -964,13 +924,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
964 } 924 }
965 925
966 fn make_ty(&mut self, type_ref: &TypeRef) -> Ty { 926 fn make_ty(&mut self, type_ref: &TypeRef) -> Ty {
967 // TODO provide generics of function
968 let generics = GenericParams::default();
969 let ty = Ty::from_hir( 927 let ty = Ty::from_hir(
970 self.db, 928 self.db,
971 &self.module, 929 // TODO use right resolver for block
972 self.impl_block.as_ref(), 930 &self.resolver,
973 &generics,
974 type_ref, 931 type_ref,
975 ); 932 );
976 let ty = self.insert_type_vars(ty); 933 let ty = self.insert_type_vars(ty);
@@ -1147,38 +1104,31 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1147 }) 1104 })
1148 } 1105 }
1149 1106
1150 fn infer_path_expr(&mut self, expr: ExprId, path: &Path) -> Option<Ty> { 1107 fn infer_path_expr(&mut self, resolver: &Resolver, path: &Path) -> Option<Ty> {
1151 if path.is_ident() || path.is_self() { 1108 let resolved = resolver.resolve_path(self.db, &path).take_values()?;
1152 // resolve locally 1109 match resolved {
1153 let name = path.as_ident().cloned().unwrap_or_else(Name::self_param); 1110 Resolution::Def { def, .. } => {
1154 if let Some(scope_entry) = self.scopes.resolve_local_name(expr, name) { 1111 let typable: Option<TypableDef> = def.into();
1155 let ty = self.type_of_pat.get(scope_entry.pat())?; 1112 let typable = typable?;
1113 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable);
1114 let ty = self.db.type_for_def(typable).apply_substs(substs);
1115 let ty = self.insert_type_vars(ty);
1116 Some(ty)
1117 }
1118 Resolution::LocalBinding { pat } => {
1119 let ty = self.type_of_pat.get(pat)?;
1156 let ty = self.resolve_ty_as_possible(&mut vec![], ty.clone()); 1120 let ty = self.resolve_ty_as_possible(&mut vec![], ty.clone());
1157 return Some(ty); 1121 Some(ty)
1158 }; 1122 }
1159 }; 1123 Resolution::GenericParam { .. } => {
1160 1124 // generic params can't refer to values... yet
1161 // resolve in module 1125 None
1162 let typable: Option<TypableDef> = self 1126 }
1163 .module 1127 Resolution::SelfType(_) => {
1164 .resolve_path(self.db, &path) 1128 log::error!("path expr {:?} resolved to Self type in values ns", path);
1165 .take_values()? 1129 None
1166 .into(); 1130 }
1167 let typable = typable?; 1131 }
1168 let ty = self.db.type_for_def(typable);
1169 let generics = GenericParams::default();
1170 let substs = Ty::substs_from_path(
1171 self.db,
1172 &self.module,
1173 self.impl_block.as_ref(),
1174 &generics,
1175 path,
1176 typable,
1177 );
1178 let ty = ty.apply_substs(substs);
1179 let ty = self.insert_type_vars(ty);
1180
1181 Some(ty)
1182 } 1132 }
1183 1133
1184 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantDef>) { 1134 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantDef>) {
@@ -1186,26 +1136,30 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1186 Some(path) => path, 1136 Some(path) => path,
1187 None => return (Ty::Unknown, None), 1137 None => return (Ty::Unknown, None),
1188 }; 1138 };
1189 let typable: Option<TypableDef> = self 1139 let resolver = &self.resolver;
1190 .module 1140 let typable: Option<TypableDef> = match resolver.resolve_path(self.db, &path).take_types() {
1191 .resolve_path(self.db, &path) 1141 Some(Resolution::Def { def, .. }) => def.into(),
1192 .take_types() 1142 Some(Resolution::LocalBinding { .. }) => {
1193 .and_then(|it| it.into()); 1143 // this cannot happen
1144 log::error!("path resolved to local binding in type ns");
1145 return (Ty::Unknown, None);
1146 }
1147 Some(Resolution::GenericParam { .. }) => {
1148 // generic params can't be used in struct literals
1149 return (Ty::Unknown, None);
1150 }
1151 Some(Resolution::SelfType(..)) => {
1152 // TODO this is allowed in an impl for a struct, handle this
1153 return (Ty::Unknown, None);
1154 }
1155 None => return (Ty::Unknown, None),
1156 };
1194 let def = match typable { 1157 let def = match typable {
1195 None => return (Ty::Unknown, None), 1158 None => return (Ty::Unknown, None),
1196 Some(it) => it, 1159 Some(it) => it,
1197 }; 1160 };
1198 // TODO remove the duplication between here and `Ty::from_path`? 1161 // TODO remove the duplication between here and `Ty::from_path`?
1199 // TODO provide generics of function 1162 let substs = Ty::substs_from_path(self.db, resolver, path, def);
1200 let generics = GenericParams::default();
1201 let substs = Ty::substs_from_path(
1202 self.db,
1203 &self.module,
1204 self.impl_block.as_ref(),
1205 &generics,
1206 path,
1207 def,
1208 );
1209 match def { 1163 match def {
1210 TypableDef::Struct(s) => { 1164 TypableDef::Struct(s) => {
1211 let ty = type_for_struct(self.db, s); 1165 let ty = type_for_struct(self.db, s);
@@ -1303,12 +1257,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1303 path: ref p, 1257 path: ref p,
1304 args: ref fields, 1258 args: ref fields,
1305 } => self.infer_struct_pat(p.as_ref(), fields, expected), 1259 } => self.infer_struct_pat(p.as_ref(), fields, expected),
1306 Pat::Path(path) => self 1260 Pat::Path(path) => {
1307 .module 1261 // TODO use correct resolver for the surrounding expression
1308 .resolve_path(self.db, &path) 1262 let resolver = self.resolver.clone();
1309 .take_values() 1263 self.infer_path_expr(&resolver, &path)
1310 .and_then(|module_def| module_def.into()) 1264 .unwrap_or(Ty::Unknown)
1311 .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)), 1265 }
1312 Pat::Bind { 1266 Pat::Bind {
1313 mode, 1267 mode,
1314 name: _name, 1268 name: _name,
@@ -1496,7 +1450,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1496 1450
1497 expected.ty 1451 expected.ty
1498 } 1452 }
1499 Expr::Path(p) => self.infer_path_expr(tgt_expr, p).unwrap_or(Ty::Unknown), 1453 Expr::Path(p) => {
1454 // TODO this could be more efficient...
1455 let resolver = expr::resolver_for_expr(self.body.clone(), self.db, tgt_expr);
1456 self.infer_path_expr(&resolver, p).unwrap_or(Ty::Unknown)
1457 }
1500 Expr::Continue => Ty::Never, 1458 Expr::Continue => Ty::Never,
1501 Expr::Break { expr } => { 1459 Expr::Break { expr } => {
1502 if let Some(expr) = expr { 1460 if let Some(expr) = expr {
@@ -1730,10 +1688,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1730pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> { 1688pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> {
1731 db.check_canceled(); 1689 db.check_canceled();
1732 let body = func.body(db); 1690 let body = func.body(db);
1733 let scopes = db.expr_scopes(func); 1691 let resolver = func.resolver(db);
1734 let module = func.module(db); 1692 let mut ctx = InferenceContext::new(db, body, resolver);
1735 let impl_block = func.impl_block(db);
1736 let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block);
1737 1693
1738 let signature = func.signature(db); 1694 let signature = func.signature(db);
1739 ctx.collect_fn_signature(&signature); 1695 ctx.collect_fn_signature(&signature);
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index e857d6856..2282286b0 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -7,12 +7,10 @@ use std::sync::Arc;
7use rustc_hash::FxHashMap; 7use rustc_hash::FxHashMap;
8 8
9use crate::{ 9use crate::{
10 HirDatabase, module_tree::ModuleId, Module, ModuleDef, Crate, Name, Function, Trait, 10 HirDatabase, module_tree::ModuleId, Module, Crate, Name, Function, Trait,
11 ids::TraitId, 11 ids::TraitId,
12 impl_block::{ImplId, ImplBlock, ImplItem}, 12 impl_block::{ImplId, ImplBlock, ImplItem},
13 generics::GenericParams,
14 ty::{AdtDef, Ty}, 13 ty::{AdtDef, Ty},
15 type_ref::TypeRef,
16}; 14};
17 15
18/// This is used as a key for indexing impls. 16/// This is used as a key for indexing impls.
@@ -85,17 +83,10 @@ impl CrateImplBlocks {
85 fn collect_recursive(&mut self, db: &impl HirDatabase, module: &Module) { 83 fn collect_recursive(&mut self, db: &impl HirDatabase, module: &Module) {
86 let module_impl_blocks = db.impls_in_module(module.clone()); 84 let module_impl_blocks = db.impls_in_module(module.clone());
87 85
88 for (impl_id, impl_data) in module_impl_blocks.impls.iter() { 86 for (impl_id, _) in module_impl_blocks.impls.iter() {
89 let impl_block = ImplBlock::from_id(Arc::clone(&module_impl_blocks), impl_id); 87 let impl_block = ImplBlock::from_id(Arc::clone(&module_impl_blocks), impl_id);
90 // TODO provide generics of impl 88
91 let generics = GenericParams::default(); 89 let target_ty = impl_block.target_ty(db);
92 let target_ty = Ty::from_hir(
93 db,
94 &module,
95 Some(&impl_block),
96 &generics,
97 impl_data.target_type(),
98 );
99 90
100 if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { 91 if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) {
101 self.impls 92 self.impls
@@ -104,14 +95,11 @@ impl CrateImplBlocks {
104 .push((module.module_id, impl_id)); 95 .push((module.module_id, impl_id));
105 } 96 }
106 97
107 if let Some(TypeRef::Path(path)) = impl_data.target_trait() { 98 if let Some(tr) = impl_block.target_trait(db) {
108 let perns = module.resolve_path(db, path); 99 self.impls_by_trait
109 if let Some(ModuleDef::Trait(tr)) = perns.take_types() { 100 .entry(tr.id)
110 self.impls_by_trait 101 .or_insert_with(Vec::new)
111 .entry(tr.id) 102 .push((module.module_id, impl_id));
112 .or_insert_with(Vec::new)
113 .push((module.module_id, impl_id));
114 }
115 } 103 }
116 } 104 }
117 105
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_function_generics.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_function_generics.snap
index 8ff6e55a6..91c48897c 100644
--- a/crates/ra_hir/src/ty/snapshots/tests__infer_function_generics.snap
+++ b/crates/ra_hir/src/ty/snapshots/tests__infer_function_generics.snap
@@ -1,12 +1,12 @@
1--- 1---
2created: "2019-01-26T18:16:16.530712344+00:00" 2created: "2019-01-27T14:52:29.934503829+00:00"
3creator: [email protected] 3creator: [email protected]
4expression: "&result" 4expression: "&result"
5source: crates/ra_hir/src/ty/tests.rs 5source: crates/ra_hir/src/ty/tests.rs
6--- 6---
7[10; 11) 't': [unknown] 7[10; 11) 't': T
8[21; 26) '{ t }': [unknown] 8[21; 26) '{ t }': T
9[23; 24) 't': [unknown] 9[23; 24) 't': T
10[38; 98) '{ ...(1); }': () 10[38; 98) '{ ...(1); }': ()
11[44; 46) 'id': fn id<u32>(T) -> T 11[44; 46) 'id': fn id<u32>(T) -> T
12[44; 52) 'id(1u32)': u32 12[44; 52) 'id(1u32)': u32
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap
index f21bffa75..626f31252 100644
--- a/crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap
+++ b/crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap
@@ -1,5 +1,5 @@
1--- 1---
2created: "2019-01-26T17:46:03.866825843+00:00" 2created: "2019-01-27T14:52:29.938713255+00:00"
3creator: [email protected] 3creator: [email protected]
4expression: "&result" 4expression: "&result"
5source: crates/ra_hir/src/ty/tests.rs 5source: crates/ra_hir/src/ty/tests.rs
@@ -8,9 +8,9 @@ source: crates/ra_hir/src/ty/tests.rs
8[65; 87) '{ ... }': [unknown] 8[65; 87) '{ ... }': [unknown]
9[75; 79) 'self': A<[unknown]> 9[75; 79) 'self': A<[unknown]>
10[75; 81) 'self.x': [unknown] 10[75; 81) 'self.x': [unknown]
11[99; 100) 't': [unknown] 11[99; 100) 't': T
12[110; 115) '{ t }': [unknown] 12[110; 115) '{ t }': T
13[112; 113) 't': [unknown] 13[112; 113) 't': T
14[135; 261) '{ ....x() }': i128 14[135; 261) '{ ....x() }': i128
15[146; 147) 'x': i32 15[146; 147) 'x': i32
16[150; 151) '1': i32 16[150; 151) '1': i32
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_type_param.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_type_param.snap
index a99323264..216d1e41f 100644
--- a/crates/ra_hir/src/ty/snapshots/tests__infer_type_param.snap
+++ b/crates/ra_hir/src/ty/snapshots/tests__infer_type_param.snap
@@ -1,15 +1,15 @@
1--- 1---
2created: "2019-01-27T16:54:18.368427685+00:00" 2created: "2019-01-27T20:38:32.153717698+00:00"
3creator: [email protected] 3creator: [email protected]
4expression: "&result" 4expression: "&result"
5source: crates/ra_hir/src/ty/tests.rs 5source: crates/ra_hir/src/ty/tests.rs
6--- 6---
7[10; 11) 'x': [unknown] 7[10; 11) 'x': T
8[21; 30) '{ x }': [unknown] 8[21; 30) '{ x }': T
9[27; 28) 'x': [unknown] 9[27; 28) 'x': T
10[44; 45) 'x': &[unknown] 10[44; 45) 'x': &T
11[56; 65) '{ x }': &[unknown] 11[56; 65) '{ x }': &T
12[62; 63) 'x': &[unknown] 12[62; 63) 'x': &T
13[77; 157) '{ ...(1); }': () 13[77; 157) '{ ...(1); }': ()
14[87; 88) 'y': u32 14[87; 88) 'y': u32
15[91; 96) '10u32': u32 15[91; 96) '10u32': u32