Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #18633 from ChayimFriedman2/unify-fn
fix: Coerce two `FnDef`s to fn pointers even if they are the same, if they are subtypes
Lukas Wirth 2024-12-08
parent 4a41883 · parent a9e015f · commit 4c755e6
-rw-r--r--crates/hir-ty/src/infer/coerce.rs6
-rw-r--r--crates/hir-ty/src/tests/coercion.rs16
2 files changed, 21 insertions, 1 deletions
diff --git a/crates/hir-ty/src/infer/coerce.rs b/crates/hir-ty/src/infer/coerce.rs
index 366c3cb0f1..2fe90a8a92 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 273571901a..7992f1feee 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()];
+}
+ "#,
+ );
+}