diff options
author | Florian Diebold <[email protected]> | 2021-05-15 16:01:27 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2021-05-21 16:48:34 +0100 |
commit | 32fc944263ae0b30eba130fbcf28f4eb5578fdb3 (patch) | |
tree | 779b701955168f7472a5ae7e760cb95c6ca604e4 /crates/hir_ty/src/infer | |
parent | a09079f27aa631b011f6c0703200862d28af81f4 (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.rs | 17 |
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 | } |