mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
You can overload a function based on its `async`-ness, and resolution is carried out based on async-ness of calling context. But during protocol conformance checking, for an `async` requirement we were accidentally choosing the non-`async overload instead of the `async` one. The `async` one is the choice people would expect, since the `async` requirement is in essence the "context" that forwards to the underlying witness. This intended behavior is also inferred from: https://github.com/apple/swift/pull/40088 The problem boiled down to a bad check when categorizing the witness matches prior to ranking them. Resolves rdar://109135488 / https://github.com/apple/swift/issues/60318
27 lines
626 B
Swift
27 lines
626 B
Swift
// RUN: %empty-directory(%t)
|
|
// RUN: %target-build-swift -Xfrontend -disable-availability-checking %s -o %t/main
|
|
// RUN: %target-codesign %t/main
|
|
// RUN: %target-run %t/main | %FileCheck %s
|
|
|
|
// REQUIRES: concurrency
|
|
// REQUIRES: executable_test
|
|
// REQUIRES: concurrency_runtime
|
|
|
|
// Ensures the more exact witness from S is chosen
|
|
// to fulfill the requirement from P.
|
|
// See: https://github.com/apple/swift/issues/60318
|
|
|
|
protocol P {
|
|
func foo() async -> String
|
|
}
|
|
|
|
struct S: P {
|
|
func foo() -> String { "plain" }
|
|
func foo() async -> String { "async" }
|
|
}
|
|
|
|
let p: P = S()
|
|
let ans = await p.foo()
|
|
print(ans)
|
|
// CHECK: async
|