From 5ab4e64a4c3f26f71ae95d673a2de1cd9c09541d Mon Sep 17 00:00:00 2001 From: Ryo Yoshida Date: Fri, 7 Apr 2023 05:17:12 +0900 Subject: [PATCH] fix: unify types in `infer_expr_coerce_never()` --- crates/hir-ty/src/infer/expr.rs | 25 +++++++++++++++++-------- crates/hir-ty/src/tests/patterns.rs | 2 +- crates/hir-ty/src/tests/regression.rs | 4 ++-- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index 7180b88d6a6..d6a205e6086 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -86,10 +86,10 @@ impl<'a> InferenceContext<'a> { } } - pub(super) fn infer_expr_coerce_never(&mut self, expr: ExprId, expected: &Expectation) -> Ty { + fn infer_expr_coerce_never(&mut self, expr: ExprId, expected: &Expectation) -> Ty { let ty = self.infer_expr_inner(expr, expected); // While we don't allow *arbitrary* coercions here, we *do* allow - // coercions from ! to `expected`. + // coercions from `!` to `expected`. if ty.is_never() { if let Some(adjustments) = self.result.expr_adjustments.get(&expr) { return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &**adjustments { @@ -99,13 +99,22 @@ impl<'a> InferenceContext<'a> { }; } - let adj_ty = self.table.new_type_var(); - self.write_expr_adj( - expr, - vec![Adjustment { kind: Adjust::NeverToAny, target: adj_ty.clone() }], - ); - adj_ty + if let Some(target) = expected.only_has_type(&mut self.table) { + self.coerce(Some(expr), &ty, &target) + .expect("never-to-any coercion should always succeed") + } else { + ty + } } else { + if let Some(expected_ty) = expected.only_has_type(&mut self.table) { + let could_unify = self.unify(&ty, &expected_ty); + if !could_unify { + self.result.type_mismatches.insert( + expr.into(), + TypeMismatch { expected: expected_ty, actual: ty.clone() }, + ); + } + } ty } } diff --git a/crates/hir-ty/src/tests/patterns.rs b/crates/hir-ty/src/tests/patterns.rs index 74bcab6caa9..be67329fee4 100644 --- a/crates/hir-ty/src/tests/patterns.rs +++ b/crates/hir-ty/src/tests/patterns.rs @@ -476,7 +476,7 @@ fn infer_adt_pattern() { 183..184 'x': usize 190..191 'x': usize 201..205 'E::B': E - 209..212 'foo': {unknown} + 209..212 'foo': bool 216..217 '1': usize 227..231 'E::B': E 235..237 '10': usize diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs index 35a06fcf61a..74c7e3efc05 100644 --- a/crates/hir-ty/src/tests/regression.rs +++ b/crates/hir-ty/src/tests/regression.rs @@ -270,7 +270,7 @@ fn infer_std_crash_5() { 61..320 '{ ... }': () 75..79 'name': &{unknown} 82..166 'if doe... }': &{unknown} - 85..98 'doesnt_matter': {unknown} + 85..98 'doesnt_matter': bool 99..128 '{ ... }': &{unknown} 113..118 'first': &{unknown} 134..166 '{ ... }': &{unknown} @@ -279,7 +279,7 @@ fn infer_std_crash_5() { 181..188 'content': &{unknown} 191..313 'if ICE... }': &{unknown} 194..231 'ICE_RE..._VALUE': {unknown} - 194..247 'ICE_RE...&name)': {unknown} + 194..247 'ICE_RE...&name)': bool 241..246 '&name': &&{unknown} 242..246 'name': &{unknown} 248..276 '{ ... }': &{unknown}