aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/resolve.rs2
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs23
2 files changed, 15 insertions, 10 deletions
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
index 0f5031e76..2609585b1 100644
--- a/crates/ra_hir/src/resolve.rs
+++ b/crates/ra_hir/src/resolve.rs
@@ -187,7 +187,7 @@ impl Resolver {
187 } 187 }
188 .into_iter() 188 .into_iter()
189 }) 189 })
190 .flat_map(|i| i) 190 .flatten()
191 } 191 }
192 192
193 fn module(&self) -> Option<(&CrateDefMap, CrateModuleId)> { 193 fn module(&self) -> Option<(&CrateDefMap, CrateModuleId)> {
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index 146e8a02e..3ac8dc46b 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -118,12 +118,8 @@ pub(crate) fn implements(db: &impl HirDatabase, trait_ref: TraitRef) -> bool {
118 None => return false, 118 None => return false,
119 }; 119 };
120 let crate_impl_blocks = db.impls_in_crate(krate); 120 let crate_impl_blocks = db.impls_in_crate(krate);
121 for impl_block in crate_impl_blocks.lookup_impl_blocks_for_trait(&trait_ref.trait_) { 121 let mut impl_blocks = crate_impl_blocks.lookup_impl_blocks_for_trait(&trait_ref.trait_);
122 if &impl_block.target_ty(db) == trait_ref.self_ty() { 122 impl_blocks.any(|impl_block| &impl_block.target_ty(db) == trait_ref.self_ty())
123 return true;
124 }
125 }
126 false
127} 123}
128 124
129fn def_crate(db: &impl HirDatabase, ty: &Ty) -> Option<Crate> { 125fn def_crate(db: &impl HirDatabase, ty: &Ty) -> Option<Crate> {
@@ -145,7 +141,7 @@ impl Ty {
145 name: &Name, 141 name: &Name,
146 resolver: &Resolver, 142 resolver: &Resolver,
147 ) -> Option<(Ty, Function)> { 143 ) -> Option<(Ty, Function)> {
148 // FIXME: what has priority, an inherent method that needs autoderefs or a trait method? 144 // FIXME: trait methods should be used before autoderefs
149 let inherent_method = self.clone().iterate_methods(db, |ty, f| { 145 let inherent_method = self.clone().iterate_methods(db, |ty, f| {
150 let sig = f.signature(db); 146 let sig = f.signature(db);
151 if sig.name() == name && sig.has_self_param() { 147 if sig.name() == name && sig.has_self_param() {
@@ -178,12 +174,21 @@ impl Ty {
178 } 174 }
179 } 175 }
180 } 176 }
181 // FIXME the implements check may result in other obligations or unifying variables? 177 // FIXME:
178 // - we might not actually be able to determine fully that the type
179 // implements the trait here; it's enough if we (well, Chalk) determine
180 // that it's possible.
181 // - when the trait method is picked, we need to register an
182 // 'obligation' somewhere so that we later check that it's really
183 // implemented
184 // - both points go for additional requirements from where clauses as
185 // well (in fact, the 'implements' condition could just be considered a
186 // 'where Self: Trait' clause)
182 candidates.retain(|(t, _m)| { 187 candidates.retain(|(t, _m)| {
183 let trait_ref = TraitRef { trait_: *t, substs: Substs::single(self.clone()) }; 188 let trait_ref = TraitRef { trait_: *t, substs: Substs::single(self.clone()) };
184 db.implements(trait_ref) 189 db.implements(trait_ref)
185 }); 190 });
186 // FIXME what happens if there are still multiple potential candidates? 191 // FIXME if there's multiple candidates here, that's an ambiguity error
187 let (_chosen_trait, chosen_method) = candidates.first()?; 192 let (_chosen_trait, chosen_method) = candidates.first()?;
188 Some((self.clone(), *chosen_method)) 193 Some((self.clone(), *chosen_method))
189 } 194 }