[CSSolver] Don't skip generic overloads when non-generic one has SK_UserConversion

In cases where matched concrete overload used a bridging, CF*, or
`AnyHashable` conversion, let's attempt generic overload choices
as well because one of them could produce a better solution e.g.
`RawRepresentable` for `==` where underlying type conforms to `Equatable`
has a better generic match than `(AnyHashable, AnyHashable) -> Bool`.

Resolves: rdar://95992916
This commit is contained in:
Pavel Yaskevich
2022-07-18 17:30:45 -07:00
parent 9a3814634a
commit baf94c6af0
2 changed files with 32 additions and 2 deletions

View File

@@ -702,10 +702,11 @@ private:
// non-generic score indicates that there were no forced
// unwrappings of optional(s), no unavailable overload
// choices present in the solution, no fixes required,
// and there are no non-trivial function conversions.
// and there are no non-trivial user or function conversions.
auto &score = BestNonGenericScore->Data;
return (score[SK_ForceUnchecked] == 0 && score[SK_Unavailable] == 0 &&
score[SK_Fix] == 0 && score[SK_FunctionConversion] == 0);
score[SK_Fix] == 0 && score[SK_UserConversion] == 0 &&
score[SK_FunctionConversion] == 0);
}
/// Attempt to apply given disjunction choice to constraint system.

View File

@@ -0,0 +1,29 @@
// RUN: %target-swift-emit-silgen %s -verify | %FileCheck %s
// rdar://95992916 - SILGen crash due to incorrect overload pick for `==`
enum E : String {
case a
case b
}
protocol P : AnyObject {
var prop: E { get }
}
func test(arr: [any P]) {
_ = arr.map {
let v = (a: $0.prop, b: $0.prop)
switch v {
case let (a, b) where a == b: break
default: break
}
}
}
// CHECK: sil private [ossa] @$s34anyhashable_and_operator_filtering4test3arrySayAA1P_pG_tFyAaD_pXEfU_
// CHECK: [[LHS_ARG:%.*]] = alloc_stack $E
// CHECK: [[RHS_ARG:%.*]] = alloc_stack $E
// CHECK: function_ref == infix<A>(_:_:)
// CHECK-NEXT: [[GENERIC_OP:%.*]] = function_ref @$ss2eeoiySbx_xtSYRzSQ8RawValueRpzlF : $@convention(thin) <τ_0_0 where τ_0_0 : RawRepresentable, τ_0_0.RawValue : Equatable> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0) -> Bool
// CHECK-NEXT: apply [[GENERIC_OP]]<E>([[LHS_ARG]], [[RHS_ARG]])