aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-06-04 23:14:46 +0100
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-06-04 23:14:46 +0100
commit5deb907b4321d8328978d3322b0826b781814452 (patch)
tree2baa3b75b1ef62c02617c37ba9b800c41a3dd102 /crates/ra_hir/src
parent8bd0e844247dc28d6ceb24b00f3cc3396bd5bf03 (diff)
parentaa30c4909ebb1e85f1591f465c9e2875aa4d394e (diff)
Merge #1374
1374: Implement `cargo lint` and fix some clippy errors r=alanhdu a=alanhdu This creates a `cargo lint` command that runs clippy with certain lints disabled. I've also gone ahead and fixed some of the lint errors, although there are many more still to go. cc #848 Co-authored-by: Alan Du <[email protected]>
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/adt.rs2
-rw-r--r--crates/ra_hir/src/code_model.rs5
-rw-r--r--crates/ra_hir/src/expr/validation.rs11
-rw-r--r--crates/ra_hir/src/impl_block.rs1
-rw-r--r--crates/ra_hir/src/lang_item.rs2
-rw-r--r--crates/ra_hir/src/nameres.rs27
-rw-r--r--crates/ra_hir/src/nameres/collector.rs2
-rw-r--r--crates/ra_hir/src/nameres/raw.rs2
-rw-r--r--crates/ra_hir/src/path.rs4
-rw-r--r--crates/ra_hir/src/source_binder.rs11
-rw-r--r--crates/ra_hir/src/traits.rs9
-rw-r--r--crates/ra_hir/src/ty.rs2
-rw-r--r--crates/ra_hir/src/ty/infer.rs43
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs38
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs9
15 files changed, 73 insertions, 95 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs
index 45a12dd4d..38ff1d6f6 100644
--- a/crates/ra_hir/src/adt.rs
+++ b/crates/ra_hir/src/adt.rs
@@ -36,7 +36,7 @@ impl AdtDef {
36 36
37impl Struct { 37impl Struct {
38 pub(crate) fn variant_data(&self, db: &impl DefDatabase) -> Arc<VariantData> { 38 pub(crate) fn variant_data(&self, db: &impl DefDatabase) -> Arc<VariantData> {
39 db.struct_data((*self).into()).variant_data.clone() 39 db.struct_data(*self).variant_data.clone()
40 } 40 }
41} 41}
42 42
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 9c02b3995..6ee6bd627 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -281,9 +281,8 @@ impl Module {
281 281
282 for impl_block in self.impl_blocks(db) { 282 for impl_block in self.impl_blocks(db) {
283 for item in impl_block.items(db) { 283 for item in impl_block.items(db) {
284 match item { 284 if let crate::ImplItem::Method(f) = item {
285 crate::ImplItem::Method(f) => f.diagnostics(db, sink), 285 f.diagnostics(db, sink);
286 _ => (),
287 } 286 }
288 } 287 }
289 } 288 }
diff --git a/crates/ra_hir/src/expr/validation.rs b/crates/ra_hir/src/expr/validation.rs
index 2816144a7..a1b2641da 100644
--- a/crates/ra_hir/src/expr/validation.rs
+++ b/crates/ra_hir/src/expr/validation.rs
@@ -31,11 +31,8 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
31 pub(crate) fn validate_body(&mut self, db: &impl HirDatabase) { 31 pub(crate) fn validate_body(&mut self, db: &impl HirDatabase) {
32 let body = self.func.body(db); 32 let body = self.func.body(db);
33 for e in body.exprs() { 33 for e in body.exprs() {
34 match e { 34 if let (id, Expr::StructLit { path, fields, spread }) = e {
35 (id, Expr::StructLit { path, fields, spread }) => { 35 self.validate_struct_literal(id, path, fields, spread, db);
36 self.validate_struct_literal(id, path, fields, spread, db)
37 }
38 _ => (),
39 } 36 }
40 } 37 }
41 } 38 }
@@ -44,7 +41,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
44 &mut self, 41 &mut self,
45 id: ExprId, 42 id: ExprId,
46 _path: &Option<Path>, 43 _path: &Option<Path>,
47 fields: &Vec<StructLitField>, 44 fields: &[StructLitField],
48 spread: &Option<ExprId>, 45 spread: &Option<ExprId>,
49 db: &impl HirDatabase, 46 db: &impl HirDatabase,
50 ) { 47 ) {
@@ -57,7 +54,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
57 _ => return, 54 _ => return,
58 }; 55 };
59 56
60 let lit_fields: FxHashSet<_> = fields.into_iter().map(|f| &f.name).collect(); 57 let lit_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
61 let missed_fields: Vec<Name> = struct_def 58 let missed_fields: Vec<Name> = struct_def
62 .fields(db) 59 .fields(db)
63 .iter() 60 .iter()
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index ba90e67e9..a0d3b33fe 100644
--- a/crates/ra_hir/src/impl_block.rs
+++ b/crates/ra_hir/src/impl_block.rs
@@ -202,7 +202,6 @@ impl ModuleImplBlocks {
202 }; 202 };
203 203
204 let (file_id, module_source) = m.module.definition_source(db); 204 let (file_id, module_source) = m.module.definition_source(db);
205 let file_id: HirFileId = file_id.into();
206 let node = match &module_source { 205 let node = match &module_source {
207 ModuleSource::SourceFile(node) => node.syntax(), 206 ModuleSource::SourceFile(node) => node.syntax(),
208 ModuleSource::Module(node) => { 207 ModuleSource::Module(node) => {
diff --git a/crates/ra_hir/src/lang_item.rs b/crates/ra_hir/src/lang_item.rs
index 4cacaeba4..684fbc068 100644
--- a/crates/ra_hir/src/lang_item.rs
+++ b/crates/ra_hir/src/lang_item.rs
@@ -95,7 +95,7 @@ impl LangItems {
95 .nth(0); 95 .nth(0);
96 if let Some(lang_item_name) = lang_item_name { 96 if let Some(lang_item_name) = lang_item_name {
97 let imp = ImplBlock::from_id(*module, impl_id); 97 let imp = ImplBlock::from_id(*module, impl_id);
98 self.items.entry(lang_item_name).or_insert(LangItemTarget::ImplBlock(imp)); 98 self.items.entry(lang_item_name).or_insert_with(|| LangItemTarget::ImplBlock(imp));
99 } 99 }
100 } 100 }
101 101
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index d649aa820..8b798d6c9 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -332,7 +332,8 @@ impl CrateDefMap {
332 let name = path.expand_macro_expr()?; 332 let name = path.expand_macro_expr()?;
333 // search local first 333 // search local first
334 // FIXME: Remove public_macros check when we have a correct local_macors implementation 334 // FIXME: Remove public_macros check when we have a correct local_macors implementation
335 let local = self.public_macros.get(&name).or(self.local_macros.get(&name)).map(|it| *it); 335 let local =
336 self.public_macros.get(&name).or_else(|| self.local_macros.get(&name)).map(|it| *it);
336 if local.is_some() { 337 if local.is_some() {
337 return local; 338 return local;
338 } 339 }
@@ -405,7 +406,7 @@ impl CrateDefMap {
405 }; 406 };
406 407
407 for (i, segment) in segments { 408 for (i, segment) in segments {
408 let curr = match curr_per_ns.as_ref().left().map_or(None, |m| m.as_ref().take_types()) { 409 let curr = match curr_per_ns.as_ref().left().and_then(|m| m.as_ref().take_types()) {
409 Some(r) => r, 410 Some(r) => r,
410 None => { 411 None => {
411 // we still have path segments left, but the path so far 412 // we still have path segments left, but the path so far
@@ -421,10 +422,8 @@ impl CrateDefMap {
421 curr_per_ns = match curr { 422 curr_per_ns = match curr {
422 ModuleDef::Module(module) => { 423 ModuleDef::Module(module) => {
423 if module.krate != self.krate { 424 if module.krate != self.krate {
424 let path = Path { 425 let path =
425 segments: path.segments[i..].iter().cloned().collect(), 426 Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ };
426 kind: PathKind::Self_,
427 };
428 log::debug!("resolving {:?} in other crate", path); 427 log::debug!("resolving {:?} in other crate", path);
429 let defp_map = db.crate_def_map(module.krate); 428 let defp_map = db.crate_def_map(module.krate);
430 let (def, s) = 429 let (def, s) =
@@ -468,7 +467,7 @@ impl CrateDefMap {
468 ); 467 );
469 468
470 return ResolvePathResult::with( 469 return ResolvePathResult::with(
471 Either::Left(PerNs::types((*s).into())), 470 Either::Left(PerNs::types(*s)),
472 ReachedFixedPoint::Yes, 471 ReachedFixedPoint::Yes,
473 Some(i), 472 Some(i),
474 ); 473 );
@@ -479,8 +478,10 @@ impl CrateDefMap {
479 } 478 }
480 479
481 fn resolve_name_in_crate_root_or_extern_prelude(&self, name: &Name) -> ItemOrMacro { 480 fn resolve_name_in_crate_root_or_extern_prelude(&self, name: &Name) -> ItemOrMacro {
482 let from_crate_root = 481 let from_crate_root = self[self.root]
483 self[self.root].scope.get_item_or_macro(name).unwrap_or(Either::Left(PerNs::none())); 482 .scope
483 .get_item_or_macro(name)
484 .unwrap_or_else(|| Either::Left(PerNs::none()));
484 let from_extern_prelude = self.resolve_name_in_extern_prelude(name); 485 let from_extern_prelude = self.resolve_name_in_extern_prelude(name);
485 486
486 or(from_crate_root, Either::Left(from_extern_prelude)) 487 or(from_crate_root, Either::Left(from_extern_prelude))
@@ -505,8 +506,10 @@ impl CrateDefMap {
505 // - current module / scope 506 // - current module / scope
506 // - extern prelude 507 // - extern prelude
507 // - std prelude 508 // - std prelude
508 let from_scope = 509 let from_scope = self[module]
509 self[module].scope.get_item_or_macro(name).unwrap_or(Either::Left(PerNs::none()));; 510 .scope
511 .get_item_or_macro(name)
512 .unwrap_or_else(|| Either::Left(PerNs::none()));;
510 let from_extern_prelude = 513 let from_extern_prelude =
511 self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); 514 self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it));
512 let from_prelude = self.resolve_in_prelude(db, name); 515 let from_prelude = self.resolve_in_prelude(db, name);
@@ -525,7 +528,7 @@ impl CrateDefMap {
525 } else { 528 } else {
526 db.crate_def_map(prelude.krate)[prelude.module_id].scope.get_item_or_macro(name) 529 db.crate_def_map(prelude.krate)[prelude.module_id].scope.get_item_or_macro(name)
527 }; 530 };
528 resolution.unwrap_or(Either::Left(PerNs::none())) 531 resolution.unwrap_or_else(|| Either::Left(PerNs::none()))
529 } else { 532 } else {
530 Either::Left(PerNs::none()) 533 Either::Left(PerNs::none())
531 } 534 }
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index 693c3fe8e..3bfef799d 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -556,7 +556,7 @@ where
556 556
557 fn define_def(&mut self, def: &raw::DefData) { 557 fn define_def(&mut self, def: &raw::DefData) {
558 let module = Module { krate: self.def_collector.def_map.krate, module_id: self.module_id }; 558 let module = Module { krate: self.def_collector.def_map.krate, module_id: self.module_id };
559 let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id.into()); 559 let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id);
560 560
561 macro_rules! def { 561 macro_rules! def {
562 ($kind:ident, $ast_id:ident) => { 562 ($kind:ident, $ast_id:ident) => {
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs
index 21935dbb9..a0afe282c 100644
--- a/crates/ra_hir/src/nameres/raw.rs
+++ b/crates/ra_hir/src/nameres/raw.rs
@@ -69,7 +69,7 @@ impl RawItems {
69 ) -> (Arc<RawItems>, Arc<ImportSourceMap>) { 69 ) -> (Arc<RawItems>, Arc<ImportSourceMap>) {
70 let mut collector = RawItemsCollector { 70 let mut collector = RawItemsCollector {
71 raw_items: RawItems::default(), 71 raw_items: RawItems::default(),
72 source_ast_id_map: db.ast_id_map(file_id.into()), 72 source_ast_id_map: db.ast_id_map(file_id),
73 source_map: ImportSourceMap::default(), 73 source_map: ImportSourceMap::default(),
74 }; 74 };
75 if let Some(node) = db.parse_or_expand(file_id) { 75 if let Some(node) = db.parse_or_expand(file_id) {
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs
index 1b129c752..67afd5027 100644
--- a/crates/ra_hir/src/path.rs
+++ b/crates/ra_hir/src/path.rs
@@ -116,7 +116,7 @@ impl Path {
116 116
117 /// `true` if this path is just a standalone `self` 117 /// `true` if this path is just a standalone `self`
118 pub fn is_self(&self) -> bool { 118 pub fn is_self(&self) -> bool {
119 self.kind == PathKind::Self_ && self.segments.len() == 0 119 self.kind == PathKind::Self_ && self.segments.is_empty()
120 } 120 }
121 121
122 /// If this path is a single identifier, like `foo`, return its name. 122 /// If this path is a single identifier, like `foo`, return its name.
@@ -140,7 +140,7 @@ impl GenericArgs {
140 args.push(GenericArg::Type(type_ref)); 140 args.push(GenericArg::Type(type_ref));
141 } 141 }
142 // lifetimes and assoc type args ignored for now 142 // lifetimes and assoc type args ignored for now
143 if args.len() > 0 { 143 if !args.is_empty() {
144 Some(GenericArgs { args }) 144 Some(GenericArgs { args })
145 } else { 145 } else {
146 None 146 None
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 75ed2de6c..6a5799622 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -48,8 +48,8 @@ pub fn module_from_declaration(
48pub fn module_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Module> { 48pub fn module_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Module> {
49 let file = db.parse(position.file_id).tree; 49 let file = db.parse(position.file_id).tree;
50 match find_node_at_offset::<ast::Module>(file.syntax(), position.offset) { 50 match find_node_at_offset::<ast::Module>(file.syntax(), position.offset) {
51 Some(m) if !m.has_semi() => module_from_inline(db, position.file_id.into(), m), 51 Some(m) if !m.has_semi() => module_from_inline(db, position.file_id, m),
52 _ => module_from_file_id(db, position.file_id.into()), 52 _ => module_from_file_id(db, position.file_id),
53 } 53 }
54} 54}
55 55
@@ -72,9 +72,9 @@ pub fn module_from_child_node(
72 child: &SyntaxNode, 72 child: &SyntaxNode,
73) -> Option<Module> { 73) -> Option<Module> {
74 if let Some(m) = child.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) { 74 if let Some(m) = child.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) {
75 module_from_inline(db, file_id.into(), m) 75 module_from_inline(db, file_id, m)
76 } else { 76 } else {
77 module_from_file_id(db, file_id.into()) 77 module_from_file_id(db, file_id)
78 } 78 }
79} 79}
80 80
@@ -99,14 +99,12 @@ pub fn struct_from_module(
99 struct_def: &ast::StructDef, 99 struct_def: &ast::StructDef,
100) -> Struct { 100) -> Struct {
101 let (file_id, _) = module.definition_source(db); 101 let (file_id, _) = module.definition_source(db);
102 let file_id = file_id.into();
103 let ctx = LocationCtx::new(db, module, file_id); 102 let ctx = LocationCtx::new(db, module, file_id);
104 Struct { id: ctx.to_def(struct_def) } 103 Struct { id: ctx.to_def(struct_def) }
105} 104}
106 105
107pub fn enum_from_module(db: &impl HirDatabase, module: Module, enum_def: &ast::EnumDef) -> Enum { 106pub fn enum_from_module(db: &impl HirDatabase, module: Module, enum_def: &ast::EnumDef) -> Enum {
108 let (file_id, _) = module.definition_source(db); 107 let (file_id, _) = module.definition_source(db);
109 let file_id = file_id.into();
110 let ctx = LocationCtx::new(db, module, file_id); 108 let ctx = LocationCtx::new(db, module, file_id);
111 Enum { id: ctx.to_def(enum_def) } 109 Enum { id: ctx.to_def(enum_def) }
112} 110}
@@ -117,7 +115,6 @@ pub fn trait_from_module(
117 trait_def: &ast::TraitDef, 115 trait_def: &ast::TraitDef,
118) -> Trait { 116) -> Trait {
119 let (file_id, _) = module.definition_source(db); 117 let (file_id, _) = module.definition_source(db);
120 let file_id = file_id.into();
121 let ctx = LocationCtx::new(db, module, file_id); 118 let ctx = LocationCtx::new(db, module, file_id);
122 Trait { id: ctx.to_def(trait_def) } 119 Trait { id: ctx.to_def(trait_def) }
123} 120}
diff --git a/crates/ra_hir/src/traits.rs b/crates/ra_hir/src/traits.rs
index 2a7c2b791..967654e97 100644
--- a/crates/ra_hir/src/traits.rs
+++ b/crates/ra_hir/src/traits.rs
@@ -77,13 +77,10 @@ impl TraitItemsIndex {
77 pub(crate) fn trait_items_index(db: &impl DefDatabase, module: Module) -> TraitItemsIndex { 77 pub(crate) fn trait_items_index(db: &impl DefDatabase, module: Module) -> TraitItemsIndex {
78 let mut index = TraitItemsIndex { traits_by_def: FxHashMap::default() }; 78 let mut index = TraitItemsIndex { traits_by_def: FxHashMap::default() };
79 for decl in module.declarations(db) { 79 for decl in module.declarations(db) {
80 match decl { 80 if let crate::ModuleDef::Trait(tr) = decl {
81 crate::ModuleDef::Trait(tr) => { 81 for item in tr.trait_data(db).items() {
82 for item in tr.trait_data(db).items() { 82 index.traits_by_def.insert(*item, tr);
83 index.traits_by_def.insert(*item, tr);
84 }
85 } 83 }
86 _ => {}
87 } 84 }
88 } 85 }
89 index 86 index
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 76d34c12b..4a37e0268 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -451,7 +451,7 @@ impl Ty {
451 /// Substitutes `Ty::Bound` vars (as opposed to type parameters). 451 /// Substitutes `Ty::Bound` vars (as opposed to type parameters).
452 pub fn subst_bound_vars(self, substs: &Substs) -> Ty { 452 pub fn subst_bound_vars(self, substs: &Substs) -> Ty {
453 self.fold(&mut |ty| match ty { 453 self.fold(&mut |ty| match ty {
454 Ty::Bound(idx) => substs.get(idx as usize).cloned().unwrap_or(Ty::Bound(idx)), 454 Ty::Bound(idx) => substs.get(idx as usize).cloned().unwrap_or_else(|| Ty::Bound(idx)),
455 ty => ty, 455 ty => ty,
456 }) 456 })
457 } 457 }
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index e8ae33ead..905fe9f0e 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -462,7 +462,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
462 let mut resolved = 462 let mut resolved =
463 if remaining_index.is_none() { def.take_values()? } else { def.take_types()? }; 463 if remaining_index.is_none() { def.take_values()? } else { def.take_types()? };
464 464
465 let remaining_index = remaining_index.unwrap_or(path.segments.len()); 465 let remaining_index = remaining_index.unwrap_or_else(|| path.segments.len());
466 let mut actual_def_ty: Option<Ty> = None; 466 let mut actual_def_ty: Option<Ty> = None;
467 467
468 let krate = resolver.krate()?; 468 let krate = resolver.krate()?;
@@ -539,7 +539,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
539 } 539 }
540 })?; 540 })?;
541 541
542 resolved = Resolution::Def(item.into()); 542 resolved = Resolution::Def(item);
543 } 543 }
544 544
545 match resolved { 545 match resolved {
@@ -762,7 +762,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
762 _ => &Ty::Unknown, 762 _ => &Ty::Unknown,
763 }; 763 };
764 let subty = self.infer_pat(*pat, expectation, default_bm); 764 let subty = self.infer_pat(*pat, expectation, default_bm);
765 Ty::apply_one(TypeCtor::Ref(*mutability), subty.into()) 765 Ty::apply_one(TypeCtor::Ref(*mutability), subty)
766 } 766 }
767 Pat::TupleStruct { path: ref p, args: ref subpats } => { 767 Pat::TupleStruct { path: ref p, args: ref subpats } => {
768 self.infer_tuple_struct_pat(p.as_ref(), subpats, expected, default_bm) 768 self.infer_tuple_struct_pat(p.as_ref(), subpats, expected, default_bm)
@@ -790,7 +790,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
790 790
791 let bound_ty = match mode { 791 let bound_ty = match mode {
792 BindingMode::Ref(mutability) => { 792 BindingMode::Ref(mutability) => {
793 Ty::apply_one(TypeCtor::Ref(mutability), inner_ty.clone().into()) 793 Ty::apply_one(TypeCtor::Ref(mutability), inner_ty.clone())
794 } 794 }
795 BindingMode::Move => inner_ty.clone(), 795 BindingMode::Move => inner_ty.clone(),
796 }; 796 };
@@ -848,28 +848,23 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
848 } 848 }
849 849
850 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 850 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
851 match callable_ty { 851 if let Ty::Apply(a_ty) = callable_ty {
852 Ty::Apply(a_ty) => match a_ty.ctor { 852 if let TypeCtor::FnDef(def) = a_ty.ctor {
853 TypeCtor::FnDef(def) => { 853 // add obligation for trait implementation, if this is a trait method
854 // add obligation for trait implementation, if this is a trait method 854 // FIXME also register obligations from where clauses from the trait or impl and method
855 // FIXME also register obligations from where clauses from the trait or impl and method 855 match def {
856 match def { 856 CallableDef::Function(f) => {
857 CallableDef::Function(f) => { 857 if let Some(trait_) = f.parent_trait(self.db) {
858 if let Some(trait_) = f.parent_trait(self.db) { 858 // construct a TraitDef
859 // construct a TraitDef 859 let substs = a_ty.parameters.prefix(
860 let substs = a_ty.parameters.prefix( 860 trait_.generic_params(self.db).count_params_including_parent(),
861 trait_.generic_params(self.db).count_params_including_parent(), 861 );
862 ); 862 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
863 self.obligations
864 .push(Obligation::Trait(TraitRef { trait_, substs }));
865 }
866 } 863 }
867 CallableDef::Struct(_) | CallableDef::EnumVariant(_) => {}
868 } 864 }
865 CallableDef::Struct(_) | CallableDef::EnumVariant(_) => {}
869 } 866 }
870 _ => {} 867 }
871 },
872 _ => {}
873 } 868 }
874 } 869 }
875 870
@@ -1049,7 +1044,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1049 Expr::StructLit { path, fields, spread } => { 1044 Expr::StructLit { path, fields, spread } => {
1050 let (ty, def_id) = self.resolve_variant(path.as_ref()); 1045 let (ty, def_id) = self.resolve_variant(path.as_ref());
1051 let substs = ty.substs().unwrap_or_else(Substs::empty); 1046 let substs = ty.substs().unwrap_or_else(Substs::empty);
1052 for (field_idx, field) in fields.into_iter().enumerate() { 1047 for (field_idx, field) in fields.iter().enumerate() {
1053 let field_ty = def_id 1048 let field_ty = def_id
1054 .and_then(|it| match it.field(self.db, &field.name) { 1049 .and_then(|it| match it.field(self.db, &field.name) {
1055 Some(field) => Some(field), 1050 Some(field) => Some(field),
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index 34817a5ec..646e58aa9 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -192,23 +192,20 @@ fn iterate_trait_method_candidates<T>(
192 // iteration 192 // iteration
193 let mut known_implemented = false; 193 let mut known_implemented = false;
194 for item in data.items() { 194 for item in data.items() {
195 match item { 195 if let TraitItem::Function(m) = *item {
196 &TraitItem::Function(m) => { 196 let sig = m.signature(db);
197 let sig = m.signature(db); 197 if name.map_or(true, |name| sig.name() == name) && sig.has_self_param() {
198 if name.map_or(true, |name| sig.name() == name) && sig.has_self_param() { 198 if !known_implemented {
199 if !known_implemented { 199 let trait_ref = canonical_trait_ref(db, t, ty.clone());
200 let trait_ref = canonical_trait_ref(db, t, ty.clone()); 200 if db.implements(krate, trait_ref).is_none() {
201 if db.implements(krate, trait_ref).is_none() { 201 continue 'traits;
202 continue 'traits;
203 }
204 }
205 known_implemented = true;
206 if let Some(result) = callback(&ty.value, m) {
207 return Some(result);
208 } 202 }
209 } 203 }
204 known_implemented = true;
205 if let Some(result) = callback(&ty.value, m) {
206 return Some(result);
207 }
210 } 208 }
211 _ => {}
212 } 209 }
213 } 210 }
214 } 211 }
@@ -230,16 +227,13 @@ fn iterate_inherent_methods<T>(
230 227
231 for impl_block in impls.lookup_impl_blocks(&ty.value) { 228 for impl_block in impls.lookup_impl_blocks(&ty.value) {
232 for item in impl_block.items(db) { 229 for item in impl_block.items(db) {
233 match item { 230 if let ImplItem::Method(f) = item {
234 ImplItem::Method(f) => { 231 let sig = f.signature(db);
235 let sig = f.signature(db); 232 if name.map_or(true, |name| sig.name() == name) && sig.has_self_param() {
236 if name.map_or(true, |name| sig.name() == name) && sig.has_self_param() { 233 if let Some(result) = callback(&ty.value, f) {
237 if let Some(result) = callback(&ty.value, f) { 234 return Some(result);
238 return Some(result);
239 }
240 } 235 }
241 } 236 }
242 _ => {}
243 } 237 }
244 } 238 }
245 } 239 }
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index 78440b258..1e4806db0 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -211,13 +211,10 @@ fn convert_where_clauses(
211 // anyway), otherwise Chalk can easily get into slow situations 211 // anyway), otherwise Chalk can easily get into slow situations
212 return vec![pred.clone().subst(substs).to_chalk(db)]; 212 return vec![pred.clone().subst(substs).to_chalk(db)];
213 } 213 }
214 match pred { 214 if let GenericPredicate::Implemented(trait_ref) = pred {
215 GenericPredicate::Implemented(trait_ref) => { 215 if blacklisted_trait(db, trait_ref.trait_) {
216 if blacklisted_trait(db, trait_ref.trait_) { 216 continue;
217 continue;
218 }
219 } 217 }
220 _ => {}
221 } 218 }
222 result.push(pred.clone().subst(substs).to_chalk(db)); 219 result.push(pred.clone().subst(substs).to_chalk(db));
223 } 220 }