aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/traits/chalk.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-05-12 19:36:36 +0100
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-05-12 19:36:36 +0100
commit0f57564f78207946fdb09e0cddc21a55966b1bc5 (patch)
treee8aa2948b2bb301f453307c35311634cda5de43b /crates/ra_hir/src/ty/traits/chalk.rs
parent02ba107bbf24b1d09e61f76bb64b7355076744c4 (diff)
parentbc59f83991a6444ff2f2364b0e942e8a82943b6d (diff)
Merge #1266
1266: Chalk integration / method resolution fixes r=matklad a=flodiebold - fix impl blocks with unresolved target trait being treated as inherent impls - add traits from prelude for method resolution, and deduplicate them - blacklist some traits from being considered in where clauses, namely `Send`, `Sync`, `Sized`, and the `Fn` traits. We don't handle these correctly yet for several reasons, and this makes us much less likely to run into cases where Chalk gets very slow (because these usually only happen if there is no solution, and that's more likely to happen for these traits). - when there's an errored where clause, return just that one (since it will be always false anyway). This also makes things easier on Chalk ;) Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/ty/traits/chalk.rs')
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs29
1 files changed, 28 insertions, 1 deletions
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index 027c5ec4c..78440b258 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -190,6 +190,14 @@ fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> {
190 } 190 }
191} 191}
192 192
193fn blacklisted_trait(db: &impl HirDatabase, trait_: Trait) -> bool {
194 let name = trait_.name(db).unwrap_or_else(crate::Name::missing).to_string();
195 match &*name {
196 "Send" | "Sync" | "Sized" | "Fn" | "FnMut" | "FnOnce" => true,
197 _ => false,
198 }
199}
200
193fn convert_where_clauses( 201fn convert_where_clauses(
194 db: &impl HirDatabase, 202 db: &impl HirDatabase,
195 def: GenericDef, 203 def: GenericDef,
@@ -198,6 +206,19 @@ fn convert_where_clauses(
198 let generic_predicates = db.generic_predicates(def); 206 let generic_predicates = db.generic_predicates(def);
199 let mut result = Vec::with_capacity(generic_predicates.len()); 207 let mut result = Vec::with_capacity(generic_predicates.len());
200 for pred in generic_predicates.iter() { 208 for pred in generic_predicates.iter() {
209 if pred.is_error() {
210 // HACK: Return just the single predicate (which is always false
211 // anyway), otherwise Chalk can easily get into slow situations
212 return vec![pred.clone().subst(substs).to_chalk(db)];
213 }
214 match pred {
215 GenericPredicate::Implemented(trait_ref) => {
216 if blacklisted_trait(db, trait_ref.trait_) {
217 continue;
218 }
219 }
220 _ => {}
221 }
201 result.push(pred.clone().subst(substs).to_chalk(db)); 222 result.push(pred.clone().subst(substs).to_chalk(db));
202 } 223 }
203 result 224 result
@@ -230,6 +251,7 @@ where
230 return Arc::new(TraitDatum { binders: make_binders(trait_datum_bound, 1) }); 251 return Arc::new(TraitDatum { binders: make_binders(trait_datum_bound, 1) });
231 } 252 }
232 let trait_: Trait = from_chalk(self.db, trait_id); 253 let trait_: Trait = from_chalk(self.db, trait_id);
254 debug!("trait {:?} = {:?}", trait_id, trait_.name(self.db));
233 let generic_params = trait_.generic_params(self.db); 255 let generic_params = trait_.generic_params(self.db);
234 let bound_vars = Substs::bound_vars(&generic_params); 256 let bound_vars = Substs::bound_vars(&generic_params);
235 let trait_ref = trait_.trait_ref(self.db).subst(&bound_vars).to_chalk(self.db); 257 let trait_ref = trait_.trait_ref(self.db).subst(&bound_vars).to_chalk(self.db);
@@ -250,6 +272,7 @@ where
250 fn struct_datum(&self, struct_id: chalk_ir::StructId) -> Arc<StructDatum> { 272 fn struct_datum(&self, struct_id: chalk_ir::StructId) -> Arc<StructDatum> {
251 debug!("struct_datum {:?}", struct_id); 273 debug!("struct_datum {:?}", struct_id);
252 let type_ctor = from_chalk(self.db, struct_id); 274 let type_ctor = from_chalk(self.db, struct_id);
275 debug!("struct {:?} = {:?}", struct_id, type_ctor);
253 // FIXME might be nicer if we can create a fake GenericParams for the TypeCtor 276 // FIXME might be nicer if we can create a fake GenericParams for the TypeCtor
254 // FIXME extract this to a method on Ty 277 // FIXME extract this to a method on Ty
255 let (num_params, where_clauses, upstream) = match type_ctor { 278 let (num_params, where_clauses, upstream) = match type_ctor {
@@ -358,7 +381,11 @@ where
358 if trait_id == UNKNOWN_TRAIT { 381 if trait_id == UNKNOWN_TRAIT {
359 return Vec::new(); 382 return Vec::new();
360 } 383 }
361 let trait_ = from_chalk(self.db, trait_id); 384 let trait_: Trait = from_chalk(self.db, trait_id);
385 let blacklisted = blacklisted_trait(self.db, trait_);
386 if blacklisted {
387 return Vec::new();
388 }
362 let result: Vec<_> = self 389 let result: Vec<_> = self
363 .db 390 .db
364 .impls_for_trait(self.krate, trait_) 391 .impls_for_trait(self.krate, trait_)