diff options
author | Florian Diebold <[email protected]> | 2021-05-16 17:27:17 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2021-05-21 16:49:09 +0100 |
commit | 9716c0b949b1a1a95b3f36928faed3abc21c0bda (patch) | |
tree | 3868e00827852afc86162fa82786592378511af5 /crates/hir_ty/src | |
parent | 4bd446f5b3f8035d5db1fde1c6c50073e3f4fb2b (diff) |
Deal with goals arising from unification
Diffstat (limited to 'crates/hir_ty/src')
-rw-r--r-- | crates/hir_ty/src/infer.rs | 6 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 18 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 13 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/regression.rs | 2 |
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; | |||
37 | use super::{DomainGoal, InEnvironment, ProjectionTy, TraitEnvironment, TraitRef, Ty}; | 37 | use super::{DomainGoal, InEnvironment, ProjectionTy, TraitEnvironment, TraitRef, Ty}; |
38 | use crate::{ | 38 | use 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)] |
106 | pub(crate) struct InferOk { | 106 | pub(crate) struct InferOk { |
107 | // obligations | 107 | goals: Vec<InEnvironment<Goal>>, |
108 | } | 108 | } |
109 | #[derive(Debug)] | 109 | #[derive(Debug)] |
110 | pub(crate) struct TypeError; | 110 | pub(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 | ||
447 | fn coerce_mutabilities(from: Mutability, to: Mutability) -> InferResult { | 449 | fn 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 |