Skip to content

Commit b9883fc

Browse files
committed
Match up array coercion for rust-lang/rust#140283
1 parent 25808c1 commit b9883fc

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1164,7 +1164,9 @@ impl InferenceContext<'_> {
11641164
expected: &Expectation,
11651165
) -> chalk_ir::Ty<Interner> {
11661166
let elem_ty = match expected.to_option(&mut self.table).as_ref().map(|t| t.kind(Interner)) {
1167-
Some(TyKind::Array(st, _) | TyKind::Slice(st)) => st.clone(),
1167+
// Avoid using a type variable as the coerce_to type, as it may resolve
1168+
// during the first coercion instead of being based on the common type.
1169+
Some(TyKind::Array(st, _) | TyKind::Slice(st)) if !st.is_ty_var() => st.clone(),
11681170
_ => self.table.new_type_var(),
11691171
};
11701172

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

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ fn foo<T>(x: &[T]) -> &[T] { x }
9696
fn test() {
9797
let x = if true {
9898
foo(&[1])
99-
// ^^^^ adjustments: Deref(None), Borrow(Ref('?8, Not)), Pointer(Unsize)
99+
// ^^^^ adjustments: Deref(None), Borrow(Ref('?7, Not)), Pointer(Unsize)
100100
} else {
101101
&[1]
102102
};
@@ -148,7 +148,7 @@ fn foo<T>(x: &[T]) -> &[T] { x }
148148
fn test(i: i32) {
149149
let x = match i {
150150
2 => foo(&[2]),
151-
// ^^^^ adjustments: Deref(None), Borrow(Ref('?8, Not)), Pointer(Unsize)
151+
// ^^^^ adjustments: Deref(None), Borrow(Ref('?7, Not)), Pointer(Unsize)
152152
1 => &[1],
153153
_ => &[3],
154154
};
@@ -957,3 +957,35 @@ fn f() {
957957
"#,
958958
);
959959
}
960+
961+
#[test]
962+
fn coerce_array_elements() {
963+
check_no_mismatches(
964+
r#"
965+
// Check that least upper bound coercions don't resolve type variable merely based on the first
966+
// coercion. Check issue rust-lang/rust#136420.
967+
968+
fn foo() {}
969+
fn bar() {}
970+
971+
fn infer<T>(_: T) {}
972+
973+
fn infer_array_element<T>(_: [T; 2]) {}
974+
975+
fn main() {
976+
infer(if false {
977+
foo
978+
} else {
979+
bar
980+
});
981+
982+
infer(match false {
983+
true => foo,
984+
false => bar,
985+
});
986+
987+
infer_array_element([foo, bar]);
988+
}
989+
"#,
990+
);
991+
}

0 commit comments

Comments
 (0)