aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2021-05-16 17:27:17 +0100
committerFlorian Diebold <[email protected]>2021-05-21 16:49:09 +0100
commit9716c0b949b1a1a95b3f36928faed3abc21c0bda (patch)
tree3868e00827852afc86162fa82786592378511af5 /crates/hir_ty/src/infer
parent4bd446f5b3f8035d5db1fde1c6c50073e3f4fb2b (diff)
Deal with goals arising from unification
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r--crates/hir_ty/src/infer/coerce.rs18
-rw-r--r--crates/hir_ty/src/infer/unify.rs13
2 files changed, 17 insertions, 14 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 00b2b585f..60186bc5f 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -26,8 +26,8 @@ impl<'a> InferenceContext<'a> {
26 return true; 26 return true;
27 } 27 }
28 match self.coerce_inner(from_ty, &to_ty) { 28 match self.coerce_inner(from_ty, &to_ty) {
29 Ok(_result) => { 29 Ok(result) => {
30 // TODO deal with goals 30 self.table.register_infer_ok(result);
31 true 31 true
32 } 32 }
33 Err(_) => { 33 Err(_) => {
@@ -67,8 +67,9 @@ impl<'a> InferenceContext<'a> {
67 let target_ty = TyKind::Function(sig.to_fn_ptr()).intern(&Interner); 67 let target_ty = TyKind::Function(sig.to_fn_ptr()).intern(&Interner);
68 let result1 = self.coerce_inner(ty1.clone(), &target_ty); 68 let result1 = self.coerce_inner(ty1.clone(), &target_ty);
69 let result2 = self.coerce_inner(ty2.clone(), &target_ty); 69 let result2 = self.coerce_inner(ty2.clone(), &target_ty);
70 if let (Ok(_result1), Ok(_result2)) = (result1, result2) { 70 if let (Ok(result1), Ok(result2)) = (result1, result2) {
71 // TODO deal with the goals 71 self.table.register_infer_ok(result1);
72 self.table.register_infer_ok(result2);
72 return target_ty; 73 return target_ty;
73 } 74 }
74 } 75 }
@@ -104,7 +105,7 @@ impl<'a> InferenceContext<'a> {
104 } 105 }
105 _ => {} 106 _ => {}
106 } 107 }
107 return Ok(InferOk {}); 108 return Ok(InferOk { goals: Vec::new() });
108 } 109 }
109 110
110 // Consider coercing the subtype to a DST 111 // Consider coercing the subtype to a DST
@@ -416,10 +417,11 @@ impl<'a> InferenceContext<'a> {
416 }, 417 },
417 ); 418 );
418 } 419 }
420 // FIXME: should we accept ambiguous results here?
419 _ => return Err(TypeError), 421 _ => return Err(TypeError),
420 }; 422 };
421 423
422 Ok(InferOk {}) 424 Ok(InferOk { goals: Vec::new() })
423 } 425 }
424} 426}
425 427
@@ -444,11 +446,11 @@ fn safe_to_unsafe_fn_ty(fn_ty: FnPointer) -> FnPointer {
444 } 446 }
445} 447}
446 448
447fn coerce_mutabilities(from: Mutability, to: Mutability) -> InferResult { 449fn coerce_mutabilities(from: Mutability, to: Mutability) -> Result<(), TypeError> {
448 match (from, to) { 450 match (from, to) {
449 (Mutability::Mut, Mutability::Mut) 451 (Mutability::Mut, Mutability::Mut)
450 | (Mutability::Mut, Mutability::Not) 452 | (Mutability::Mut, Mutability::Not)
451 | (Mutability::Not, Mutability::Not) => Ok(InferOk {}), 453 | (Mutability::Not, Mutability::Not) => Ok(()),
452 (Mutability::Not, Mutability::Mut) => Err(TypeError), 454 (Mutability::Not, Mutability::Mut) => Err(TypeError),
453 } 455 }
454} 456}
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 539e12420..d872cdd58 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -307,12 +307,12 @@ impl<'a> InferenceTable<'a> {
307 /// Unify two types and register new trait goals that arise from that. 307 /// Unify two types and register new trait goals that arise from that.
308 // TODO give these two functions better names 308 // TODO give these two functions better names
309 pub(crate) fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { 309 pub(crate) fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
310 let _result = if let Ok(r) = self.unify_inner(ty1, ty2) { 310 let result = if let Ok(r) = self.unify_inner(ty1, ty2) {
311 r 311 r
312 } else { 312 } else {
313 return false; 313 return false;
314 }; 314 };
315 // TODO deal with new goals 315 self.register_infer_ok(result);
316 true 316 true
317 } 317 }
318 318
@@ -327,10 +327,7 @@ impl<'a> InferenceTable<'a> {
327 t1, 327 t1,
328 t2, 328 t2,
329 ) { 329 ) {
330 Ok(_result) => { 330 Ok(result) => Ok(InferOk { goals: result.goals }),
331 // TODO deal with new goals
332 Ok(InferOk {})
333 }
334 Err(chalk_ir::NoSolution) => Err(TypeError), 331 Err(chalk_ir::NoSolution) => Err(TypeError),
335 } 332 }
336 } 333 }
@@ -353,6 +350,10 @@ impl<'a> InferenceTable<'a> {
353 } 350 }
354 } 351 }
355 352
353 pub fn register_infer_ok(&mut self, infer_ok: InferOk) {
354 infer_ok.goals.into_iter().for_each(|goal| self.register_obligation_in_env(goal));
355 }
356
356 pub fn resolve_obligations_as_possible(&mut self) { 357 pub fn resolve_obligations_as_possible(&mut self) {
357 let _span = profile::span("resolve_obligations_as_possible"); 358 let _span = profile::span("resolve_obligations_as_possible");
358 let mut changed = true; 359 let mut changed = true;