aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-04-02 12:25:40 +0100
committerGitHub <[email protected]>2021-04-02 12:25:40 +0100
commit00ce7ae5248b41d5944abe6075407236cde1b075 (patch)
treea7d300232f331eb2d4e854e884c8d8c0d60404c6 /crates/hir_ty/src/infer
parenta0b3eb7135361315ed953613a1a8c7a038b1562d (diff)
parent0e8c4503bf4754f4437d8bd45a110b9d0ec671e0 (diff)
Merge #8285
8285: Don't recheck obligations if we have learned nothing new r=matklad a=flodiebold This is just the most trivial check: If no inference variables have been updated, and there are no new obligations, we can just skip trying to solve them again. We could be smarter about it, but this already helps quite a bit, and I don't want to touch this too much before we replace the inference table by Chalk's. Fixes #8263 (well, improves it quite a bit). Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r--crates/hir_ty/src/infer/expr.rs6
-rw-r--r--crates/hir_ty/src/infer/path.rs2
-rw-r--r--crates/hir_ty/src/infer/unify.rs8
3 files changed, 11 insertions, 5 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 6279aa572..25ab3ea4c 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -99,7 +99,7 @@ impl<'a> InferenceContext<'a> {
99 environment: trait_env, 99 environment: trait_env,
100 }); 100 });
101 if self.db.trait_solve(krate, goal.value).is_some() { 101 if self.db.trait_solve(krate, goal.value).is_some() {
102 self.obligations.push(implements_fn_trait); 102 self.push_obligation(implements_fn_trait);
103 let output_proj_ty = crate::ProjectionTy { 103 let output_proj_ty = crate::ProjectionTy {
104 associated_ty_id: to_assoc_type_id(output_assoc_type), 104 associated_ty_id: to_assoc_type_id(output_assoc_type),
105 substitution: substs, 105 substitution: substs,
@@ -964,7 +964,7 @@ impl<'a> InferenceContext<'a> {
964 let (predicate, binders) = 964 let (predicate, binders) =
965 predicate.clone().subst(parameters).into_value_and_skipped_binders(); 965 predicate.clone().subst(parameters).into_value_and_skipped_binders();
966 always!(binders == 0); // quantified where clauses not yet handled 966 always!(binders == 0); // quantified where clauses not yet handled
967 self.obligations.push(predicate.cast(&Interner)); 967 self.push_obligation(predicate.cast(&Interner));
968 } 968 }
969 // add obligation for trait implementation, if this is a trait method 969 // add obligation for trait implementation, if this is a trait method
970 match def { 970 match def {
@@ -974,7 +974,7 @@ impl<'a> InferenceContext<'a> {
974 // construct a TraitRef 974 // construct a TraitRef
975 let substs = 975 let substs =
976 parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); 976 parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
977 self.obligations.push( 977 self.push_obligation(
978 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs } 978 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }
979 .cast(&Interner), 979 .cast(&Interner),
980 ); 980 );
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs
index cefa38509..717738789 100644
--- a/crates/hir_ty/src/infer/path.rs
+++ b/crates/hir_ty/src/infer/path.rs
@@ -258,7 +258,7 @@ impl<'a> InferenceContext<'a> {
258 .push(ty.clone()) 258 .push(ty.clone())
259 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 259 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
260 .build(); 260 .build();
261 self.obligations.push( 261 self.push_obligation(
262 TraitRef { 262 TraitRef {
263 trait_id: to_chalk_trait_id(trait_), 263 trait_id: to_chalk_trait_id(trait_),
264 substitution: trait_substs.clone(), 264 substitution: trait_substs.clone(),
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 6e7b0f5a6..5ea4b7481 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -231,6 +231,7 @@ pub(crate) struct TypeVariableData {
231pub(crate) struct InferenceTable { 231pub(crate) struct InferenceTable {
232 pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>, 232 pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>,
233 pub(super) type_variable_table: TypeVariableTable, 233 pub(super) type_variable_table: TypeVariableTable,
234 pub(super) revision: u32,
234} 235}
235 236
236impl InferenceTable { 237impl InferenceTable {
@@ -238,6 +239,7 @@ impl InferenceTable {
238 InferenceTable { 239 InferenceTable {
239 var_unification_table: InPlaceUnificationTable::new(), 240 var_unification_table: InPlaceUnificationTable::new(),
240 type_variable_table: TypeVariableTable { inner: Vec::new() }, 241 type_variable_table: TypeVariableTable { inner: Vec::new() },
242 revision: 0,
241 } 243 }
242 } 244 }
243 245
@@ -360,7 +362,10 @@ impl InferenceTable {
360 == self.type_variable_table.is_diverging(*tv2) => 362 == self.type_variable_table.is_diverging(*tv2) =>
361 { 363 {
362 // both type vars are unknown since we tried to resolve them 364 // both type vars are unknown since we tried to resolve them
363 self.var_unification_table.union(tv1.to_inner(), tv2.to_inner()); 365 if !self.var_unification_table.unioned(tv1.to_inner(), tv2.to_inner()) {
366 self.var_unification_table.union(tv1.to_inner(), tv2.to_inner());
367 self.revision += 1;
368 }
364 true 369 true
365 } 370 }
366 371
@@ -398,6 +403,7 @@ impl InferenceTable {
398 tv.to_inner(), 403 tv.to_inner(),
399 TypeVarValue::Known(other.clone().intern(&Interner)), 404 TypeVarValue::Known(other.clone().intern(&Interner)),
400 ); 405 );
406 self.revision += 1;
401 true 407 true
402 } 408 }
403 409