aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer.rs
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.rs
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.rs')
-rw-r--r--crates/hir_ty/src/infer.rs18
1 files changed, 15 insertions, 3 deletions
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index e4407ff50..497a1beb7 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -210,6 +210,7 @@ struct InferenceContext<'a> {
210 table: unify::InferenceTable, 210 table: unify::InferenceTable,
211 trait_env: Arc<TraitEnvironment>, 211 trait_env: Arc<TraitEnvironment>,
212 obligations: Vec<DomainGoal>, 212 obligations: Vec<DomainGoal>,
213 last_obligations_check: Option<u32>,
213 result: InferenceResult, 214 result: InferenceResult,
214 /// The return type of the function being inferred, or the closure if we're 215 /// The return type of the function being inferred, or the closure if we're
215 /// currently within one. 216 /// currently within one.
@@ -245,6 +246,7 @@ impl<'a> InferenceContext<'a> {
245 result: InferenceResult::default(), 246 result: InferenceResult::default(),
246 table: unify::InferenceTable::new(), 247 table: unify::InferenceTable::new(),
247 obligations: Vec::default(), 248 obligations: Vec::default(),
249 last_obligations_check: None,
248 return_ty: TyKind::Unknown.intern(&Interner), // set in collect_fn_signature 250 return_ty: TyKind::Unknown.intern(&Interner), // set in collect_fn_signature
249 trait_env: owner 251 trait_env: owner
250 .as_generic_def_id() 252 .as_generic_def_id()
@@ -334,6 +336,11 @@ impl<'a> InferenceContext<'a> {
334 } 336 }
335 337
336 fn resolve_obligations_as_possible(&mut self) { 338 fn resolve_obligations_as_possible(&mut self) {
339 if self.last_obligations_check == Some(self.table.revision) {
340 // no change
341 return;
342 }
343 self.last_obligations_check = Some(self.table.revision);
337 let obligations = mem::replace(&mut self.obligations, Vec::new()); 344 let obligations = mem::replace(&mut self.obligations, Vec::new());
338 for obligation in obligations { 345 for obligation in obligations {
339 let in_env = InEnvironment::new(self.trait_env.env.clone(), obligation.clone()); 346 let in_env = InEnvironment::new(self.trait_env.env.clone(), obligation.clone());
@@ -360,6 +367,11 @@ impl<'a> InferenceContext<'a> {
360 } 367 }
361 } 368 }
362 369
370 fn push_obligation(&mut self, o: DomainGoal) {
371 self.obligations.push(o);
372 self.last_obligations_check = None;
373 }
374
363 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { 375 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
364 self.table.unify(ty1, ty2) 376 self.table.unify(ty1, ty2)
365 } 377 }
@@ -408,8 +420,8 @@ impl<'a> InferenceContext<'a> {
408 }), 420 }),
409 ty: ty.clone(), 421 ty: ty.clone(),
410 }; 422 };
411 self.obligations.push(trait_ref.cast(&Interner)); 423 self.push_obligation(trait_ref.cast(&Interner));
412 self.obligations.push(alias_eq.cast(&Interner)); 424 self.push_obligation(alias_eq.cast(&Interner));
413 self.resolve_ty_as_possible(ty) 425 self.resolve_ty_as_possible(ty)
414 } 426 }
415 None => self.err_ty(), 427 None => self.err_ty(),
@@ -436,7 +448,7 @@ impl<'a> InferenceContext<'a> {
436 let var = self.table.new_type_var(); 448 let var = self.table.new_type_var();
437 let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() }; 449 let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() };
438 let obligation = alias_eq.cast(&Interner); 450 let obligation = alias_eq.cast(&Interner);
439 self.obligations.push(obligation); 451 self.push_obligation(obligation);
440 var 452 var
441 } 453 }
442 454