aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/adt.rs5
-rw-r--r--crates/ra_hir/src/code_model_api.rs11
-rw-r--r--crates/ra_hir/src/code_model_impl/module.rs9
-rw-r--r--crates/ra_hir/src/db.rs10
-rw-r--r--crates/ra_hir/src/lib.rs9
-rw-r--r--crates/ra_hir/src/ty.rs234
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs39
-rw-r--r--crates/ra_hir/src/ty/tests.rs6
8 files changed, 139 insertions, 184 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs
index 57d112f74..d87fe7049 100644
--- a/crates/ra_hir/src/adt.rs
+++ b/crates/ra_hir/src/adt.rs
@@ -1,6 +1,5 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use ra_db::Cancelable;
4use ra_syntax::{ 3use ra_syntax::{
5 SyntaxNode, 4 SyntaxNode,
6 ast::{self, NameOwner, StructFlavor, AstNode} 5 ast::{self, NameOwner, StructFlavor, AstNode}
@@ -18,8 +17,8 @@ impl Struct {
18 Struct { def_id } 17 Struct { def_id }
19 } 18 }
20 19
21 pub(crate) fn variant_data(&self, db: &impl HirDatabase) -> Cancelable<Arc<VariantData>> { 20 pub(crate) fn variant_data(&self, db: &impl HirDatabase) -> Arc<VariantData> {
22 Ok(db.struct_data(self.def_id).variant_data.clone()) 21 db.struct_data(self.def_id).variant_data.clone()
23 } 22 }
24} 23}
25 24
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index 7ccd29e2f..0cf7deac9 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -1,7 +1,7 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use relative_path::RelativePathBuf; 3use relative_path::RelativePathBuf;
4use ra_db::{CrateId, Cancelable, FileId}; 4use ra_db::{CrateId, FileId};
5use ra_syntax::{ast, TreeArc, SyntaxNode}; 5use ra_syntax::{ast, TreeArc, SyntaxNode};
6 6
7use crate::{ 7use crate::{
@@ -142,10 +142,7 @@ impl Module {
142 self.resolve_path_impl(db, path) 142 self.resolve_path_impl(db, path)
143 } 143 }
144 144
145 pub fn problems( 145 pub fn problems(&self, db: &impl HirDatabase) -> Vec<(TreeArc<SyntaxNode>, Problem)> {
146 &self,
147 db: &impl HirDatabase,
148 ) -> Cancelable<Vec<(TreeArc<SyntaxNode>, Problem)>> {
149 self.problems_impl(db) 146 self.problems_impl(db)
150 } 147 }
151} 148}
@@ -160,7 +157,7 @@ impl StructField {
160 pub fn name(&self) -> &Name { 157 pub fn name(&self) -> &Name {
161 &self.name 158 &self.name
162 } 159 }
163 pub fn ty(&self, db: &impl HirDatabase) -> Cancelable<Option<Ty>> { 160 pub fn ty(&self, db: &impl HirDatabase) -> Option<Ty> {
164 db.type_for_field(self.struct_.def_id, self.name.clone()) 161 db.type_for_field(self.struct_.def_id, self.name.clone())
165 } 162 }
166} 163}
@@ -318,7 +315,7 @@ impl Function {
318 db.fn_signature(self.def_id) 315 db.fn_signature(self.def_id)
319 } 316 }
320 317
321 pub fn infer(&self, db: &impl HirDatabase) -> Cancelable<Arc<InferenceResult>> { 318 pub fn infer(&self, db: &impl HirDatabase) -> Arc<InferenceResult> {
322 db.infer(self.def_id) 319 db.infer(self.def_id)
323 } 320 }
324} 321}
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs
index 04301ae53..a5c032d69 100644
--- a/crates/ra_hir/src/code_model_impl/module.rs
+++ b/crates/ra_hir/src/code_model_impl/module.rs
@@ -1,4 +1,4 @@
1use ra_db::{Cancelable, SourceRootId, FileId}; 1use ra_db::{SourceRootId, FileId};
2use ra_syntax::{ast, SyntaxNode, AstNode, TreeArc}; 2use ra_syntax::{ast, SyntaxNode, AstNode, TreeArc};
3 3
4use crate::{ 4use crate::{
@@ -176,12 +176,9 @@ impl Module {
176 curr_per_ns 176 curr_per_ns
177 } 177 }
178 178
179 pub fn problems_impl( 179 pub fn problems_impl(&self, db: &impl HirDatabase) -> Vec<(TreeArc<SyntaxNode>, Problem)> {
180 &self,
181 db: &impl HirDatabase,
182 ) -> Cancelable<Vec<(TreeArc<SyntaxNode>, Problem)>> {
183 let loc = self.def_id.loc(db); 180 let loc = self.def_id.loc(db);
184 let module_tree = db.module_tree(loc.source_root_id); 181 let module_tree = db.module_tree(loc.source_root_id);
185 Ok(loc.module_id.problems(&module_tree, db)) 182 loc.module_id.problems(&module_tree, db)
186 } 183 }
187} 184}
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 161a5e714..0a0994f5f 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -1,7 +1,7 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use ra_syntax::{SyntaxNode, TreeArc, SourceFile}; 3use ra_syntax::{SyntaxNode, TreeArc, SourceFile};
4use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase, Cancelable}; 4use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase};
5 5
6use crate::{ 6use crate::{
7 DefLoc, DefId, MacroCallLoc, MacroCallId, Name, HirFileId, 7 DefLoc, DefId, MacroCallLoc, MacroCallId, Name, HirFileId,
@@ -52,17 +52,17 @@ pub trait HirDatabase: SyntaxDatabase
52 use fn crate::adt::EnumVariantData::enum_variant_data_query; 52 use fn crate::adt::EnumVariantData::enum_variant_data_query;
53 } 53 }
54 54
55 fn infer(def_id: DefId) -> Cancelable<Arc<InferenceResult>> { 55 fn infer(def_id: DefId) -> Arc<InferenceResult> {
56 type InferQuery; 56 type InferQuery;
57 use fn crate::ty::infer; 57 use fn crate::ty::infer;
58 } 58 }
59 59
60 fn type_for_def(def_id: DefId) -> Cancelable<Ty> { 60 fn type_for_def(def_id: DefId) -> Ty {
61 type TypeForDefQuery; 61 type TypeForDefQuery;
62 use fn crate::ty::type_for_def; 62 use fn crate::ty::type_for_def;
63 } 63 }
64 64
65 fn type_for_field(def_id: DefId, field: Name) -> Cancelable<Option<Ty>> { 65 fn type_for_field(def_id: DefId, field: Name) -> Option<Ty> {
66 type TypeForFieldQuery; 66 type TypeForFieldQuery;
67 use fn crate::ty::type_for_field; 67 use fn crate::ty::type_for_field;
68 } 68 }
@@ -102,7 +102,7 @@ pub trait HirDatabase: SyntaxDatabase
102 use fn crate::impl_block::impls_in_module; 102 use fn crate::impl_block::impls_in_module;
103 } 103 }
104 104
105 fn impls_in_crate(krate: Crate) -> Cancelable<Arc<CrateImplBlocks>> { 105 fn impls_in_crate(krate: Crate) -> Arc<CrateImplBlocks> {
106 type ImplsInCrateQuery; 106 type ImplsInCrateQuery;
107 use fn crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query; 107 use fn crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query;
108 } 108 }
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 45dda4f7f..ef7d049ee 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -5,15 +5,6 @@
5//! to a particular crate instance. That is, it has cfg flags and features 5//! to a particular crate instance. That is, it has cfg flags and features
6//! applied. So, the relation between syntax and HIR is many-to-one. 6//! applied. So, the relation between syntax and HIR is many-to-one.
7 7
8macro_rules! ctry {
9 ($expr:expr) => {
10 match $expr {
11 None => return Ok(None),
12 Some(it) => it,
13 }
14 };
15}
16
17pub mod db; 8pub mod db;
18#[cfg(test)] 9#[cfg(test)]
19mod mock; 10mod mock;
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index e5f8ffc2e..dbbbce795 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -30,8 +30,6 @@ use ra_arena::map::ArenaMap;
30use join_to_string::join; 30use join_to_string::join;
31use rustc_hash::FxHashMap; 31use rustc_hash::FxHashMap;
32 32
33use ra_db::Cancelable;
34
35use crate::{ 33use crate::{
36 Def, DefId, Module, Function, Struct, Enum, EnumVariant, Path, Name, ImplBlock, 34 Def, DefId, Module, Function, Struct, Enum, EnumVariant, Path, Name, ImplBlock,
37 FnSignature, FnScopes, 35 FnSignature, FnScopes,
@@ -41,14 +39,6 @@ use crate::{
41 expr::{Body, Expr, Literal, ExprId, PatId, UnaryOp, BinaryOp, Statement}, 39 expr::{Body, Expr, Literal, ExprId, PatId, UnaryOp, BinaryOp, Statement},
42}; 40};
43 41
44fn transpose<T>(x: Cancelable<Option<T>>) -> Option<Cancelable<T>> {
45 match x {
46 Ok(Some(t)) => Some(Ok(t)),
47 Ok(None) => None,
48 Err(e) => Some(Err(e)),
49 }
50}
51
52/// The ID of a type variable. 42/// The ID of a type variable.
53#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] 43#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
54pub struct TypeVarId(u32); 44pub struct TypeVarId(u32);
@@ -271,28 +261,28 @@ impl Ty {
271 module: &Module, 261 module: &Module,
272 impl_block: Option<&ImplBlock>, 262 impl_block: Option<&ImplBlock>,
273 type_ref: &TypeRef, 263 type_ref: &TypeRef,
274 ) -> Cancelable<Self> { 264 ) -> Self {
275 Ok(match type_ref { 265 match type_ref {
276 TypeRef::Never => Ty::Never, 266 TypeRef::Never => Ty::Never,
277 TypeRef::Tuple(inner) => { 267 TypeRef::Tuple(inner) => {
278 let inner_tys = inner 268 let inner_tys = inner
279 .iter() 269 .iter()
280 .map(|tr| Ty::from_hir(db, module, impl_block, tr)) 270 .map(|tr| Ty::from_hir(db, module, impl_block, tr))
281 .collect::<Cancelable<Vec<_>>>()?; 271 .collect::<Vec<_>>();
282 Ty::Tuple(inner_tys.into()) 272 Ty::Tuple(inner_tys.into())
283 } 273 }
284 TypeRef::Path(path) => Ty::from_hir_path(db, module, impl_block, path)?, 274 TypeRef::Path(path) => Ty::from_hir_path(db, module, impl_block, path),
285 TypeRef::RawPtr(inner, mutability) => { 275 TypeRef::RawPtr(inner, mutability) => {
286 let inner_ty = Ty::from_hir(db, module, impl_block, inner)?; 276 let inner_ty = Ty::from_hir(db, module, impl_block, inner);
287 Ty::RawPtr(Arc::new(inner_ty), *mutability) 277 Ty::RawPtr(Arc::new(inner_ty), *mutability)
288 } 278 }
289 TypeRef::Array(_inner) => Ty::Unknown, // TODO 279 TypeRef::Array(_inner) => Ty::Unknown, // TODO
290 TypeRef::Slice(inner) => { 280 TypeRef::Slice(inner) => {
291 let inner_ty = Ty::from_hir(db, module, impl_block, inner)?; 281 let inner_ty = Ty::from_hir(db, module, impl_block, inner);
292 Ty::Slice(Arc::new(inner_ty)) 282 Ty::Slice(Arc::new(inner_ty))
293 } 283 }
294 TypeRef::Reference(inner, mutability) => { 284 TypeRef::Reference(inner, mutability) => {
295 let inner_ty = Ty::from_hir(db, module, impl_block, inner)?; 285 let inner_ty = Ty::from_hir(db, module, impl_block, inner);
296 Ty::Ref(Arc::new(inner_ty), *mutability) 286 Ty::Ref(Arc::new(inner_ty), *mutability)
297 } 287 }
298 TypeRef::Placeholder => Ty::Unknown, 288 TypeRef::Placeholder => Ty::Unknown,
@@ -300,7 +290,7 @@ impl Ty {
300 let mut inner_tys = params 290 let mut inner_tys = params
301 .iter() 291 .iter()
302 .map(|tr| Ty::from_hir(db, module, impl_block, tr)) 292 .map(|tr| Ty::from_hir(db, module, impl_block, tr))
303 .collect::<Cancelable<Vec<_>>>()?; 293 .collect::<Vec<_>>();
304 let return_ty = inner_tys 294 let return_ty = inner_tys
305 .pop() 295 .pop()
306 .expect("TypeRef::Fn should always have at least return type"); 296 .expect("TypeRef::Fn should always have at least return type");
@@ -311,7 +301,7 @@ impl Ty {
311 Ty::FnPtr(Arc::new(sig)) 301 Ty::FnPtr(Arc::new(sig))
312 } 302 }
313 TypeRef::Error => Ty::Unknown, 303 TypeRef::Error => Ty::Unknown,
314 }) 304 }
315 } 305 }
316 306
317 pub(crate) fn from_hir_opt( 307 pub(crate) fn from_hir_opt(
@@ -319,10 +309,8 @@ impl Ty {
319 module: &Module, 309 module: &Module,
320 impl_block: Option<&ImplBlock>, 310 impl_block: Option<&ImplBlock>,
321 type_ref: Option<&TypeRef>, 311 type_ref: Option<&TypeRef>,
322 ) -> Cancelable<Self> { 312 ) -> Self {
323 type_ref 313 type_ref.map_or(Ty::Unknown, |t| Ty::from_hir(db, module, impl_block, t))
324 .map(|t| Ty::from_hir(db, module, impl_block, t))
325 .unwrap_or(Ok(Ty::Unknown))
326 } 314 }
327 315
328 pub(crate) fn from_hir_path( 316 pub(crate) fn from_hir_path(
@@ -330,19 +318,19 @@ impl Ty {
330 module: &Module, 318 module: &Module,
331 impl_block: Option<&ImplBlock>, 319 impl_block: Option<&ImplBlock>,
332 path: &Path, 320 path: &Path,
333 ) -> Cancelable<Self> { 321 ) -> Self {
334 if let Some(name) = path.as_ident() { 322 if let Some(name) = path.as_ident() {
335 if let Some(int_ty) = primitive::UncertainIntTy::from_name(name) { 323 if let Some(int_ty) = primitive::UncertainIntTy::from_name(name) {
336 return Ok(Ty::Int(int_ty)); 324 return Ty::Int(int_ty);
337 } else if let Some(float_ty) = primitive::UncertainFloatTy::from_name(name) { 325 } else if let Some(float_ty) = primitive::UncertainFloatTy::from_name(name) {
338 return Ok(Ty::Float(float_ty)); 326 return Ty::Float(float_ty);
339 } else if name.as_known_name() == Some(KnownName::SelfType) { 327 } else if name.as_known_name() == Some(KnownName::SelfType) {
340 return Ty::from_hir_opt(db, module, None, impl_block.map(|i| i.target_type())); 328 return Ty::from_hir_opt(db, module, None, impl_block.map(|i| i.target_type()));
341 } else if let Some(known) = name.as_known_name() { 329 } else if let Some(known) = name.as_known_name() {
342 match known { 330 match known {
343 KnownName::Bool => return Ok(Ty::Bool), 331 KnownName::Bool => return Ty::Bool,
344 KnownName::Char => return Ok(Ty::Char), 332 KnownName::Char => return Ty::Char,
345 KnownName::Str => return Ok(Ty::Str), 333 KnownName::Str => return Ty::Str,
346 _ => {} 334 _ => {}
347 } 335 }
348 } 336 }
@@ -352,10 +340,9 @@ impl Ty {
352 let resolved = if let Some(r) = module.resolve_path(db, path).take_types() { 340 let resolved = if let Some(r) = module.resolve_path(db, path).take_types() {
353 r 341 r
354 } else { 342 } else {
355 return Ok(Ty::Unknown); 343 return Ty::Unknown;
356 }; 344 };
357 let ty = db.type_for_def(resolved)?; 345 db.type_for_def(resolved)
358 Ok(ty)
359 } 346 }
360 347
361 pub fn unit() -> Self { 348 pub fn unit() -> Self {
@@ -445,7 +432,7 @@ impl fmt::Display for Ty {
445 432
446/// Compute the declared type of a function. This should not need to look at the 433/// Compute the declared type of a function. This should not need to look at the
447/// function body. 434/// function body.
448fn type_for_fn(db: &impl HirDatabase, f: Function) -> Cancelable<Ty> { 435fn type_for_fn(db: &impl HirDatabase, f: Function) -> Ty {
449 let signature = f.signature(db); 436 let signature = f.signature(db);
450 let module = f.module(db); 437 let module = f.module(db);
451 let impl_block = f.impl_block(db); 438 let impl_block = f.impl_block(db);
@@ -454,38 +441,38 @@ fn type_for_fn(db: &impl HirDatabase, f: Function) -> Cancelable<Ty> {
454 .params() 441 .params()
455 .iter() 442 .iter()
456 .map(|tr| Ty::from_hir(db, &module, impl_block.as_ref(), tr)) 443 .map(|tr| Ty::from_hir(db, &module, impl_block.as_ref(), tr))
457 .collect::<Cancelable<Vec<_>>>()?; 444 .collect::<Vec<_>>();
458 let output = Ty::from_hir(db, &module, impl_block.as_ref(), signature.ret_type())?; 445 let output = Ty::from_hir(db, &module, impl_block.as_ref(), signature.ret_type());
459 let sig = FnSig { input, output }; 446 let sig = FnSig { input, output };
460 Ok(Ty::FnPtr(Arc::new(sig))) 447 Ty::FnPtr(Arc::new(sig))
461} 448}
462 449
463fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Cancelable<Ty> { 450fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty {
464 Ok(Ty::Adt { 451 Ty::Adt {
465 def_id: s.def_id(), 452 def_id: s.def_id(),
466 name: s.name(db).unwrap_or_else(Name::missing), 453 name: s.name(db).unwrap_or_else(Name::missing),
467 }) 454 }
468} 455}
469 456
470pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Cancelable<Ty> { 457pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty {
471 Ok(Ty::Adt { 458 Ty::Adt {
472 def_id: s.def_id(), 459 def_id: s.def_id(),
473 name: s.name(db).unwrap_or_else(Name::missing), 460 name: s.name(db).unwrap_or_else(Name::missing),
474 }) 461 }
475} 462}
476 463
477pub(crate) fn type_for_enum_variant(db: &impl HirDatabase, ev: EnumVariant) -> Cancelable<Ty> { 464pub(crate) fn type_for_enum_variant(db: &impl HirDatabase, ev: EnumVariant) -> Ty {
478 let enum_parent = ev.parent_enum(db); 465 let enum_parent = ev.parent_enum(db);
479 466
480 type_for_enum(db, enum_parent) 467 type_for_enum(db, enum_parent)
481} 468}
482 469
483pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Ty> { 470pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Ty {
484 let def = def_id.resolve(db); 471 let def = def_id.resolve(db);
485 match def { 472 match def {
486 Def::Module(..) => { 473 Def::Module(..) => {
487 log::debug!("trying to get type for module {:?}", def_id); 474 log::debug!("trying to get type for module {:?}", def_id);
488 Ok(Ty::Unknown) 475 Ty::Unknown
489 } 476 }
490 Def::Function(f) => type_for_fn(db, f), 477 Def::Function(f) => type_for_fn(db, f),
491 Def::Struct(s) => type_for_struct(db, s), 478 Def::Struct(s) => type_for_struct(db, s),
@@ -497,19 +484,15 @@ pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Cancelable<T
497 def_id, 484 def_id,
498 def 485 def
499 ); 486 );
500 Ok(Ty::Unknown) 487 Ty::Unknown
501 } 488 }
502 } 489 }
503} 490}
504 491
505pub(super) fn type_for_field( 492pub(super) fn type_for_field(db: &impl HirDatabase, def_id: DefId, field: Name) -> Option<Ty> {
506 db: &impl HirDatabase,
507 def_id: DefId,
508 field: Name,
509) -> Cancelable<Option<Ty>> {
510 let def = def_id.resolve(db); 493 let def = def_id.resolve(db);
511 let variant_data = match def { 494 let variant_data = match def {
512 Def::Struct(s) => s.variant_data(db)?, 495 Def::Struct(s) => s.variant_data(db),
513 Def::EnumVariant(ev) => ev.variant_data(db), 496 Def::EnumVariant(ev) => ev.variant_data(db),
514 // TODO: unions 497 // TODO: unions
515 _ => panic!( 498 _ => panic!(
@@ -519,13 +502,8 @@ pub(super) fn type_for_field(
519 }; 502 };
520 let module = def_id.module(db); 503 let module = def_id.module(db);
521 let impl_block = def_id.impl_block(db); 504 let impl_block = def_id.impl_block(db);
522 let type_ref = ctry!(variant_data.get_field_type_ref(&field)); 505 let type_ref = variant_data.get_field_type_ref(&field)?;
523 Ok(Some(Ty::from_hir( 506 Some(Ty::from_hir(db, &module, impl_block.as_ref(), &type_ref))
524 db,
525 &module,
526 impl_block.as_ref(),
527 &type_ref,
528 )?))
529} 507}
530 508
531/// The result of type inference: A mapping from expressions and patterns to types. 509/// The result of type inference: A mapping from expressions and patterns to types.
@@ -702,7 +680,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
702 self.type_of_pat.insert(pat, ty); 680 self.type_of_pat.insert(pat, ty);
703 } 681 }
704 682
705 fn make_ty(&self, type_ref: &TypeRef) -> Cancelable<Ty> { 683 fn make_ty(&self, type_ref: &TypeRef) -> Ty {
706 Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), type_ref) 684 Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), type_ref)
707 } 685 }
708 686
@@ -848,49 +826,49 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
848 }) 826 })
849 } 827 }
850 828
851 fn infer_path_expr(&mut self, expr: ExprId, path: &Path) -> Cancelable<Option<Ty>> { 829 fn infer_path_expr(&mut self, expr: ExprId, path: &Path) -> Option<Ty> {
852 if path.is_ident() || path.is_self() { 830 if path.is_ident() || path.is_self() {
853 // resolve locally 831 // resolve locally
854 let name = path.as_ident().cloned().unwrap_or_else(Name::self_param); 832 let name = path.as_ident().cloned().unwrap_or_else(Name::self_param);
855 if let Some(scope_entry) = self.scopes.resolve_local_name(expr, name) { 833 if let Some(scope_entry) = self.scopes.resolve_local_name(expr, name) {
856 let ty = ctry!(self.type_of_pat.get(scope_entry.pat())); 834 let ty = self.type_of_pat.get(scope_entry.pat())?;
857 let ty = self.resolve_ty_as_possible(ty.clone()); 835 let ty = self.resolve_ty_as_possible(ty.clone());
858 return Ok(Some(ty)); 836 return Some(ty);
859 }; 837 };
860 }; 838 };
861 839
862 // resolve in module 840 // resolve in module
863 let resolved = ctry!(self.module.resolve_path(self.db, &path).take_values()); 841 let resolved = self.module.resolve_path(self.db, &path).take_values()?;
864 let ty = self.db.type_for_def(resolved)?; 842 let ty = self.db.type_for_def(resolved);
865 let ty = self.insert_type_vars(ty); 843 let ty = self.insert_type_vars(ty);
866 Ok(Some(ty)) 844 Some(ty)
867 } 845 }
868 846
869 fn resolve_variant(&self, path: Option<&Path>) -> Cancelable<(Ty, Option<DefId>)> { 847 fn resolve_variant(&self, path: Option<&Path>) -> (Ty, Option<DefId>) {
870 let path = if let Some(path) = path { 848 let path = if let Some(path) = path {
871 path 849 path
872 } else { 850 } else {
873 return Ok((Ty::Unknown, None)); 851 return (Ty::Unknown, None);
874 }; 852 };
875 let def_id = if let Some(def_id) = self.module.resolve_path(self.db, &path).take_types() { 853 let def_id = if let Some(def_id) = self.module.resolve_path(self.db, &path).take_types() {
876 def_id 854 def_id
877 } else { 855 } else {
878 return Ok((Ty::Unknown, None)); 856 return (Ty::Unknown, None);
879 }; 857 };
880 Ok(match def_id.resolve(self.db) { 858 match def_id.resolve(self.db) {
881 Def::Struct(s) => { 859 Def::Struct(s) => {
882 let ty = type_for_struct(self.db, s)?; 860 let ty = type_for_struct(self.db, s);
883 (ty, Some(def_id)) 861 (ty, Some(def_id))
884 } 862 }
885 Def::EnumVariant(ev) => { 863 Def::EnumVariant(ev) => {
886 let ty = type_for_enum_variant(self.db, ev)?; 864 let ty = type_for_enum_variant(self.db, ev);
887 (ty, Some(def_id)) 865 (ty, Some(def_id))
888 } 866 }
889 _ => (Ty::Unknown, None), 867 _ => (Ty::Unknown, None),
890 }) 868 }
891 } 869 }
892 870
893 fn infer_expr(&mut self, expr: ExprId, expected: &Expectation) -> Cancelable<Ty> { 871 fn infer_expr(&mut self, expr: ExprId, expected: &Expectation) -> Ty {
894 let body = Arc::clone(&self.body); // avoid borrow checker problem 872 let body = Arc::clone(&self.body); // avoid borrow checker problem
895 let ty = match &body[expr] { 873 let ty = match &body[expr] {
896 Expr::Missing => Ty::Unknown, 874 Expr::Missing => Ty::Unknown,
@@ -900,11 +878,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
900 else_branch, 878 else_branch,
901 } => { 879 } => {
902 // if let is desugared to match, so this is always simple if 880 // if let is desugared to match, so this is always simple if
903 self.infer_expr(*condition, &Expectation::has_type(Ty::Bool))?; 881 self.infer_expr(*condition, &Expectation::has_type(Ty::Bool));
904 let then_ty = self.infer_expr(*then_branch, expected)?; 882 let then_ty = self.infer_expr(*then_branch, expected);
905 match else_branch { 883 match else_branch {
906 Some(else_branch) => { 884 Some(else_branch) => {
907 self.infer_expr(*else_branch, expected)?; 885 self.infer_expr(*else_branch, expected);
908 } 886 }
909 None => { 887 None => {
910 // no else branch -> unit 888 // no else branch -> unit
@@ -913,31 +891,31 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
913 }; 891 };
914 then_ty 892 then_ty
915 } 893 }
916 Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected)?, 894 Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected),
917 Expr::Loop { body } => { 895 Expr::Loop { body } => {
918 self.infer_expr(*body, &Expectation::has_type(Ty::unit()))?; 896 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
919 // TODO handle break with value 897 // TODO handle break with value
920 Ty::Never 898 Ty::Never
921 } 899 }
922 Expr::While { condition, body } => { 900 Expr::While { condition, body } => {
923 // while let is desugared to a match loop, so this is always simple while 901 // while let is desugared to a match loop, so this is always simple while
924 self.infer_expr(*condition, &Expectation::has_type(Ty::Bool))?; 902 self.infer_expr(*condition, &Expectation::has_type(Ty::Bool));
925 self.infer_expr(*body, &Expectation::has_type(Ty::unit()))?; 903 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
926 Ty::unit() 904 Ty::unit()
927 } 905 }
928 Expr::For { iterable, body, .. } => { 906 Expr::For { iterable, body, .. } => {
929 let _iterable_ty = self.infer_expr(*iterable, &Expectation::none()); 907 let _iterable_ty = self.infer_expr(*iterable, &Expectation::none());
930 // TODO write type for pat 908 // TODO write type for pat
931 self.infer_expr(*body, &Expectation::has_type(Ty::unit()))?; 909 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
932 Ty::unit() 910 Ty::unit()
933 } 911 }
934 Expr::Lambda { body, .. } => { 912 Expr::Lambda { body, .. } => {
935 // TODO write types for args, infer lambda type etc. 913 // TODO write types for args, infer lambda type etc.
936 let _body_ty = self.infer_expr(*body, &Expectation::none())?; 914 let _body_ty = self.infer_expr(*body, &Expectation::none());
937 Ty::Unknown 915 Ty::Unknown
938 } 916 }
939 Expr::Call { callee, args } => { 917 Expr::Call { callee, args } => {
940 let callee_ty = self.infer_expr(*callee, &Expectation::none())?; 918 let callee_ty = self.infer_expr(*callee, &Expectation::none());
941 let (param_tys, ret_ty) = match &callee_ty { 919 let (param_tys, ret_ty) = match &callee_ty {
942 Ty::FnPtr(sig) => (&sig.input[..], sig.output.clone()), 920 Ty::FnPtr(sig) => (&sig.input[..], sig.output.clone()),
943 _ => { 921 _ => {
@@ -950,7 +928,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
950 self.infer_expr( 928 self.infer_expr(
951 *arg, 929 *arg,
952 &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)), 930 &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)),
953 )?; 931 );
954 } 932 }
955 ret_ty 933 ret_ty
956 } 934 }
@@ -959,12 +937,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
959 args, 937 args,
960 method_name, 938 method_name,
961 } => { 939 } => {
962 let receiver_ty = self.infer_expr(*receiver, &Expectation::none())?; 940 let receiver_ty = self.infer_expr(*receiver, &Expectation::none());
963 let resolved = receiver_ty.clone().lookup_method(self.db, method_name)?; 941 let resolved = receiver_ty.clone().lookup_method(self.db, method_name);
964 let method_ty = match resolved { 942 let method_ty = match resolved {
965 Some(def_id) => { 943 Some(def_id) => {
966 self.write_method_resolution(expr, def_id); 944 self.write_method_resolution(expr, def_id);
967 self.db.type_for_def(def_id)? 945 self.db.type_for_def(def_id)
968 } 946 }
969 None => Ty::Unknown, 947 None => Ty::Unknown,
970 }; 948 };
@@ -986,32 +964,32 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
986 self.infer_expr( 964 self.infer_expr(
987 *arg, 965 *arg,
988 &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)), 966 &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)),
989 )?; 967 );
990 } 968 }
991 ret_ty 969 ret_ty
992 } 970 }
993 Expr::Match { expr, arms } => { 971 Expr::Match { expr, arms } => {
994 let _ty = self.infer_expr(*expr, &Expectation::none())?; 972 let _ty = self.infer_expr(*expr, &Expectation::none());
995 for arm in arms { 973 for arm in arms {
996 // TODO type the bindings in pats 974 // TODO type the bindings in pats
997 // TODO type the guard 975 // TODO type the guard
998 let _ty = self.infer_expr(arm.expr, &Expectation::none())?; 976 let _ty = self.infer_expr(arm.expr, &Expectation::none());
999 } 977 }
1000 // TODO unify all the match arm types 978 // TODO unify all the match arm types
1001 Ty::Unknown 979 Ty::Unknown
1002 } 980 }
1003 Expr::Path(p) => self.infer_path_expr(expr, p)?.unwrap_or(Ty::Unknown), 981 Expr::Path(p) => self.infer_path_expr(expr, p).unwrap_or(Ty::Unknown),
1004 Expr::Continue => Ty::Never, 982 Expr::Continue => Ty::Never,
1005 Expr::Break { expr } => { 983 Expr::Break { expr } => {
1006 if let Some(expr) = expr { 984 if let Some(expr) = expr {
1007 // TODO handle break with value 985 // TODO handle break with value
1008 self.infer_expr(*expr, &Expectation::none())?; 986 self.infer_expr(*expr, &Expectation::none());
1009 } 987 }
1010 Ty::Never 988 Ty::Never
1011 } 989 }
1012 Expr::Return { expr } => { 990 Expr::Return { expr } => {
1013 if let Some(expr) = expr { 991 if let Some(expr) = expr {
1014 self.infer_expr(*expr, &Expectation::has_type(self.return_ty.clone()))?; 992 self.infer_expr(*expr, &Expectation::has_type(self.return_ty.clone()));
1015 } 993 }
1016 Ty::Never 994 Ty::Never
1017 } 995 }
@@ -1020,60 +998,58 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1020 fields, 998 fields,
1021 spread, 999 spread,
1022 } => { 1000 } => {
1023 let (ty, def_id) = self.resolve_variant(path.as_ref())?; 1001 let (ty, def_id) = self.resolve_variant(path.as_ref());
1024 for field in fields { 1002 for field in fields {
1025 let field_ty = if let Some(def_id) = def_id { 1003 let field_ty = if let Some(def_id) = def_id {
1026 self.db 1004 self.db
1027 .type_for_field(def_id, field.name.clone())? 1005 .type_for_field(def_id, field.name.clone())
1028 .unwrap_or(Ty::Unknown) 1006 .unwrap_or(Ty::Unknown)
1029 } else { 1007 } else {
1030 Ty::Unknown 1008 Ty::Unknown
1031 }; 1009 };
1032 self.infer_expr(field.expr, &Expectation::has_type(field_ty))?; 1010 self.infer_expr(field.expr, &Expectation::has_type(field_ty));
1033 } 1011 }
1034 if let Some(expr) = spread { 1012 if let Some(expr) = spread {
1035 self.infer_expr(*expr, &Expectation::has_type(ty.clone()))?; 1013 self.infer_expr(*expr, &Expectation::has_type(ty.clone()));
1036 } 1014 }
1037 ty 1015 ty
1038 } 1016 }
1039 Expr::Field { expr, name } => { 1017 Expr::Field { expr, name } => {
1040 let receiver_ty = self.infer_expr(*expr, &Expectation::none())?; 1018 let receiver_ty = self.infer_expr(*expr, &Expectation::none());
1041 let ty = receiver_ty 1019 let ty = receiver_ty
1042 .autoderef(self.db) 1020 .autoderef(self.db)
1043 .find_map(|derefed_ty| match derefed_ty { 1021 .find_map(|derefed_ty| match derefed_ty {
1044 // this is more complicated than necessary because type_for_field is cancelable 1022 // this is more complicated than necessary because type_for_field is cancelable
1045 Ty::Tuple(fields) => { 1023 Ty::Tuple(fields) => {
1046 let i = name.to_string().parse::<usize>().ok(); 1024 let i = name.to_string().parse::<usize>().ok();
1047 i.and_then(|i| fields.get(i).cloned()).map(Ok) 1025 i.and_then(|i| fields.get(i).cloned())
1048 }
1049 Ty::Adt { def_id, .. } => {
1050 transpose(self.db.type_for_field(def_id, name.clone()))
1051 } 1026 }
1027 Ty::Adt { def_id, .. } => self.db.type_for_field(def_id, name.clone()),
1052 _ => None, 1028 _ => None,
1053 }) 1029 })
1054 .unwrap_or(Ok(Ty::Unknown))?; 1030 .unwrap_or(Ty::Unknown);
1055 self.insert_type_vars(ty) 1031 self.insert_type_vars(ty)
1056 } 1032 }
1057 Expr::Try { expr } => { 1033 Expr::Try { expr } => {
1058 let _inner_ty = self.infer_expr(*expr, &Expectation::none())?; 1034 let _inner_ty = self.infer_expr(*expr, &Expectation::none());
1059 Ty::Unknown 1035 Ty::Unknown
1060 } 1036 }
1061 Expr::Cast { expr, type_ref } => { 1037 Expr::Cast { expr, type_ref } => {
1062 let _inner_ty = self.infer_expr(*expr, &Expectation::none())?; 1038 let _inner_ty = self.infer_expr(*expr, &Expectation::none());
1063 let cast_ty = 1039 let cast_ty =
1064 Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), type_ref)?; 1040 Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), type_ref);
1065 let cast_ty = self.insert_type_vars(cast_ty); 1041 let cast_ty = self.insert_type_vars(cast_ty);
1066 // TODO check the cast... 1042 // TODO check the cast...
1067 cast_ty 1043 cast_ty
1068 } 1044 }
1069 Expr::Ref { expr, mutability } => { 1045 Expr::Ref { expr, mutability } => {
1070 // TODO pass the expectation down 1046 // TODO pass the expectation down
1071 let inner_ty = self.infer_expr(*expr, &Expectation::none())?; 1047 let inner_ty = self.infer_expr(*expr, &Expectation::none());
1072 // TODO reference coercions etc. 1048 // TODO reference coercions etc.
1073 Ty::Ref(Arc::new(inner_ty), *mutability) 1049 Ty::Ref(Arc::new(inner_ty), *mutability)
1074 } 1050 }
1075 Expr::UnaryOp { expr, op } => { 1051 Expr::UnaryOp { expr, op } => {
1076 let inner_ty = self.infer_expr(*expr, &Expectation::none())?; 1052 let inner_ty = self.infer_expr(*expr, &Expectation::none());
1077 match op { 1053 match op {
1078 Some(UnaryOp::Deref) => { 1054 Some(UnaryOp::Deref) => {
1079 if let Some(derefed_ty) = inner_ty.builtin_deref() { 1055 if let Some(derefed_ty) = inner_ty.builtin_deref() {
@@ -1094,11 +1070,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1094 } 1070 }
1095 _ => Expectation::none(), 1071 _ => Expectation::none(),
1096 }; 1072 };
1097 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation)?; 1073 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
1098 // TODO: find implementation of trait corresponding to operation 1074 // TODO: find implementation of trait corresponding to operation
1099 // symbol and resolve associated `Output` type 1075 // symbol and resolve associated `Output` type
1100 let rhs_expectation = binary_op_rhs_expectation(*op, lhs_ty); 1076 let rhs_expectation = binary_op_rhs_expectation(*op, lhs_ty);
1101 let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation))?; 1077 let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation));
1102 1078
1103 // TODO: similar as above, return ty is often associated trait type 1079 // TODO: similar as above, return ty is often associated trait type
1104 binary_op_return_ty(*op, rhs_ty) 1080 binary_op_return_ty(*op, rhs_ty)
@@ -1108,7 +1084,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1108 Expr::Tuple { exprs } => { 1084 Expr::Tuple { exprs } => {
1109 let mut ty_vec = Vec::with_capacity(exprs.len()); 1085 let mut ty_vec = Vec::with_capacity(exprs.len());
1110 for arg in exprs.iter() { 1086 for arg in exprs.iter() {
1111 ty_vec.push(self.infer_expr(*arg, &Expectation::none())?); 1087 ty_vec.push(self.infer_expr(*arg, &Expectation::none()));
1112 } 1088 }
1113 1089
1114 Ty::Tuple(Arc::from(ty_vec)) 1090 Ty::Tuple(Arc::from(ty_vec))
@@ -1133,7 +1109,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1133 self.unify(&ty, &expected.ty); 1109 self.unify(&ty, &expected.ty);
1134 let ty = self.resolve_ty_as_possible(ty); 1110 let ty = self.resolve_ty_as_possible(ty);
1135 self.write_expr_ty(expr, ty.clone()); 1111 self.write_expr_ty(expr, ty.clone());
1136 Ok(ty) 1112 ty
1137 } 1113 }
1138 1114
1139 fn infer_block( 1115 fn infer_block(
@@ -1141,7 +1117,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1141 statements: &[Statement], 1117 statements: &[Statement],
1142 tail: Option<ExprId>, 1118 tail: Option<ExprId>,
1143 expected: &Expectation, 1119 expected: &Expectation,
1144 ) -> Cancelable<Ty> { 1120 ) -> Ty {
1145 for stmt in statements { 1121 for stmt in statements {
1146 match stmt { 1122 match stmt {
1147 Statement::Let { 1123 Statement::Let {
@@ -1154,10 +1130,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1154 &self.module, 1130 &self.module,
1155 self.impl_block.as_ref(), 1131 self.impl_block.as_ref(),
1156 type_ref.as_ref(), 1132 type_ref.as_ref(),
1157 )?; 1133 );
1158 let decl_ty = self.insert_type_vars(decl_ty); 1134 let decl_ty = self.insert_type_vars(decl_ty);
1159 let ty = if let Some(expr) = initializer { 1135 let ty = if let Some(expr) = initializer {
1160 let expr_ty = self.infer_expr(*expr, &Expectation::has_type(decl_ty))?; 1136 let expr_ty = self.infer_expr(*expr, &Expectation::has_type(decl_ty));
1161 expr_ty 1137 expr_ty
1162 } else { 1138 } else {
1163 decl_ty 1139 decl_ty
@@ -1166,43 +1142,41 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1166 self.write_pat_ty(*pat, ty); 1142 self.write_pat_ty(*pat, ty);
1167 } 1143 }
1168 Statement::Expr(expr) => { 1144 Statement::Expr(expr) => {
1169 self.infer_expr(*expr, &Expectation::none())?; 1145 self.infer_expr(*expr, &Expectation::none());
1170 } 1146 }
1171 } 1147 }
1172 } 1148 }
1173 let ty = if let Some(expr) = tail { 1149 let ty = if let Some(expr) = tail {
1174 self.infer_expr(expr, expected)? 1150 self.infer_expr(expr, expected)
1175 } else { 1151 } else {
1176 Ty::unit() 1152 Ty::unit()
1177 }; 1153 };
1178 Ok(ty) 1154 ty
1179 } 1155 }
1180 1156
1181 fn collect_fn_signature(&mut self, signature: &FnSignature) -> Cancelable<()> { 1157 fn collect_fn_signature(&mut self, signature: &FnSignature) {
1182 let body = Arc::clone(&self.body); // avoid borrow checker problem 1158 let body = Arc::clone(&self.body); // avoid borrow checker problem
1183 for (type_ref, pat) in signature.params().iter().zip(body.params()) { 1159 for (type_ref, pat) in signature.params().iter().zip(body.params()) {
1184 let ty = self.make_ty(type_ref)?; 1160 let ty = self.make_ty(type_ref);
1185 let ty = self.insert_type_vars(ty); 1161 let ty = self.insert_type_vars(ty);
1186 self.write_pat_ty(*pat, ty); 1162 self.write_pat_ty(*pat, ty);
1187 } 1163 }
1188 self.return_ty = { 1164 self.return_ty = {
1189 let ty = self.make_ty(signature.ret_type())?; 1165 let ty = self.make_ty(signature.ret_type());
1190 let ty = self.insert_type_vars(ty); 1166 let ty = self.insert_type_vars(ty);
1191 ty 1167 ty
1192 }; 1168 };
1193 Ok(())
1194 } 1169 }
1195 1170
1196 fn infer_body(&mut self) -> Cancelable<()> { 1171 fn infer_body(&mut self) {
1197 self.infer_expr( 1172 self.infer_expr(
1198 self.body.body_expr(), 1173 self.body.body_expr(),
1199 &Expectation::has_type(self.return_ty.clone()), 1174 &Expectation::has_type(self.return_ty.clone()),
1200 )?; 1175 );
1201 Ok(())
1202 } 1176 }
1203} 1177}
1204 1178
1205pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<InferenceResult>> { 1179pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Arc<InferenceResult> {
1206 db.check_canceled(); 1180 db.check_canceled();
1207 let function = Function::new(def_id); // TODO: consts also need inference 1181 let function = Function::new(def_id); // TODO: consts also need inference
1208 let body = function.body(db); 1182 let body = function.body(db);
@@ -1212,9 +1186,9 @@ pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<InferenceRe
1212 let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block); 1186 let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block);
1213 1187
1214 let signature = function.signature(db); 1188 let signature = function.signature(db);
1215 ctx.collect_fn_signature(&signature)?; 1189 ctx.collect_fn_signature(&signature);
1216 1190
1217 ctx.infer_body()?; 1191 ctx.infer_body();
1218 1192
1219 Ok(Arc::new(ctx.resolve_all())) 1193 Arc::new(ctx.resolve_all())
1220} 1194}
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index 94c5124a9..b221bd142 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -6,7 +6,7 @@ use std::sync::Arc;
6 6
7use rustc_hash::FxHashMap; 7use rustc_hash::FxHashMap;
8 8
9use ra_db::{Cancelable, SourceRootId}; 9use ra_db::SourceRootId;
10 10
11use crate::{HirDatabase, DefId, module_tree::ModuleId, Module, Crate, Name, Function, impl_block::{ImplId, ImplBlock, ImplItem}}; 11use crate::{HirDatabase, DefId, module_tree::ModuleId, Module, Crate, Name, Function, impl_block::{ImplId, ImplBlock, ImplItem}};
12use super::Ty; 12use super::Ty;
@@ -42,7 +42,7 @@ impl CrateImplBlocks {
42 &'a self, 42 &'a self,
43 db: &'a impl HirDatabase, 43 db: &'a impl HirDatabase,
44 ty: &Ty, 44 ty: &Ty,
45 ) -> impl Iterator<Item = Cancelable<ImplBlock>> + 'a { 45 ) -> impl Iterator<Item = ImplBlock> + 'a {
46 let fingerprint = TyFingerprint::for_impl(ty); 46 let fingerprint = TyFingerprint::for_impl(ty);
47 fingerprint 47 fingerprint
48 .and_then(|f| self.impls.get(&f)) 48 .and_then(|f| self.impls.get(&f))
@@ -50,11 +50,11 @@ impl CrateImplBlocks {
50 .flat_map(|i| i.iter()) 50 .flat_map(|i| i.iter())
51 .map(move |(module_id, impl_id)| { 51 .map(move |(module_id, impl_id)| {
52 let module_impl_blocks = db.impls_in_module(self.source_root_id, *module_id); 52 let module_impl_blocks = db.impls_in_module(self.source_root_id, *module_id);
53 Ok(ImplBlock::from_id(module_impl_blocks, *impl_id)) 53 ImplBlock::from_id(module_impl_blocks, *impl_id)
54 }) 54 })
55 } 55 }
56 56
57 fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) -> Cancelable<()> { 57 fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) {
58 let module_id = module.def_id.loc(db).module_id; 58 let module_id = module.def_id.loc(db).module_id;
59 let module_impl_blocks = db.impls_in_module(self.source_root_id, module_id); 59 let module_impl_blocks = db.impls_in_module(self.source_root_id, module_id);
60 60
@@ -65,7 +65,7 @@ impl CrateImplBlocks {
65 // ignore for now 65 // ignore for now
66 } else { 66 } else {
67 let target_ty = 67 let target_ty =
68 Ty::from_hir(db, &module, Some(&impl_block), impl_data.target_type())?; 68 Ty::from_hir(db, &module, Some(&impl_block), impl_data.target_type());
69 if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { 69 if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) {
70 self.impls 70 self.impls
71 .entry(target_ty_fp) 71 .entry(target_ty_fp)
@@ -76,16 +76,14 @@ impl CrateImplBlocks {
76 } 76 }
77 77
78 for child in module.children(db) { 78 for child in module.children(db) {
79 self.collect_recursive(db, child)?; 79 self.collect_recursive(db, child);
80 } 80 }
81
82 Ok(())
83 } 81 }
84 82
85 pub(crate) fn impls_in_crate_query( 83 pub(crate) fn impls_in_crate_query(
86 db: &impl HirDatabase, 84 db: &impl HirDatabase,
87 krate: Crate, 85 krate: Crate,
88 ) -> Cancelable<Arc<CrateImplBlocks>> { 86 ) -> Arc<CrateImplBlocks> {
89 let crate_graph = db.crate_graph(); 87 let crate_graph = db.crate_graph();
90 let file_id = crate_graph.crate_root(krate.crate_id); 88 let file_id = crate_graph.crate_root(krate.crate_id);
91 let source_root_id = db.file_source_root(file_id); 89 let source_root_id = db.file_source_root(file_id);
@@ -94,9 +92,9 @@ impl CrateImplBlocks {
94 impls: FxHashMap::default(), 92 impls: FxHashMap::default(),
95 }; 93 };
96 if let Some(module) = krate.root_module(db) { 94 if let Some(module) = krate.root_module(db) {
97 crate_impl_blocks.collect_recursive(db, module)?; 95 crate_impl_blocks.collect_recursive(db, module);
98 } 96 }
99 Ok(Arc::new(crate_impl_blocks)) 97 Arc::new(crate_impl_blocks)
100 } 98 }
101} 99}
102 100
@@ -111,13 +109,13 @@ impl Ty {
111 // TODO: cache this as a query? 109 // TODO: cache this as a query?
112 // - if so, what signature? (TyFingerprint, Name)? 110 // - if so, what signature? (TyFingerprint, Name)?
113 // - or maybe cache all names and def_ids of methods per fingerprint? 111 // - or maybe cache all names and def_ids of methods per fingerprint?
114 pub fn lookup_method(self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<DefId>> { 112 pub fn lookup_method(self, db: &impl HirDatabase, name: &Name) -> Option<DefId> {
115 self.iterate_methods(db, |f| { 113 self.iterate_methods(db, |f| {
116 let sig = f.signature(db); 114 let sig = f.signature(db);
117 if sig.name() == name && sig.has_self_param() { 115 if sig.name() == name && sig.has_self_param() {
118 Ok(Some(f.def_id())) 116 Some(f.def_id())
119 } else { 117 } else {
120 Ok(None) 118 None
121 } 119 }
122 }) 120 })
123 } 121 }
@@ -127,8 +125,8 @@ impl Ty {
127 pub fn iterate_methods<T>( 125 pub fn iterate_methods<T>(
128 self, 126 self,
129 db: &impl HirDatabase, 127 db: &impl HirDatabase,
130 mut callback: impl FnMut(Function) -> Cancelable<Option<T>>, 128 mut callback: impl FnMut(Function) -> Option<T>,
131 ) -> Cancelable<Option<T>> { 129 ) -> Option<T> {
132 // For method calls, rust first does any number of autoderef, and then one 130 // For method calls, rust first does any number of autoderef, and then one
133 // autoref (i.e. when the method takes &self or &mut self). We just ignore 131 // autoref (i.e. when the method takes &self or &mut self). We just ignore
134 // the autoref currently -- when we find a method matching the given name, 132 // the autoref currently -- when we find a method matching the given name,
@@ -143,15 +141,14 @@ impl Ty {
143 Some(krate) => krate, 141 Some(krate) => krate,
144 None => continue, 142 None => continue,
145 }; 143 };
146 let impls = db.impls_in_crate(krate)?; 144 let impls = db.impls_in_crate(krate);
147 145
148 for impl_block in impls.lookup_impl_blocks(db, &derefed_ty) { 146 for impl_block in impls.lookup_impl_blocks(db, &derefed_ty) {
149 let impl_block = impl_block?;
150 for item in impl_block.items() { 147 for item in impl_block.items() {
151 match item { 148 match item {
152 ImplItem::Method(f) => { 149 ImplItem::Method(f) => {
153 if let Some(result) = callback(f.clone())? { 150 if let Some(result) = callback(f.clone()) {
154 return Ok(Some(result)); 151 return Some(result);
155 } 152 }
156 } 153 }
157 _ => {} 154 _ => {}
@@ -159,6 +156,6 @@ impl Ty {
159 } 156 }
160 } 157 }
161 } 158 }
162 Ok(None) 159 None
163 } 160 }
164} 161}
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index b44ac9987..929fee04c 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -321,7 +321,7 @@ fn infer(content: &str) -> String {
321 .filter_map(ast::FnDef::cast) 321 .filter_map(ast::FnDef::cast)
322 { 322 {
323 let func = source_binder::function_from_source(&db, file_id, fn_def).unwrap(); 323 let func = source_binder::function_from_source(&db, file_id, fn_def).unwrap();
324 let inference_result = func.infer(&db).unwrap(); 324 let inference_result = func.infer(&db);
325 let body_syntax_mapping = func.body_syntax_mapping(&db); 325 let body_syntax_mapping = func.body_syntax_mapping(&db);
326 let mut types = Vec::new(); 326 let mut types = Vec::new();
327 for (pat, ty) in inference_result.type_of_pat.iter() { 327 for (pat, ty) in inference_result.type_of_pat.iter() {
@@ -405,7 +405,7 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() {
405 let func = source_binder::function_from_position(&db, pos).unwrap(); 405 let func = source_binder::function_from_position(&db, pos).unwrap();
406 { 406 {
407 let events = db.log_executed(|| { 407 let events = db.log_executed(|| {
408 func.infer(&db).unwrap(); 408 func.infer(&db);
409 }); 409 });
410 assert!(format!("{:?}", events).contains("infer")) 410 assert!(format!("{:?}", events).contains("infer"))
411 } 411 }
@@ -424,7 +424,7 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() {
424 424
425 { 425 {
426 let events = db.log_executed(|| { 426 let events = db.log_executed(|| {
427 func.infer(&db).unwrap(); 427 func.infer(&db);
428 }); 428 });
429 assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events) 429 assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events)
430 } 430 }