diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir/src/resolve.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 23 |
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 | ||
129 | fn def_crate(db: &impl HirDatabase, ty: &Ty) -> Option<Crate> { | 125 | fn 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 | } |