From a9e015f8eeea28f7c9e5286c12c1776fc439b899 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sat, 7 Dec 2024 19:16:00 +0200 Subject: [PATCH] Coerce two `FnDef`s 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. --- crates/hir-ty/src/infer/coerce.rs | 6 +++++- crates/hir-ty/src/tests/coercion.rs | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/crates/hir-ty/src/infer/coerce.rs b/crates/hir-ty/src/infer/coerce.rs index 366c3cb0f177..2fe90a8a9243 100644 --- a/crates/hir-ty/src/infer/coerce.rs +++ b/crates/hir-ty/src/infer/coerce.rs @@ -125,7 +125,11 @@ impl CoerceMany { // pointers to have a chance at getting a match. See // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916 let sig = match (self.merged_ty().kind(Interner), expr_ty.kind(Interner)) { - (TyKind::FnDef(x, _), TyKind::FnDef(y, _)) if x == y => None, + (TyKind::FnDef(x, _), TyKind::FnDef(y, _)) + if x == y && ctx.table.unify(&self.merged_ty(), &expr_ty) => + { + None + } (TyKind::Closure(x, _), TyKind::Closure(y, _)) if x == y => None, (TyKind::FnDef(..) | TyKind::Closure(..), TyKind::FnDef(..) | TyKind::Closure(..)) => { // FIXME: we're ignoring safety here. To be more correct, if we have one FnDef and one Closure, diff --git a/crates/hir-ty/src/tests/coercion.rs b/crates/hir-ty/src/tests/coercion.rs index 273571901ad5..7992f1feeeb1 100644 --- a/crates/hir-ty/src/tests/coercion.rs +++ b/crates/hir-ty/src/tests/coercion.rs @@ -942,3 +942,19 @@ fn main() { "#, ) } + +#[test] +fn regression_18626() { + check_no_mismatches( + r#" +fn f() { + trait T { + fn f() {} + } + impl T for i32 {} + impl T for u32 {} + &[i32::f, u32::f] as &[fn()]; +} + "#, + ); +}