mirror of
https://github.com/apple/swift.git
synced 2026-03-04 18:24:35 +01:00
This optimizes for the case where we have a disjunction that contains an operator defined in a protocol, and a protocol defined in a protocol extension, and furthermore, the protocol extension operator's type is a refinement of the protocol requirement operator's type. In this case, there are three possibilities: - Either the operator requirement is witnessed by a concrete operator in the conforming type, in which case the solution involving the protocol extension operator is going to be worse, so we can skip this choice. - Otherwise, the protocol requirement operator is witnessed by the same protocol extension operator that we skipped, in which case we will find the same solution if we just pick the protocol requirement operator anyway. - The only other possibility is that the protocol requirement operator is witnessed by a protocol extension operator, but also, a more refined protocol extension operator exists. However, it appears that in this case, solution ranking _also_ picks the solution involving the protocol requirement operator, as the new test case demonstrates. Thus, we gain nothing by considering these protocol extension operators. Skip them when forming the disjunction.
43 lines
1.9 KiB
Swift
43 lines
1.9 KiB
Swift
// RUN: %target-swift-frontend -emit-sil %s -solver-enable-optimize-operator-defaults | %FileCheck %s
|
|
// RUN: %target-swift-frontend -emit-sil %s -solver-disable-optimize-operator-defaults | %FileCheck %s
|
|
|
|
infix operator +++
|
|
|
|
protocol P {
|
|
associatedtype A
|
|
static func +++(_: Self, _: Self) -> Self
|
|
}
|
|
|
|
extension P {
|
|
static func +++(_: Self, _: Self) -> Self { fatalError() }
|
|
}
|
|
|
|
extension P where A == Int {
|
|
static func +++(_: Self, _: Self) -> Self { fatalError() }
|
|
}
|
|
|
|
struct G<T>: P {
|
|
typealias A = T
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden @$s27protocol_extension_operator1PPAAE3pppoiyxx_xtFZ : $@convention(method) <Self where Self : P> (@in_guaranteed Self, @in_guaranteed Self, @thick Self.Type) -> @out Self {
|
|
// CHECK: function_ref @$s27protocol_extension_operator1PPAAE3pppoiyxx_xtFZ : $@convention(method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, @thick τ_0_0.Type) -> @out τ_0_0
|
|
// CHECK: return
|
|
func testConcreteContext() {
|
|
_ = G<Int>() +++ G<Int>()
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden @$s27protocol_extension_operator18testGenericContextyyxAA1PRzlF : $@convention(thin) <T where T : P> (@in_guaranteed T) -> () {
|
|
// CHECK: function_ref @$s27protocol_extension_operator1PPAAE3pppoiyxx_xtFZ : $@convention(method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, @thick τ_0_0.Type) -> @out τ_0_0
|
|
// CHECK: return
|
|
func testGenericContext<T: P>(_: T) {
|
|
_ = G<T>() +++ G<T>()
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden @$s27protocol_extension_operator22testConstrainedContextyyxAA1PRzSi1ARtzlF : $@convention(thin) <T where T : P, T.A == Int> (@in_guaranteed T) -> () {
|
|
// CHECK: function_ref @$s27protocol_extension_operator1PPAAE3pppoiyxx_xtFZ : $@convention(method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, @thick τ_0_0.Type) -> @out τ_0_0
|
|
// CHECK: return
|
|
func testConstrainedContext<T: P>(_: T) where T.A == Int {
|
|
_ = G<T>() +++ G<T>()
|
|
}
|