Skip to content

Commit 1907786

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 39aab98 commit 1907786

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

src/tools/rust-analyzer/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,

src/tools/rust-analyzer/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)