aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2021-05-15 16:01:27 +0100
committerFlorian Diebold <[email protected]>2021-05-21 16:48:34 +0100
commit32fc944263ae0b30eba130fbcf28f4eb5578fdb3 (patch)
tree779b701955168f7472a5ae7e760cb95c6ca604e4 /crates/hir_ty/src/infer
parenta09079f27aa631b011f6c0703200862d28af81f4 (diff)
Fix handling of diverging branches in match coercion
Fixes #7626.
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r--crates/hir_ty/src/infer/coerce.rs17
1 files changed, 13 insertions, 4 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 27f59c8bb..4d80b4a08 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -45,6 +45,10 @@ impl<'a> InferenceContext<'a> {
45 /// - if we were concerned with lifetime subtyping, we'd need to look for a 45 /// - if we were concerned with lifetime subtyping, we'd need to look for a
46 /// least upper bound. 46 /// least upper bound.
47 pub(super) fn coerce_merge_branch(&mut self, ty1: &Ty, ty2: &Ty) -> Ty { 47 pub(super) fn coerce_merge_branch(&mut self, ty1: &Ty, ty2: &Ty) -> Ty {
48 let ty1 = self.resolve_ty_shallow(ty1);
49 let ty1 = ty1.as_ref();
50 let ty2 = self.resolve_ty_shallow(ty2);
51 let ty2 = ty2.as_ref();
48 // Special case: two function types. Try to coerce both to 52 // Special case: two function types. Try to coerce both to
49 // pointers to have a chance at getting a match. See 53 // pointers to have a chance at getting a match. See
50 // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916 54 // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916
@@ -71,12 +75,17 @@ impl<'a> InferenceContext<'a> {
71 } 75 }
72 } 76 }
73 77
74 if self.coerce(ty1, ty2) { 78 // It might not seem like it, but order is important here: ty1 is our
75 ty2.clone() 79 // "previous" type, ty2 is the "new" one being added. If the previous
76 } else if self.coerce(ty2, ty1) { 80 // type is a type variable and the new one is `!`, trying it the other
81 // way around first would mean we make the type variable `!`, instead of
82 // just marking it as possibly diverging.
83 if self.coerce(ty2, ty1) {
77 ty1.clone() 84 ty1.clone()
85 } else if self.coerce(ty1, ty2) {
86 ty2.clone()
78 } else { 87 } else {
79 // FIXME record a type mismatch 88 // TODO record a type mismatch
80 cov_mark::hit!(coerce_merge_fail_fallback); 89 cov_mark::hit!(coerce_merge_fail_fallback);
81 ty1.clone() 90 ty1.clone()
82 } 91 }