mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
While a Swift protocol can have its async requirements satisfied by a sync witness, this is not the case for ObjC protocols because it is not just a calling convention difference. Because every async ObjC function requirement in the protocol also has a sibling that is sync, a sync witness might be trying to conform to the sync version that takes a completion handler. Without this change, we were seeing an issue where we would consider both the async and sync versions of an ObjC requirement, and accidentially choose the async version when the witness was sync, and then raise an error about the typechecker's mistake. Instead of raising an error, this change removes the ability for the typechecker to even consider the errornous conformance. resolves rdar://73326234
42 lines
1.6 KiB
Swift
42 lines
1.6 KiB
Swift
// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency
|
|
// REQUIRES: objc_interop
|
|
// REQUIRES: concurrency
|
|
|
|
import Foundation
|
|
|
|
// async objc requirement, sync witness
|
|
@objc protocol Tracker {
|
|
func track(event: String) async // expected-note {{protocol requires function 'track(event:)' with type '(String) async -> ()'; do you want to add a stub?}}
|
|
}
|
|
class Dog: NSObject, Tracker { // expected-error {{type 'Dog' does not conform to protocol 'Tracker'}}
|
|
func track(event: String) {} // expected-note {{candidate is not 'async', but @objc protocol requirement is}}
|
|
}
|
|
|
|
// sync objc requirement, async witness
|
|
@objc protocol Runner {
|
|
func run(event: String) // expected-note {{protocol requires function 'run(event:)' with type '(String) -> ()'; do you want to add a stub?}}
|
|
}
|
|
class Athlete: NSObject, Runner { // expected-error {{type 'Athlete' does not conform to protocol 'Runner'}}
|
|
func run(event: String) async {} // expected-note {{candidate is 'async', but @objc protocol requirement is not}}
|
|
}
|
|
|
|
|
|
// async swift protocol, sync witness
|
|
protocol Snacker {
|
|
func snack(food: String) async
|
|
}
|
|
|
|
class Foodie: Snacker {
|
|
func snack(food: String) {}
|
|
}
|
|
|
|
|
|
// sync swift protocol, async witness
|
|
protocol Backer {
|
|
func back(stonk: String) // expected-note {{protocol requires function 'back(stonk:)' with type '(String) -> ()'; do you want to add a stub?}}
|
|
}
|
|
|
|
class Investor: Backer { // expected-error {{type 'Investor' does not conform to protocol 'Backer'}}
|
|
func back(stonk: String) async {} // expected-note {{candidate is 'async', but protocol requirement is not}}
|
|
}
|