diff options
Diffstat (limited to 'crates/hir_ty/src/infer.rs')
-rw-r--r-- | crates/hir_ty/src/infer.rs | 18 |
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 | ||