Skip to content

Commit a9e015f

Browse files
Coerce two FnDefs to fn pointers even if they are the same, if they are subtypes
That's because they can be the same function but still different substs, which mandates them to coerce to fn pointers in order to unify.
1 parent 39fd171 commit a9e015f

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,11 @@ impl CoerceMany {
125125
// pointers to have a chance at getting a match. See
126126
// https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916
127127
let sig = match (self.merged_ty().kind(Interner), expr_ty.kind(Interner)) {
128-
(TyKind::FnDef(x, _), TyKind::FnDef(y, _)) if x == y => None,
128+
(TyKind::FnDef(x, _), TyKind::FnDef(y, _))
129+
if x == y && ctx.table.unify(&self.merged_ty(), &expr_ty) =>
130+
{
131+
None
132+
}
129133
(TyKind::Closure(x, _), TyKind::Closure(y, _)) if x == y => None,
130134
(TyKind::FnDef(..) | TyKind::Closure(..), TyKind::FnDef(..) | TyKind::Closure(..)) => {
131135
// FIXME: we're ignoring safety here. To be more correct, if we have one FnDef and one Closure,

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,3 +942,19 @@ fn main() {
942942
"#,
943943
)
944944
}
945+
946+
#[test]
947+
fn regression_18626() {
948+
check_no_mismatches(
949+
r#"
950+
fn f() {
951+
trait T {
952+
fn f() {}
953+
}
954+
impl T for i32 {}
955+
impl T for u32 {}
956+
&[i32::f, u32::f] as &[fn()];
957+
}
958+
"#,
959+
);
960+
}

0 commit comments

Comments
 (0)