8687: fix: closure unify without check ClosureId r=lnicola a=komonad

Previously, the unification of closure types is blocked by `Ty.equals_ctor` which compares the ClosureId of the closures. Here is a workaround to allow closures to unify their substitutions.

Fixes #8604.

Co-authored-by: Comonad <comonad@foxmail.com>
This commit is contained in:
bors[bot] 2021-04-29 07:45:37 +00:00 committed by GitHub
commit 80bee14e14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 0 deletions

View File

@ -332,6 +332,10 @@ impl InferenceTable {
| (TyKind::Slice(ty1), TyKind::Slice(ty2)) => self.unify_inner(ty1, ty2, depth + 1),
_ => true, /* we checked equals_ctor already */
}
} else if let (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) =
(ty1.kind(&Interner), ty2.kind(&Interner))
{
self.unify_substs(substs1, substs2, depth + 1)
} else {
self.unify_inner_trivial(&ty1, &ty2, depth)
}

View File

@ -1028,6 +1028,42 @@ fn infer_in_elseif() {
)
}
#[test]
fn infer_closure_unify() {
check_infer(
r#"
fn foo(f: bool) {
let a = |x| x;
let b = |x| x;
let id = if f { a } else { b };
id(123);
}
"#,
expect![[r#"
7..8 'f': bool
16..106 '{ ...23); }': ()
26..27 'a': |i32| -> i32
30..35 '|x| x': |i32| -> i32
31..32 'x': i32
34..35 'x': i32
45..46 'b': |i32| -> i32
49..54 '|x| x': |i32| -> i32
50..51 'x': i32
53..54 'x': i32
64..66 'id': |i32| -> i32
69..90 'if f {... { b }': |i32| -> i32
72..73 'f': bool
74..79 '{ a }': |i32| -> i32
76..77 'a': |i32| -> i32
85..90 '{ b }': |i32| -> i32
87..88 'b': |i32| -> i32
96..98 'id': |i32| -> i32
96..103 'id(123)': i32
99..102 '123': i32
"#]],
)
}
#[test]
fn infer_if_match_with_return() {
check_infer(