Skip to content

Commit ca0f6bb

Browse files
committed
Auto merge of rust-lang#14520 - lowr:fix/unify-variable-fallout, r=Veykril
fix: unify types in `infer_expr_coerce_never()` Fixes rust-lang#14506 rust-lang#14506 turned out to be a regression in type inference. `infer_expr_coerce_never()` added in rust-lang#14251 allows never-to-any coercion but should also perform ordinary type unification in other cases.
2 parents 625a6f3 + 5ab4e64 commit ca0f6bb

File tree

3 files changed

+20
-11
lines changed

3 files changed

+20
-11
lines changed

crates/hir-ty/src/infer/expr.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,10 @@ impl<'a> InferenceContext<'a> {
8686
}
8787
}
8888

89-
pub(super) fn infer_expr_coerce_never(&mut self, expr: ExprId, expected: &Expectation) -> Ty {
89+
fn infer_expr_coerce_never(&mut self, expr: ExprId, expected: &Expectation) -> Ty {
9090
let ty = self.infer_expr_inner(expr, expected);
9191
// While we don't allow *arbitrary* coercions here, we *do* allow
92-
// coercions from ! to `expected`.
92+
// coercions from `!` to `expected`.
9393
if ty.is_never() {
9494
if let Some(adjustments) = self.result.expr_adjustments.get(&expr) {
9595
return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &**adjustments {
@@ -99,13 +99,22 @@ impl<'a> InferenceContext<'a> {
9999
};
100100
}
101101

102-
let adj_ty = self.table.new_type_var();
103-
self.write_expr_adj(
104-
expr,
105-
vec![Adjustment { kind: Adjust::NeverToAny, target: adj_ty.clone() }],
106-
);
107-
adj_ty
102+
if let Some(target) = expected.only_has_type(&mut self.table) {
103+
self.coerce(Some(expr), &ty, &target)
104+
.expect("never-to-any coercion should always succeed")
105+
} else {
106+
ty
107+
}
108108
} else {
109+
if let Some(expected_ty) = expected.only_has_type(&mut self.table) {
110+
let could_unify = self.unify(&ty, &expected_ty);
111+
if !could_unify {
112+
self.result.type_mismatches.insert(
113+
expr.into(),
114+
TypeMismatch { expected: expected_ty, actual: ty.clone() },
115+
);
116+
}
117+
}
109118
ty
110119
}
111120
}

crates/hir-ty/src/tests/patterns.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ fn infer_adt_pattern() {
476476
183..184 'x': usize
477477
190..191 'x': usize
478478
201..205 'E::B': E
479-
209..212 'foo': {unknown}
479+
209..212 'foo': bool
480480
216..217 '1': usize
481481
227..231 'E::B': E
482482
235..237 '10': usize

crates/hir-ty/src/tests/regression.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ fn infer_std_crash_5() {
270270
61..320 '{ ... }': ()
271271
75..79 'name': &{unknown}
272272
82..166 'if doe... }': &{unknown}
273-
85..98 'doesnt_matter': {unknown}
273+
85..98 'doesnt_matter': bool
274274
99..128 '{ ... }': &{unknown}
275275
113..118 'first': &{unknown}
276276
134..166 '{ ... }': &{unknown}
@@ -279,7 +279,7 @@ fn infer_std_crash_5() {
279279
181..188 'content': &{unknown}
280280
191..313 'if ICE... }': &{unknown}
281281
194..231 'ICE_RE..._VALUE': {unknown}
282-
194..247 'ICE_RE...&name)': {unknown}
282+
194..247 'ICE_RE...&name)': bool
283283
241..246 '&name': &&{unknown}
284284
242..246 'name': &{unknown}
285285
248..276 '{ ... }': &{unknown}

0 commit comments

Comments
 (0)