aboutsummaryrefslogtreecommitdiff
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
parent4bd446f5b3f8035d5db1fde1c6c50073e3f4fb2b (diff)
Deal with goals arising from unification
-rw-r--r--crates/hir_ty/src/infer.rs6
-rw-r--r--crates/hir_ty/src/infer/coerce.rs18
-rw-r--r--crates/hir_ty/src/infer/unify.rs13
-rw-r--r--crates/hir_ty/src/tests/regression.rs2
4 files changed, 21 insertions, 18 deletions
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index ab742e203..db2234018 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -37,8 +37,8 @@ use syntax::SmolStr;
37use super::{DomainGoal, InEnvironment, ProjectionTy, TraitEnvironment, TraitRef, Ty}; 37use super::{DomainGoal, InEnvironment, ProjectionTy, TraitEnvironment, TraitRef, Ty};
38use crate::{ 38use crate::{
39 db::HirDatabase, fold_tys, infer::diagnostics::InferenceDiagnostic, 39 db::HirDatabase, fold_tys, infer::diagnostics::InferenceDiagnostic,
40 lower::ImplTraitLoweringMode, to_assoc_type_id, AliasEq, AliasTy, Interner, TyBuilder, TyExt, 40 lower::ImplTraitLoweringMode, to_assoc_type_id, AliasEq, AliasTy, Goal, Interner, TyBuilder,
41 TyKind, 41 TyExt, TyKind,
42}; 42};
43 43
44// This lint has a false positive here. See the link below for details. 44// This lint has a false positive here. See the link below for details.
@@ -104,7 +104,7 @@ impl Default for BindingMode {
104 104
105#[derive(Debug)] 105#[derive(Debug)]
106pub(crate) struct InferOk { 106pub(crate) struct InferOk {
107 // obligations 107 goals: Vec<InEnvironment<Goal>>,
108} 108}
109#[derive(Debug)] 109#[derive(Debug)]
110pub(crate) struct TypeError; 110pub(crate) struct TypeError;
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;
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs
index baef81590..ad9edf11c 100644
--- a/crates/hir_ty/src/tests/regression.rs
+++ b/crates/hir_ty/src/tests/regression.rs
@@ -758,7 +758,7 @@ fn issue_4885() {
758 "#, 758 "#,
759 expect![[r#" 759 expect![[r#"
760 136..139 'key': &K 760 136..139 'key': &K
761 198..214 '{ ...key) }': {unknown} 761 198..214 '{ ...key) }': impl Future<Output = <K as Foo<R>>::Bar>
762 204..207 'bar': fn bar<R, K>(&K) -> impl Future<Output = <K as Foo<R>>::Bar> 762 204..207 'bar': fn bar<R, K>(&K) -> impl Future<Output = <K as Foo<R>>::Bar>
763 204..212 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar> 763 204..212 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar>
764 208..211 'key': &K 764 208..211 'key': &K